def update(eventType, type, parameters, code, event, message, defaultStatus): if not type in state.state: state.state[type] = {'lastevents': []} #keep the last state try: prev_status = state.state[type][parameters]['status'] except (IndexError, KeyError): #if we are here, we've never seen this event type, parameter combination before prev_status = None # if this event has never generated 'state' before, populate the defaults if not parameters in state.state[type]: state.state[type][parameters] = { 'name': config.ZONENAMES[parameters] if type == 'zone' else config.PARTITIONNAMES[parameters], 'lastevents': [], 'status': defaultStatus } #update the state state.state[type][parameters]['status'] = dict( state.state[type][parameters]['status'], **event['status']) #if this is the first event in this zone/partition we've seen, don't do anything here. if prev_status != None: #if we've seen this before, check if it's changed if prev_status == state.state[type][parameters]['status']: logger.debug( 'Discarded event. State not changed. ({} {})'.format( event['type'], parameters)) else: events.put('statechange', type, parameters, code, event, message, defaultStatus) else: events.put('stateinit', type, parameters, code, event, message, defaultStatus) #write event state.state[type][parameters]['lastevents'].append({ 'datetime': str(datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")), 'code': code, 'message': message }) #write to all events state.state[type]['lastevents'].append({ 'datetime': str(datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")), 'code': code, 'message': message })
def handle_line(self, rawinput): self._last_activity = time.time() if rawinput == '': return input = rawinput.strip() if config.ENVISALINKLOGRAW == True: logger.debug('RX RAW < "' + str(input) + '"') if re.match(r'^\d\d:\d\d:\d\d ',input): evltime = input[:8] input = input[9:] if not re.match(r'^[0-9a-fA-F]{5,}$', input): logger.warning('Received invalid TPI message: ' + repr(rawinput)); return code = int(input[:3]) parameters = input[3:][:-2] try: event = getMessageType(int(code)) except KeyError: logger.warning('Received unknown TPI code: "%s", parameters: "%s"' % (input[:3], parameters)) return rcksum = int(input[-2:], 16) ccksum = int(get_checksum(input[:3],parameters), 16) if rcksum != ccksum: logger.warning('Received invalid TPI checksum %02X vs %02X: "%s"' % (rcksum, ccksum, input)) return message = self.format_event(event, parameters) logger.debug('RX < ' +str(code)+' - '+message) try: handler = "handle_%s" % event['handler'] except KeyError: handler = "handle_event" try: func = getattr(self, handler) if handler != 'handle_login': events.put('proxy', None, rawinput) except AttributeError: raise CodeError("Handler function doesn't exist") func(code, parameters, event, message) try: line = yield self._connection.read_until(self._terminator) self.handle_line(line) except StreamClosedError: #we don't need to handle this, the callback has been set for closed connections. pass
def get(self, request): parameters = {} parameters['alarmcode'] = self.get_argument('alarmcode', None) parameters['partition'] = self.get_argument('partition', 1) parameters['zone'] = self.get_argument('zone', None) if request == 'arm': response = { 'response': 'Request to arm partition %s received' % parameters['partition'] } elif request == 'stayarm': response = { 'response': 'Request to arm partition %s in stay received' % parameters['partition'] } elif request == 'armwithcode': if parameters['alarmcode'] == None: raise tornado.web.HTTPError(404) response = { 'response': 'Request to arm partition %s with code received' % parameters['partition'] } elif request == 'disarm': if parameters['alarmcode'] == None: raise tornado.web.HTTPError(404) response = { 'response': 'Request to disarm partition %s received' % parameters['partition'] } elif request == 'refresh': response = {'response': 'Request to refresh data received'} elif request == 'pgm': response = {'response': 'Request to trigger PGM'} elif request == 'bypass': response = { 'response': 'Zone bypass for %s received' % paramters['zone'] } elif request == 'instantarm': if parameters['alarmcode'] == None: raise tornado.web.HTTPError(404) response = { 'response': 'Request to arm partition %s with code received' % parameters['partition'] } #send event for our request events.put('alarm_update', request, parameters) self.write(response)
def handle_event(self, code, parameters, event, message): # only handle events with a 'type' defined if not 'type' in event: return parameters = int(parameters) try: defaultStatus = evl_Defaults[event['type']] except IndexError: defaultStatus = {} if (event['type'] == 'zone' and parameters in config.ZONENAMES) or (event['type'] == 'partition' and parameters in config.PARTITIONNAMES): events.put('alarm', event['type'], parameters, code, event, message, defaultStatus) elif (event['type'] == 'zone' or event['type'] == 'partition'): logger.debug('Ignoring unnamed %s %s' % (event['type'], parameters)) else: logger.debug('Ignoring unhandled event %s' % event['type'])
def dispatch_client(self): try: while True: line = yield self.stream.read_until(b'\r\n') if self.authenticated == True: events.put('envisalink', None, line) else: if line.strip() == ('005' + config.ENVISALINKPROXYPASS + get_checksum('005', config.ENVISALINKPROXYPASS)): logger.info('Proxy User Authenticated') self.authenticated = True self.send_command('5051') else: logger.info('Proxy User Authentication failed') self.send_command('5050') self.stream.close() except StreamClosedError: #on_disconnect will catch this pass
def get(self, request): parameters = {} parameters['alarmcode'] = self.get_argument('alarmcode', None) parameters['partition'] = self.get_argument('partition', 1) if request == 'arm': response = {'response' : 'Request to arm partition %s received' % parameters['partition']} elif request == 'stayarm': response = {'response' : 'Request to arm partition %s in stay received' % parameters['partition']} elif request == 'armwithcode': if parameters['alarmcode'] == None: raise tornado.web.HTTPError(404) response = {'response' : 'Request to arm partition %s with code received' % parameters['partition']} elif request == 'disarm': if parameters['alarmcode'] == None: raise tornado.web.HTTPError(404) response = {'response' : 'Request to disarm partition %s received' % parameters['partition']} elif request == 'refresh': response = {'response' : 'Request to refresh data received'} elif request == 'pgm': response = {'response' : 'Request to trigger PGM'} #send event for our request events.put('alarm_update', request, parameters) self.write(response)
def update(eventType, type, parameters, code, event, message, defaultStatus): if not type in state.state: state.state[type] = {'lastevents' : []} #keep the last state try: prev_status = state.state[type][parameters]['status'] except (IndexError,KeyError): #if we are here, we've never seen this event type, parameter combination before prev_status = None # if this event has never generated 'state' before, populate the defaults if not parameters in state.state[type]: state.state[type][parameters] = {'name' : config.ZONENAMES[parameters] if type == 'zone' else config.PARTITIONNAMES[parameters], 'lastevents' : [], 'status' : defaultStatus} #update the state state.state[type][parameters]['status'] = dict(state.state[type][parameters]['status'], **event['status']) #if this is the first event in this zone/partition we've seen, don't do anything here. if prev_status != None: #if we've seen this before, check if it's changed if prev_status == state.state[type][parameters]['status']: logger.debug('Discarded event. State not changed. ({} {})'.format(event['type'], parameters)) else: events.put('statechange', type, parameters, code, event, message, defaultStatus) else: events.put('stateinit', type, parameters, code, event, message, defaultStatus) #write event state.state[type][parameters]['lastevents'].append({ 'datetime' : str(datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")), 'code' : code, 'message' : message}) #write to all events state.state[type]['lastevents'].append({ 'datetime' : str(datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")), 'code' : code, 'message' : message})
def check_connection(self): if (self._last_activity + config.ENVISALINKKEEPALIVE) < time.time(): events.put('alarm_update', 'ping')
def refresh(self): if self._connection: events.put('alarm_update', 'ping')