/Markov-Model-for-Smart-Building

A hidden markov model was implemented to minimize the cost of electricity for a smart building while also making sure that light is turned on if there are people in it.

Primary LanguagePython

Markov Model for Smart Building

SUMMARY

  • A hidden markov model was implemented to minimize the cost of electricity for a smart building while also making sure that light is turned on if there are people in it.

AIM

  • Write a program that plays the part of a "smart building".
  • Input to the program will be a real-time stream of sensor data from throughout the building.
  • Use this data to decide whether to turn on the lights in each room.
  • Goal is to minimize the cost of lighting in the building, while also trying to make sure that the lights stay on if there are people in a room.
  • Every 15 seconds, the program will recieve a new data point and it has to decide whether each light should be turned on or off.
  • There are several types of sensors in the building, each with different reliability and data output.
  • You will be given a file called data.csv containing one day of complete data with all sensor values and the number of people in each room.
  • Your solution must include a Probabilistic Graphical Model as the core component.

DATA

  • The file data.csv contains complete data that is representative of a typical weekday in the office building.
  • This data includes the output of each sensor as well as the true number of people in each room.
  • This data was generated using a simulation of the building, and the program will be tested against many days of data generated by the same simulation.
  • We are given only 2400 complete data points, from a single workday.
  • The simulation attempts to be a realistic approximation to reality, so it includes many different types of noise and bias.

SENSOR DATA

  • Submission file contains a function called get_action(sensor_data), which receives sensor data in the following format:

sensor_data = {'reliable_sensor1': 'motion', 'reliable_sensor2': 'motion', 'reliable_sensor3': 'motion', 'reliable_sensor4': 'motion', 'unreliable_sensor1': 'motion', 'unreliable_sensor2': 'motion', 'unreliable_sensor3': 'motion', 'unreliable_sensor4': 'motion', 'door_sensor1': 0, 'door_sensor2': 0, 'door_sensor3': 0, 'door_sensor4':0, 'robot1': ('r1', 0), 'robot2': ('r16', 0), 'time': datetime.time(8, 0), 'electricity_price': 0.81}

  • The possible values of each field in sensor_data are:
    • reliable_sensors: can have values ['motion', 'no motion']. All reliable_sensors are of the same brand and are usually quite accurate.

    • Unreliable_sensors: can have values ['motion', 'no motion']. Unreliable_sensors are a different type of motion sensor, which tend to be a little less accurate.

    • door_sensors: count how many people passed through a door (in either direction, so it can be any integer).

    • The robot sensors are robots that wander around the building and count the number of people in each room.

      • The value is a 2-tuple of the current room and the number of people counted. example -> ('r4', 8).
    • Any of the sensor may fail at any time, in which case they will have the value None. They may start working again.

    • time: A datatime.time object representing the current time.

      • Datapoints will be provided in 15 seconds resolution i.e., function will be given input of data points from 15 second intervals from 8 am - 6 pm.

TRAINING DATA

  • The file data.csv contains for each of the above sensors as well as columns for each room, which tell us the current number of people in that room.
  • The columns of data.csv are the following and can be divided into two groups:
    • Columns that represent readings from the sensors = ['reliable_sensor1', 'reliable_sensor2', 'reliable_sensor3', 'reliable_sensor4', 'unreliable_sensor1', 'unreliable_sensor2', 'unreliable_sensor3', 'unreliable_sensor4', 'robot1', 'robot2', 'door_sensor1', 'door_sensor2', 'door_sensor3', 'door_sensor4', time, electricity_price].
    • Columns that provide the ground truth with the number of people in each room, corridor, open area, and outside the building = ['r1', 'r2', 'r3', 'r4', 'r5','r6', 'r7', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15', 'r16', 'r17', 'r18', 'r19', 'r20', 'r21', 'r22', 'r23', 'r24', 'r25', 'r26', 'r27', 'r28', 'r29', 'r30', 'r31', 'r32', 'r33', 'r34', 'r35', 'c1', 'c2', 'c3', 'c4', 'o1', 'outside']

ACTION DATA

  • get_action() must return a dictionary with the following format.
  • Note: Every numbered room named "r" in the building has lights that we can turn on or off.
  • All other rooms/corridors have lights that are permanently on, which we cannot control and have no impact on the cost.

actions_dict = {'lights1': 'off', 'lights2': 'off', 'lights3': 'off', 'lights4': 'off', 'lights5': 'off', 'lights6': 'off', 'lights7': 'off', 'lights8': 'off', 'lights9': 'off', 'lights10': 'off', 'lights11': 'off', 'lights12': 'off', 'lights13': 'off', 'lights14': 'off', 'lights15': 'off', 'lights16': 'off', 'lights17': 'off','lights18': 'off', 'lights19': 'off', 'lights20': 'off', 'lights21': 'off', 'lights22': 'off', 'lights23': 'off', 'lights24': 'off', 'lights25': 'off', 'lights26': 'off', 'lights27': 'off', 'lights28': 'off', 'lights29': 'off','lights30': 'off', 'lights31': 'off', 'lights32': 'off', 'lights33': 'off', 'lights34': 'off','lights35': 'off'}

  • The outcome space of all actions = ('on', 'off').

COST SPECIFICATION

  • If a light is on for 15 seconds, it usually costs about 1 cent.
  • The exact price of electricity goes up and down and it is included in the sensor_data.
  • if there are people in a room and there is no light on, it costs 4 cent per person every 15 seconds.
  • Goal is to minimize the total cost of lighting plus the lost productivity, added up over the whole day.

CONSTRAINTS

  • The program should not run longer than 1800 seconds for 10 days (180s/day).

Code ReadMe

  • The detailed readme with the information about the working of the model can be be found inside the code folder.