X-Git-Url: https://git.realraum.at/?a=blobdiff_plain;f=track-presence.py;h=9e4d272cf8ea7efa7338fd2bc99e9593a44886d4;hb=d73860aa0723724aa86640c099a8e5a925865c93;hp=0f449adb0b7f921762e75d314d8e14855bc1d383;hpb=f7e232e0522447ef5719323b9a812fd2424cba8d;p=svn42.git diff --git a/track-presence.py b/track-presence.py index 0f449ad..9e4d272 100644 --- a/track-presence.py +++ b/track-presence.py @@ -41,12 +41,15 @@ class UWSConfig: self.config_parser.add_section('sensors') self.config_parser.set('sensors','remote_cmd',"ssh -o PasswordAuthentication=no %RHOST% %RSHELL% %RSOCKET%") self.config_parser.set('sensors','remote_host',"slug.realraum.at") - self.config_parser.set('sensors','remote_socket',"/var/run/tuer/door_cmd.socket") - self.config_parser.set('sensors','remote_shell',"serial") + self.config_parser.set('sensors','remote_socket',"/var/run/power_sensor.socket") + self.config_parser.set('sensors','remote_shell',"usocket") self.config_parser.add_section('tracker') - self.config_parser.set('tracker','sec_wait_movement_after_door_closed',2.0) - self.config_parser.set('tracker','sec_general_movement_timeout',1800) + self.config_parser.set('tracker','sec_wait_movement_after_door_closed',2.5) + self.config_parser.set('tracker','sec_general_movement_timeout',3600) self.config_parser.set('tracker','server_socket',"/var/run/tuer/presence.socket") + self.config_parser.set('tracker','photo_flashlight',950) + self.config_parser.set('tracker','photo_daylight',500) + self.config_parser.set('tracker','photo_artif_light',150) self.config_parser.add_section('debug') self.config_parser.set('debug','enabled',"False") self.config_mtime=0 @@ -138,7 +141,7 @@ class UWSConfig: ######## Status Listener Threads ############ -def trackSensorStatusThread(uwscfg,status_tracker): +def trackSensorStatusThread(uwscfg,status_tracker,connection_listener): #RE_TEMP = re.compile(r'temp\d: (\d+\.\d+)') RE_PHOTO = re.compile(r'photo\d: (\d+\.\d+)') RE_MOVEMENT = re.compile(r'movement|button\d?') @@ -153,7 +156,7 @@ def trackSensorStatusThread(uwscfg,status_tracker): raise Exception("trackSensorStatusThread: subprocess %d finished, returncode: %d" % (sshp.pid,sshp.returncode)) (stdoutdata, stderrdata) = sshp.communicate(input="listen movement\n") (stdoutdata, stderrdata) = sshp.communicate(input="listen button\n") - (stdoutdata, stderrdata) = sshp.communicate(input="listen photo0\n") + (stdoutdata, stderrdata) = sshp.communicate(input="listen photo\n") while True: line = sshp.stdout.readline() logging.debug("Got Line: " + line) @@ -161,6 +164,8 @@ def trackSensorStatusThread(uwscfg,status_tracker): raise Exception("EOF on Subprocess, daemon seems to have quit") if not sshp.poll() is None: raise Exception("trackSensorStatusThread: subprocess %d finished, returncode: %d" % (sshp.pid,sshp.returncode)) + + connection_listener.distributeData(line) m = RE_MOVEMENT.match(line) if not m is None: status_tracker.movementDetected() @@ -189,7 +194,7 @@ def trackSensorStatusThread(uwscfg,status_tracker): time.sleep(5) -def trackDoorStatusThread(uwscfg, status_tracker): +def trackDoorStatusThread(uwscfg, status_tracker,connection_listener): #socket.setdefaulttimeout(10.0) #affects all new Socket Connections (urllib as well) RE_STATUS = re.compile(r'Status: (\w+), idle') RE_REQUEST = re.compile(r'Request: (\w+) (?:Card )?(.+)') @@ -213,6 +218,7 @@ def trackDoorStatusThread(uwscfg, status_tracker): if line == "": raise Exception("EOF on Socket, daemon seems to have quit") + connection_listener.distributeData(line) m = RE_STATUS.match(line) if not m is None: (status,who) = m.group(1,2) @@ -241,6 +247,8 @@ class StatusTracker: #(threading.Thread): self.door_manual_switch_used=False self.last_door_operation_unixts=0 self.last_movement_unixts=0 + self.last_light_value=0 + self.last_light_unixts=0 self.lock=threading.Lock() #Notify State locked by self.presence_notify_lock self.last_somebody_present_result=False @@ -273,11 +281,29 @@ class StatusTracker: #(threading.Thread): self.lock.release() self.checkPresenceStateChangeAndNotify() - def currentLightLevel(self): + def currentLightLevel(self, value): self.uwscfg.checkConfigUpdates() - #... + self.last_light_unixts=time.time() + self.last_light_value=value; self.checkPresenceStateChangeAndNotify() + def checkLight(self, somebody_present=None): + if somebody_present is None: + somebody_present=self.somebodyPresent() + + if self.last_light_value > self.uwscfg.tracker_photo_flashlight: + return "Light: flashlight" + elif self.last_light_value > self.uwscfg.tracker_photo_daylight: + return "Light: daylight" + elif self.last_light_value > self.uwscfg.tracker_photo_artif_light: + if not somebody_present and self.last_light_unixts > self.last_door_operation_unixts: + return "Light: forgotten" + else: + return "Light: on" + else: + return "Light: off" + + #TODO: check brightness level from cam or an arduino sensor def somebodyPresent(self): global uwscfg @@ -291,7 +317,7 @@ class StatusTracker: #(threading.Thread): self.timer=threading.Timer(self.uwscfg.tracker_sec_wait_movement, self.checkPresenceStateChangeAndNotify) self.timer.start() return True - elif (self.last_movement_unixts > self.last_door_operation_unixts and time.time() - self.last_movement_unixts < self.uwscfg.tracker_sec_general_movement_timeout): + elif (self.last_movement_unixts > self.last_door_operation_unixts and (self.door_manual_switch_used or ( time.time() - self.last_movement_unixts < self.uwscfg.tracker_sec_general_movement_timeout))): return True else: return False @@ -319,15 +345,17 @@ class ConnectionListener: def statusString(self,somebody_present): if somebody_present: - return "Status: people present" + "\n" + return "Presence: yes" + "\n" else: - return "Status: room empty" + "\n" + return "Presence: no" + "\n" def updateStatus(self,somebody_present): - presence_status_data = self.statusString(somebody_present) + self.distributeData(self.statusString(somebody_present)) + + def distributeData(self,data): with self.lock: for socket_to_send_to in self.client_sockets: - socket_to_send_to.send(presence_status_data) + socket_to_send_to.send(data) def serve(self): self.server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) @@ -336,14 +364,13 @@ class ConnectionListener: except OSError: pass self.server_socket.bind(self.uwscfg.tracker_server_socket) - self.server_socket.listen(backlog=2) + self.server_socket.listen(2) while (self.running): - (ready_to_read, ready_to_write, in_error) = select.select(rlist=[self.server_socket]+self.client_sockets, wlist=[], xlist=[]) + (ready_to_read, ready_to_write, in_error) = select.select([self.server_socket]+self.client_sockets, [], []) for socket_to_read in ready_to_read: if socket_to_read == self.server_socket: newsocketconn, addr = self.server_socket.accept() - presence_status_data = self.statusString(self.status_tracker.somebodyPresent()) - newsocketconn.send(presence_status_data) + newsocketconn.send(self.statusString(self.status_tracker.somebodyPresent())) with self.lock: self.client_sockets.append(newsocketconn) else: @@ -378,11 +405,14 @@ else: #Status Tracker keeps track of stuff and derives peoples presence from current state status_tracker = StatusTracker(uwscfg) +#ConnectionListener servers incoming socket connections and distributes status update +connection_listener = ConnectionListener(uwscfg, status_tracker) #Thread listening for door status changes -track_doorstatus_thread = threading.Thread(target=trackDoorStatusThread,args=(uwscfg,status_tracker),name="trackDoorStatusThread") +track_doorstatus_thread = threading.Thread(target=trackDoorStatusThread,args=(uwscfg,status_tracker,connection_listener),name="trackDoorStatusThread") track_doorstatus_thread.start() #Thread listening for movement -track_sensorstatus_thread = threading.Thread(target=trackSensorStatusThread,args=(uwscfg,status_tracker),name="trackSensorStatusThread") +track_sensorstatus_thread = threading.Thread(target=trackSensorStatusThread,args=(uwscfg,status_tracker,connection_listener),name="trackSensorStatusThread") track_sensorstatus_thread.start() -#ConnectionListener servers incoming socket connections and distributes status update -connection_listener = ConnectionListener(uwscfg, status_tracker) + +#main routine: serve connections +connection_listener.serve() \ No newline at end of file