def handle_temperature(self): #Check the current temperature and adjust outlets accordingly temp_sensors = self.devices_by_name('temperature') outlets = self.devices_by_name('outlet') if(len(temp_sensors) < 1): #If no temperature sensors are registered, exit logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Temperature handling failed, no temperature sensors registered') #print('WARNING: Temperature handling failed, no temperature sensors registered') elif(len(outlets) < 1): #If no outlets are registered, exit logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Temperature handling failed, no outlets registered') #print('WARNING: Temperature handling failed, no outlets registered') else: temperatures = [] for t in temp_sensors: #Get the state of each registered temperature sensor try: self.clock += 1 r = iot.build_receiver(t) c, val = r.get_attr(self.clock, 'state') self.update_clock(c) if((type(val) == int) or (type(val) == float)): temperatures.append(val) except: logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Failed to contact temperature sensor: ' + str(t)) print('WARNING: Failed to contact temperature sensor: ' + str(t)) logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Read temperature value(s) of: ' + str(temperatures)) if (len(temperatures) == 0): #If no registered temperature sensors could be contacted, exit logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Temperature handling failed, could not contact any temperature sensors') print('WARNING: Temperature handling failed, could not contact any temperature sensors') else: #Calculate the average of all reported temperature values, and turn on or off all registered outlets accordingly #For T < 1, turn them on. For T > 2, turn them off. temperature = sum(temperatures) / len(temperatures) if(temperature < 1): logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Temperature is below 1 degree, turning outlets on') for o in outlets: try: self.clock += 1 r = iot.build_receiver(o) c = r.set_attr(self.clock, 'state', 1) self.update_clock(c) logging.info(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Turned outlet on: ' + str(o)) except: logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Failed to contact outlet: ' + str(o)) print('WARNING: Failed to contact outlet: ' + str(o)) elif(temperature > 2): logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Temperature is above 2 degrees, turning outlets off') for o in outlets: try: self.clock += 1 r = iot.build_receiver(o) c = r.set_attr(self.clock, 'state', 0) self.update_clock(c) logging.info(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Turned outlet off: ' + str(o)) except: logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Failed to contact outlet: ' + str(o)) print('WARNING: Failed to contact outlet: ' + str(o))
def handle_motion(self, c): #Triggered by the motion sensor when it detects motion self.update_clock(c) if self.motion_mode == 'HOME': #If the current mode is 'HOME', turn on the bulb logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Motion detected, turning bulbs on') bulbs = self.devices_by_name('bulb') if(len(bulbs) == 0): logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Motion handling failed, no bulbs registered') #print('WARNING: Motion handling failed, no bulbs registered') self.clock += 1 time.sleep(10) else: for b in bulbs: try: self.clock += 1 logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Turning on bulb: ' + str(b)) r = iot.build_receiver(b) c = r.set_attr(self.clock, 'state', 1) self.update_clock(c) logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Turned bulb on: ' + str(b)) except: logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Failed to contact bulb: ' + str(b)) print('WARNING: Failed to contact bulb: ' + str(b)) else: #If the current mode is anything but 'HOME', send an intruder alert to the user print('!!! INTRUDER DETECTED !!!') logging.critical(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + '!!! INTRUDER DETECTED !!!') self.alert_user()
def handle_door_state(self, c, state): #Called remotely by the door sensor whenever its state changes #If the door is opened, update the device list, and check all presence sensors to see if a user is home #If no presence sensors respond positively, send an intruder alert to the user device(s) self.update_clock(c) if state == 0: logging.debug( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Door was closed') return self.clock else: logging.debug( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Door was opened') presence = self.devices_by_name('presence') for i in presence: try: r = iot.build_receiver(i) c, s = r.get_attr(self.clock) self.update_clock(c) if s == 1: logging.debug( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'User is home, not sending alert') return self.clock except: logging.warning( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Failed to contact presence sensor: ' + str(i)) self.alert_user() return self.clock
def set_attr(self, c, attr, val): #Set the value of a given attribute #Generally called remotely self.update_clock(c) setattr(self, attr, val) logging.info( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Attribute ' + str(attr) + ' was set to: ' + str(val)) print('Attribute ' + str(attr) + ' was set to: ' + str(val)) if ((attr == 'state') and (not (self.name == 'backend'))): self.db_put(self.name, val) if (attr == 'motion_mode'): displays = self.devices_by_name('display') for i in displays: try: r = iot.build_receiver(i) c = r.display_message( self.clock, 'Motion mode was set to: ' + str(val)) self.update_clock(c) except: logging.warning( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Could not connect to the display device at ' + str(compose_address(i['ip'], i['port']))) print( 'WARNING: Could not connect to the display device at ' + str(compose_address(i['ip'], i['port']))) return self.clock
def gateway_heartbeat(self): while 1: if ((self.gateway_ip == False) or (self.gateway_port == False)): print('gateway_ip: ' + str(self.gateway_ip)) print('gateway_port: ' + str(self.gateway_port)) print 'Reregistering!' self.register() else: g = {'ip': self.gateway_ip, 'port': self.gateway_port} g = iot.build_receiver(g) try: c = g.ping(self.clock) self.update_clock(c) logging.debug( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Gateway still alive, checking again in 5 seconds') time.sleep(5) except: logging.debug( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Gateway unreachable, checking for a new registration request' ) self.gateway_ip = False self.gateway_port = False continue
def db_put(self, k, v): #Contact the backend device to store a value in the persistent databases #Store a copy in the local cache first in case it's needed again soon #Also notify all other gateways that they should write the new value to their caches and databases self.cache_put(k, v) backend = {'ip': self.backend_ip, 'port': self.backend_port} b = iot.build_receiver(backend) c = b.db_put(self.clock, k, v) self.update_clock(c) gateways = self.devices_by_name('gateway') for g in gateways: self.clock += 1 r = iot.build_receiver(g) c = r.db_update(self.clock, k, v) self.update_clock(c)
def alert_user(self): #Send an intruder alert to the user display displays = self.devices_by_name('display') for i in displays: try: self.clock += 1 r = iot.build_receiver(i) c = r.display_message(self.clock, '!!! INTRUDER DETECTED !!!') self.update_clock(c) logging.debug('User Alerted') print('User Alerted') except: logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Could not connect to the display device at ' + str(compose_address(i['ip'], i['port']))) print('WARNING: Could not connect to the display device at ' + str(compose_address(i['ip'], i['port'])))
def db_update(self, c, k, v): #Called remotely by another gateway when it writes to its database #Used by all other databases to make the same change without propagating a duplicate change self.update_clock(c) self.cache_put(k, v) try: backend = {'ip': self.backend_ip, 'port': self.backend_port} b = iot.build_receiver(backend) c = b.db_put(self.clock, k, v) self.update_clock(c) self.clock += 1 return self.clock() except: if not ((self.backend_ip == False) and (self.backened_port == False)): #If a backend is registered but can't be reached, unregister it and submit a new request self.backend_ip == False self.backend_port == False self.request_db() self.clock += 1 return self.clock()
def set_attr(self, c, attr, val): #Set the value of a given attribute #Generally called remotely self.update_clock(c) setattr(self, attr, val) logging.info(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Attribute ' + str(attr) + ' was set to: ' + str(val)) print('Attribute ' + str(attr) + ' was set to: ' + str(val)) if((attr == 'state') and (not(self.name == 'backend'))): self.db_put(self.name, val) if(attr == 'motion_mode'): displays = self.devices_by_name('display') for i in displays: try: r = iot.build_receiver(i) c = r.display_message(self.clock, 'Motion mode was set to: ' + str(val)) self.update_clock(c) except: logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Could not connect to the display device at ' + str(compose_address(i['ip'], i['port']))) print('WARNING: Could not connect to the display device at ' + str(compose_address(i['ip'], i['port']))) return self.clock
def handle_door_state(self, c, state): #Called remotely by the door sensor whenever its state changes #If the door is opened, update the device list, and check all presence sensors to see if a user is home #If no presence sensors respond positively, send an intruder alert to the user device(s) self.update_clock(c) if state == 0: logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Door was closed') return self.clock else: logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Door was opened') presence = self.devices_by_name('presence') for i in presence: try: r = iot.build_receiver(i) c, s = r.get_attr(self.clock) self.update_clock(c) if s == 1: logging.debug(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'User is home, not sending alert') return self.clock except: logging.warning(str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Failed to contact presence sensor: ' + str(i)) self.alert_user() return self.clock
def register(self): registered = False while not registered: requests = os.listdir('db_requests/') valid_requests = [] for i in requests: if not i.startswith('req_'): logging.debug( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Ignoring improperly named request file: ' + str(i)) else: valid_requests.append(i) if (len(valid_requests) == 0): #If there are no open gateway requests, wait five seconds and check again time.sleep(5) continue request = min(valid_requests) print('Attempting to answer request: ' + str(request)) filename = ('db_requests/' + str(request)) f = open(filename, 'r') address = f.readlines() ip = address[0].strip() port = int(address[1].strip()) print('Found request address of: ' + str(iot.compose_address(ip, port))) gateway = {'ip': ip, 'port': port} try: logging.debug( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Attempting to register with gateway at: ' + str(iot.compose_address(ip, port))) g = iot.build_receiver(gateway) self.ip = socket.gethostbyname(socket.gethostname()) self.clock += 1 c, id, port, devices = g.register_db(self.clock, self.name, self.ip) self.update_clock(c) if ((id == False) or (port == False)): continue else: print('Registered with gateway. Received:\n\tID: ' + str(id) + '\n\tPort: ' + str(port)) logging.info( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Registered with gateway. Using port number: ' + str(port)) self.id = id self.port = port self.devices = devices self.gateway_ip = gateway['ip'] print self.gateway_ip self.gateway_port = gateway['port'] print self.gateway_port registered = True print registered break except: logging.warning( str(self.clock) + ' | ' + str(self.timestamp()) + ': ' + 'Failed to register with the gateway, trying another request' ) time.sleep(5) continue