class ActionsResource: def __init__(self): self.action_service = ActionService() self.configuration_store = ConfigurationStore() def on_get(self, request, response): Logger.info(LOCATION, INCOMING_REQUEST + METHOD_GET + ' ' + ACTIONS_ENDPOINT) response.media = self.action_service.get_actions() def on_post(self, request, response): configuration = self.configuration_store.get() if configuration.get_device_status() is not DeviceStatus.ACTIVE: error = 'Not allowed to trigger actions when device is not activated.' Logger.error(LOCATION, error) raise falcon.HTTPForbidden(description=error) Logger.info(LOCATION, INCOMING_REQUEST + METHOD_POST + ' ' + ACTIONS_ENDPOINT) data = request.media if ACTION_ID not in data.keys(): Logger.error( LOCATION, 'Missing parameter `' + ACTION_ID + '` for ' + METHOD_POST + ' ' + ACTIONS_ENDPOINT) raise falcon.HTTPBadRequest action_id = data[ACTION_ID] value = data[VALUE_KEY] if VALUE_KEY in data.keys() else None success = self.action_service.trigger(action_id, value) if success: response.media = {'message': 'Action triggered'} else: raise falcon.HTTPServiceUnavailable
class ConfigurationService: def __init__(self): self.configuration_store = ConfigurationStore() self.configuration = self.configuration_store.get() self.key_generator = KeyGenerator() def initialize_configuration(self, maker_id): Logger.info(LOCATION, 'Initializing configuration...') public_key, private_key = KeyGenerator().generate_key() device_id = self.key_generator.generate_uuid() device_status = DeviceStatus.NEW.value self.configuration.initialize(maker_id, device_id, device_status, public_key, private_key) self.configuration_store.save(self.configuration) self.generate_qr_code() def generate_qr_code(self): try: device_information = self.configuration.get_device_information() qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(json.dumps(device_information)) qr.print_ascii(invert=True) except Exception as exception: raise exception
class ConfigurationService: def __init__(self): self.configuration_store = ConfigurationStore() self.configuration = self.configuration_store.get() self.key_generator = KeyGenerator() def initialize_configuration(self, maker_id): Logger.info(LOCATION, 'Initializing configuration...') public_key, private_key = KeyGenerator().generate_key() device_id = self.key_generator.generate_uuid() device_status = DeviceStatus.NEW.value self.configuration.initialize(maker_id, device_id, device_status, public_key, private_key) self.configuration_store.save(self.configuration) self.generate_qr_code() Logger.success(LOCATION, 'Configuration successfully initialized.') def resume_configuration(self): device_status = self.configuration.get_device_status() Logger.info(LOCATION, 'DeviceStatus = ' + device_status.value) if device_status == DeviceStatus.NEW: self.pair() if device_status == DeviceStatus.PAIRED: self.activate() def pair(self): success = PairingService().run() if success: self.configuration.set_device_status(DeviceStatus.PAIRED.value) self.configuration_store.save(self.configuration) self.activate() def activate(self): success = ActivationService().run() if success: self.configuration.set_device_status(DeviceStatus.ACTIVE.value) self.configuration_store.save(self.configuration) def generate_qr_code(self): try: Logger.info(LOCATION, 'Generating QR Code for alternative pairing...') device_information = self.configuration.get_device_information() image = qrcode.make(json.dumps(device_information), image_factory=PymagingImage) Store.save_qrcode(image) Logger.success(LOCATION, 'QR Code successfully generated') except Exception as exception: Logger.error(LOCATION, 'QR Code not generated') raise exception
class PairingResource: def __init__(self): self.configuration_store = ConfigurationStore() def on_get(self, request, response): Logger.info(LOCATION, INCOMING_REQUEST + METHOD_GET + ' ' + PAIRING_ENDPOINT) configuration = self.configuration_store.get() if configuration.get_device_status() is not DeviceStatus.NEW: error = 'Device is already paired.' Logger.error(LOCATION, error) raise falcon.HTTPForbidden(description=error) response.media = configuration.get_device_information subprocess.Popen(['make', 'pair'])
class ActivationResource: def __init__(self): self.configuration_service = ConfigurationService() self.configuration_store = ConfigurationStore() def on_get(self, request, response): Logger.info(LOCATION, "Serving Activation Request...") configuration = self.configuration_store.get() if configuration.get_device_status() is DeviceStatus.ACTIVE: error = 'Device is already activated' Logger.error(LOCATION, error) raise falcon.HTTPBadRequest(description=error) else: self.configuration_service.resume_configuration()
class DeviceCharacteristic(Characteristic): #On initializing this class the uuid and read property is defined def __init__(self): Characteristic.__init__(self, { 'uuid': 'CAD1B5132DA446099908234C6D1B2A9C', 'properties': ['read'], }) # define/create a store for data bytes self.byteData = bytearray() self.configuration_store = ConfigurationStore() # OnReadRequest shall be trigged when device characteristics information # are needed. As per the offset the data shall be sent back via the callback. # On the first request the offset shall be 0, hence the function compiles # the necessary information w.r.t device characteristics and returns through callback. # Since the entire data is not sent back by the caller, every time the offset value # is updated by the caller. This means from the specified offset the data needs to be sent # as byte sequence through CB. The sent data shall be of JSON format. def onReadRequest(self, offset, callback): if not offset: configuration = self.configuration_store.get() Logger.info(LOCATION, 'Device data being read by connected device.') device_status = configuration.get_device_status() device_information = configuration.get_device_information() data = { 'deviceID': device_information['deviceID'], 'makerID': device_information['makerID'], 'name': socket.gethostname(), 'publicKey': device_information['publicKey'] } # Added required information for Multipairing device. if (device_status == DeviceStatus.MULTIPAIR): data['multipair'] = 1 data['aid'] = device_information['aid'] self.byteData.extend(map(ord, json.dumps(data))) Logger.info(LOCATION, json.dumps(data)) callback(Characteristic.RESULT_SUCCESS, self.byteData[offset:])
class DeviceCharacteristic(Characteristic): #On initializing this class the uuid and read property is defined def __init__(self): Characteristic.__init__(self, { 'uuid': BLENO_DEVICE_CHARACTERISTICS_UUID, 'properties': ['read'], }) # define/create a store for data bytes self.deviceData = bytearray() self.configuration_store = ConfigurationStore() ''' OnReadRequest is trigged when device specific data are required. As per the offset the data is prepared and sent back via the callback. On first request the offset will be 0, hence the function compiles the device characteristics data and returns it via the callback. Depending on the offset values, the data is returned through the callback during subsequent calls to this API. The sent data is of JSON format. ''' def onReadRequest(self, offset, callback): if not offset: configuration = self.configuration_store.get() Logger.info(LOCATION, 'Device data being read by connected device.') device_status = configuration.get_device_status() device_information = configuration.get_device_information() data = { 'deviceID': device_information['deviceID'], 'makerID': device_information['makerID'], 'name': socket.gethostname(), 'publicKey' : device_information['publicKey'] } # Multipairing mode checks if(device_status == DeviceStatus.MULTIPAIR): data['multipair'] = 1 data['aid'] = device_information['aid'] self.deviceData.extend(map(ord, json.dumps(data))) Logger.info(LOCATION, json.dumps(data)) #Return through the callback the necessary data callback(Characteristic.RESULT_SUCCESS, self.deviceData[offset:])
class ConfigurationService: def __init__(self): self.configuration_store = ConfigurationStore() self.configuration = self.configuration_store.get() self.key_generator = KeyGenerator() def initialize_configuration(self, maker_id): Logger.info(LOCATION, 'Initializing configuration...') public_key, private_key = KeyGenerator().generate_key() device_id = self.key_generator.generate_uuid() #initialize the alternative id. aid = 0 # Option for Multi pairing # If the option is yes, then alternative id needed print('Enable Multi pair(yes/no)') status = input() if (status == 'yes'): device_status = DeviceStatus.MULTIPAIR.value print('Enter your alternativeID:') aid = input() else: device_status = DeviceStatus.NEW.value # Added alternative id as an argument to initializing the configuration self.configuration.initialize(maker_id, device_id, device_status, aid, public_key, private_key) self.configuration_store.save(self.configuration) self.generate_qr_code() Logger.success(LOCATION, 'Configuration successfully initialized.') def resume_configuration(self): device_status = self.configuration.get_device_status() Logger.info(LOCATION, 'DeviceStatus = ' + device_status.value) if device_status == DeviceStatus.NEW: self.pair() if device_status == DeviceStatus.PAIRED: self.activate() def pair(self): success = PairingService().run() if success: self.configuration.set_device_status(DeviceStatus.PAIRED.value) self.configuration_store.save(self.configuration) self.activate() def activate(self): success = ActivationService().run() if success: self.configuration.set_device_status(DeviceStatus.ACTIVE.value) self.configuration_store.save(self.configuration) def generate_qr_code(self): try: Logger.info(LOCATION, 'Generating QR Code for alternative pairing...') device_information = self.configuration.get_device_information() image = qrcode.make(json.dumps(device_information), image_factory=PymagingImage) Store.save_qrcode(image) Logger.success(LOCATION, 'QR Code successfully generated') except Exception as exception: Logger.error(LOCATION, 'QR Code not generated') raise exception