def parsing(self, commands): ''' parse all commands ''' cmd_list = commands.findall("command") for cmd in cmd_list: cmd_name = cmd.get("action", "0") cmd_ID = cmd.get("id", "0") logging.info("{} -{} -{}".format(cmd.tag, cmd_ID, cmd_name)) # each time a answer is received, up the cmd_id in the GW DB db = DB_gw(self.db_cur) db.upd_cmd_id_gw(self.GW_ID, cmd_ID) # indicate in the command queue that the answer has been received queue = cmd_queue(self.db_cur) queue.ack(self.GW_ID, cmd_ID) if cmd_name == "getSensors": self.getSensors(cmd) if cmd_name == "getMode": self.getMode(cmd) if cmd_name == "getUsers": self.getUsers(cmd) if cmd_name == "switchZPSS": self.getSmartPlug(cmd)
def getMode(self, data): #find mode in xml for cmdParam in data: logging.debug("{} -{}".format(cmdParam.tag, cmdParam.text)) if cmdParam.tag == "xmldata": elt = cmdParam.find("mode") mode = elt.get("value", "0") break # store result in DB db = DB_gw(self.db_cur) db.upd_polling_gw(self.MAC, mode)
def handle(self): Contact_ID_filter = re.compile( r'^\[[0-9A-Fa-f]{4}#[0-9A-Fa-f\s]{4}18[0-9A-Fa-f\s]{13}\]$' ) # contact ID self.request.settimeout(10) self.IPaddr = self.client_address[0] try: self.data = self.request.recv(32) except socket.timeout: # fail after x seconds of no activity, connection automatically closed now = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") hclog.info( "ERROR: session opened without content UTC {} [client {}] {}". format(now, self.IPaddr, threading.current_thread())) else: now = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") hclog.info("Contact ID: UTC {} {} [client {}]:{} {}".format( now, self.data, self.client_address[0], self.client_address[1], threading.current_thread())) try: data = self.data.decode() if Contact_ID_filter.match(data): self.request.sendall( b'\x06') # respond only if Contact ID is correct hclog.debug("Contact ID format OK, acknowledge sent") rptipid = data[1:5] tmp = data[6:].split(' ') acct2 = tmp[0] db_cur = DB_mngt(HcDB.config()) if db_cur.echec: hclog.info("Cannot open DB") else: gw = DB_gw(db_cur) # returns the_id of the gateway gw_id = gw.search_gw_from_acct(rptipid, acct2) if gw_id == []: hclog.info( " No Gw found with acct2= {}".format(acct2)) else: hclog.debug(" on Gw_id {}".format(gw_id[0][0])) snsr_list = gw.search_sensors_name_from_gwID( gw_id[0][0]) # get sensors from gateways usr_list = gw.search_users_name_from_gwID( gw_id[0][0]) # get users from gateways) event = [ ] # data [0730#74 181751000032CA2] event = translate( data, snsr_list, usr_list ) # returns event code, formated alarm message, event action (send SMS, email , call) if event[0] != '000': #get info about user #user_id, propertyaddr, SN_SMS, SN_Voice, prof.email, language " usr_profile = gw.search_usrprofile_from_gwID( gw_id[0][0] ) # get usr_profile from gateway = username, propertyaddr, SN_SMS, SN_Voice, prof.email, language req="INSERT INTO {}"\ "(timestamp, userWEB_id, type, gwID_id, sensorID_id, event_code, event_description)"\ " VALUES ( %s, %s, %s, %s, %s, %s, %s )".format("history_events") value = (now, usr_profile[0][0], "GW", gw_id[0][0], event[3], event[0], event[1]) db_cur.executerReq(req, value) db_cur.commit() send_notification(usr_profile[0], event) if event[0] == "400" or event[ 0] == "407": # check if Horus has been armed via keyfob / keypad, then arm camera if relevant if event[ 1][: 5] == "Armed": # dirty implementation ;-) , should pass the alarm status instead securityStatus = 1 elif event[ 1][: 8] == "Disarmed": # dirty implementation ;-) , should pass the alarm status instead securityStatus = 0 else: securityStatus = 9 if securityStatus == 0 or securityStatus == 1: cam_cursor = DB_camera(db_cur) cam_list = cam_cursor.search_cam_list_from_user( usr_profile[0][0]) # returns : id, securityStatus (char), activateWithAlarm (Bolean) for cam in cam_list: if cam[2] == 1: #send "Arm/Disarm command to the camera" #add_camera_cmd( self, cam_id, cmd): cam_cursor.add_camera_cmd( cam[0], 'GET /adm/set_group.cgi?group=SYSTEM&pir_mode={} HTTP/1.1\r\n' .format(securityStatus)) cam_cursor.add_camera_cmd( cam[0], 'GET /adm/set_group.cgi?group=EVENT&event_trigger=1&event_interval=0&event_pir=ftpu:1&event_attach=avi,1,10,20 HTTP/1.1\r\n' ) #change the camera security status #update_camera_status(self, cam_id, status) cam_cursor.update_camera_security_flag( cam[0], securityStatus) db_cur.commit() hclog.info( "Camera {} Armed/disarmed ( {} ) on Gw {} request" .format( cam[0], securityStatus, gw_id[0][0])) # "if..." close the opened DB db_cur.close() # data not matching the Contact ID format else: hclog.info( "ERROR: Bad Contact ID: UTC {} {} [client {}]".format( now, self.data, self.client_address[0])) except: if 'db_cur' in locals(): db_cur.close() hclog.info( "ERROR: bad Contact ID translation or user error in DB or issue sending notification: UTC {} {} [client {}]" .format(now, self.data, self.client_address[0])) finally: self.request.close() finally: pass
def Main(): opts = getopts() logging.basicConfig(format='%(asctime)s [%(levelname)s] %(message)s', level=get_logging_level(opts)) # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Bind the socket to the port server_ip = Rpt_svr.config("ip") server_port = Rpt_svr.config("port") server = (server_ip, int(server_port)) logging.info('starting up on %s port %s' % server) sock.bind(server) # Listen for incoming connections sock.listen(1) Contact_ID_filter = re.compile(r'^\[[0-9A-Fa-f]{4}#[0-9A-Fa-f\s]{4}18[0-9A-Fa-f\s]{13}\]$') # contact ID while True: # Wait for a connection # print ('waiting for a connection') try: connection, client_address = sock.accept() # print ('connection from {}'.format(client_address)) # Receive the data in small chunks and retransmit it while True: try: data = connection.recv(32) except SocketError as e: errno, strerror = e.args logging.info("Socket errorI/O error({0}): {1}".format(errno,strerror)) else: if data: now=datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") # now = time.strftime("%Y-%m-%d %H:%M:%S") logging.info("Contact ID: {} {} ".format(now, data)) try: data = data.decode() if Contact_ID_filter.match(data): connection.sendall( b'\x06' ) # respond only if Contact ID is correct logging.debug("Contact ID format OK, acknowledge sent") rptipid = data[1:5] tmp = data[6:].split(' ') acct2 = tmp[0] db_cur= DB_mngt( HcDB.config() ) if db_cur.echec: logging.info("Cannot open DB") else : gw=DB_gw(db_cur) gw_id = gw.search_gw_from_acct( rptipid, acct2 ) # returns gateways_id if gw_id == []: logging.info( " No Gw found with acct2= {}".format(acct2)) else: logging.debug( " on Gw_id {}".format(gw_id[0][0])) snsr_list = gw.search_sensors_name_from_gwID( gw_id[0][0] ) # get sensors from gateways event=[] # data [0730#74 181751000032CA2] event = translate(data, snsr_list) # returns event code, formated alarm message, event action (send SMS, email , call) usr_profile = gw.search_usrprofile_from_gwID( gw_id[0][0] ) # get usr_profile from gateway = username, propertyaddr, SN_SMS, SN_Voice, prof.email, language req="INSERT INTO {} (timestamp, userWEB_id, type, gwID_id, event_code, event_description) VALUES ( %s, %s, %s, %s, %s, %s )".format("history_events") value= (now, usr_profile[0][0], "GW", gw_id[0][0],event[0], event[1], ) db_cur.executerReq(req, value) db_cur.commit() db_cur.close() send_notification(usr_profile[0], event) else: logging.info("Error: bad contact id format") except: db_cur.close() logging.info("Error: bad Contact ID translation or user error in DB or issue sending notification") else: # print ('no more data from {}'.format(client_address)) break finally: # Clean up the connection connection.close() db_cur.close()
def Main(): opts = getopts() logPath= HcLog.config("logPath") retentionTime = int(HcLog.config("retentionTime")) moduleName = "care_svr" hclog = logging.getLogger() # must be the rotlogger, otherwise sub-modules will not benefit from the config. handler = TimedRotatingFileHandler(logPath + moduleName + '.log', when='midnight', backupCount=retentionTime) if opts.level == 'debug': hclog.setLevel(logging.DEBUG) handler.setLevel(logging.DEBUG) else: hclog.setLevel(logging.INFO) handler.setLevel(logging.INFO) formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s',datefmt='%b %d %H:%M:%S') handler.setFormatter(formatter) hclog.addHandler(handler) print('Care Server starting up') hclog.info('Care Server starting up' ) db_cur= DB_mngt( HcDB.config() ) if db_cur.echec: hclog.info("Cannot open DB") exit() else : # get naive date current_tz = pytz.timezone('Europe/Brussels') date = datetime.now().date() gwDB=DB_gw(db_cur) gw_list = gwDB.search_gw_with_Care_flag( "1" ) for gw in gw_list: hclog.info("Scan rules of Gw= {}, current time= {}".format(gw[0], datetime.today().strftime("%Y-%m-%d %H:%M:%S") ) ) rules= gwDB.search_rules_from_gwID( gw[0] ) for rule in rules: hclog.info("Rule: sensor_id {}, start_time {}, end_time {}".format(rule[1],rule[2],rule[3]) ) dt= datetime.combine(date, time(0, 0) ) + rule[2] start = current_tz.localize(dt).astimezone(pytz.utc) # convert to UTC time dt = datetime.combine(date, time(0, 0) ) + rule[3] end = current_tz.localize(dt).astimezone(pytz.utc) # convert to UTC time if start <= datetime.now(timezone.utc) <= end: # we are between the start and the end of the rule if rule[4] != "1": # rule was not valid during the last script run gwDB.upd_in_rule_flag(rule[0], "1") # update flag of rule id hclog.debug("Rule is applicable") break else: if rule[4] == "1": # the rule was valid during the last script run gwDB.upd_in_rule_flag(rule[0], "0") # deactivate flag of rule id evt_list = gwDB.apply_rule(rule[1], start.strftime("%Y-%m-%d %H:%M:%S"), end.strftime("%Y-%m-%d %H:%M:%S")) # check if there was sensor messages between start and end time hclog.debug( "Event List= {}".format(evt_list) ) if len(evt_list) == 0: hclog.debug( "No event found during rule validity period" ) snsr_list = gwDB.search_sensors_name_from_gwID( gw[0]) # get sensors from gateways sensor_name="" for s in snsr_list: # search for sensor name based on sensor ID if rule[1] == s[0]: sensor_name=s[2] break no_event= ("900", "Event: No motion detected on sensor {}".format(sensor_name), EventCode.value("900")[1], None) usr_profile = gwDB.search_usrprofile_from_gwID( gw[0] ) # get usr_profile from gateway = username, propertyaddr, SN_SMS, SN_Voice, prof.email, language now=datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") req="INSERT INTO {} (timestamp, userWEB_id, type, gwID_id, sensorID_id, event_code, event_description) VALUES ( %s, %s, %s, %s, %s, %s, %s )".format("history_events") value= (now, usr_profile[0][0], "CR", gw[0],no_event[3], no_event[0], no_event[1]) db_cur.executerReq(req, value) db_cur.commit() send_notification(usr_profile[0], no_event) db_cur.close() hclog.info('Finished' )
def do_POST(self): ''' Handle POST requests. ''' logging.debug('POST received %s' % (self.path)) # CITATION: http://stackoverflow.com/questions/4233218/python-basehttprequesthandler-post-variables ctype, pdict = cgi.parse_header(self.headers['content-type']) if ctype == 'multipart/form-data': postvars = cgi.parse_multipart(self.rfile, pdict) elif ctype == 'application/x-www-form-urlencoded': length = int(self.headers['content-length']) raw_cmd=self.rfile.read(length) postvars = urllib.parse.parse_qs(raw_cmd, encoding='iso-8859-1', keep_blank_values=1) else: postvars = {} # init AES encryption vectors MAC= postvars["id".encode('iso-8859-1')] AES= AESCipher(MAC[0]) # get xml frame command_enc= postvars["strRecXML".encode('iso-8859-1')] # decryt xml frame command_xml = AES.decrypt(command_enc[0]) logging.info("POST decrypted: MAC = {}".format(MAC) ) # remove trailling zeros logging.debug("{}\n".format(command_xml.replace('\x00',"")) ) # remove trailling zeros # check if MAC is defined in DB_GW climax_xml= etree.fromstring(command_xml.encode('iso-8859-1')) elt=climax_xml.find("mac") MAC_xml = elt.get ("value", "0") if MAC_xml != "" : db_cur= DB_mngt(HcDB.config()) if db_cur.echec: sys.exit() gw=DB_gw(db_cur) gw_params = gw.search_gw(MAC_xml) if (gw_params): logging.debug( "MAC {} found in Climax_DB".format(MAC_xml) ) mac_gwParams = gw_params[0] acct2_gwParams = gw_params[1] gw_ID_gwParams = gw_params[2] user_ID_gwParams = gw_params[3] rptip_ID_gwParams = gw_params[4] elt=climax_xml.find("rptipid") rptipid_xml= elt.get ("value", "0") if rptipid_xml == "" or rptip_ID_gwParams == "": logging.info("Register GW MAC : {}".format(MAC_xml)) # get acct2 number in config file config = configparser.ConfigParser() config.read("config.ini") last_acct2_created=config.get('other', 'last_acct2_created') acct2= int(last_acct2_created)+1 last_acct2_created=str(acct2) # update incremented acct2 number in config for next time... config.set('other','last_acct2_created',last_acct2_created) # get rptipid (Internet reporting ID) to provision the gw rptipid_xml=config.get('other', 'rptipid') # save the updated values cfgfile = open("config.ini",'w') config.write(cfgfile) cfgfile.close() cmd=cmdTo_climax(db_cur, MAC_xml, user_ID_gwParams, gw_ID_gwParams,rptipid_xml) server_resp=cmd.autoRegister(rptipid_xml,last_acct2_created) gw.upd_account_gw(MAC_xml, rptipid_xml,last_acct2_created) logging.info("POST: Register sent to GW= {0}".format(server_resp) ) else: # GW is registered, analyse GW answer answer_gw = answerFrom_climax(db_cur, MAC_xml, user_ID_gwParams, gw_ID_gwParams) cmdTo_gw = cmdTo_climax(db_cur, MAC_xml, user_ID_gwParams, gw_ID_gwParams,rptip_ID_gwParams) elt=climax_xml.find("commands") if elt != None: # received cmd to process answer_gw.parsing(elt) # get from the queue the commands to be sent server_resp = cmdTo_gw.server_cmd() if server_resp == None: server_resp=cmdTo_gw.polling(rptip_ID_gwParams) logging.debug("POST: Polling sent to GW= {0}\n".format(server_resp) ) AES= AESCipher(MAC[0]) server_xml_resp = server_resp.encode('iso-8859-1') command = AES.encrypt(server_xml_resp) self.send_response(200) # OK # bud display IP address of the GW , Why??? # according to doc : text/xml , but according to trace text/html self.send_header('Content-type', 'text/xml; charset=utf-8') self.send_header('Content-Length', "{0}".format(len(command)) ) self.send_header('Set-Cookies', 'path=/') self.end_headers() self.wfile.write(command) else: logging.info("Polling : MAC not found in DB {}".format(MAC_xml) ) db_cur.close() logging.debug("POST: exit POST function\n\n\n" )