class DataCollectorService(object): def __init__(self, comm_config, data_dirpath): self.comm_config = comm_config self.comm_config['subscribe'][ 'berrynet/engine/tensorflow/result'] = self.update self.comm_config['subscribe'][ 'berrynet/engine/mvclassification/result'] = self.update self.comm = Communicator(self.comm_config, debug=True) self.data_dirpath = data_dirpath def update(self, pl): if not os.path.exists(self.data_dirpath): try: os.mkdir(self.data_dirpath) except Exception as e: logger.warn('Failed to create {}'.format(self.data_dirpath)) raise (e) payload_json = payload.deserialize_payload(pl.decode('utf-8')) jpg_bytes = payload.destringify_jpg(payload_json['bytes']) payload_json.pop('bytes') logger.debug('inference text result: {}'.format(payload_json)) timestamp = datetime.now().isoformat() with open(pjoin(self.data_dirpath, timestamp + '.jpg'), 'wb') as f: f.write(jpg_bytes) with open(pjoin(self.data_dirpath, timestamp + '.json'), 'w') as f: f.write(json.dumps(payload_json, indent=4)) def run(self, args): """Infinite loop serving inference requests""" self.comm.run()
class DashboardService(object): def __init__(self, service_name, comm_config): self.service_name = service_name self.comm_config = comm_config self.comm_config['subscribe'][ 'berrynet/engine/tensorflow/result'] = self.update self.comm_config['subscribe'][ 'berrynet/engine/mvclassification/result'] = self.update self.comm = Communicator(self.comm_config, debug=True) self.basedir = '/usr/local/berrynet/dashboard/www/freeboard' def update(self, pl): payload_json = payload.deserialize_payload(pl.decode('utf-8')) jpg_bytes = payload.destringify_jpg(payload_json['bytes']) inference_result = [ '{0}: {1}<br>'.format(anno['label'], anno['confidence']) for anno in payload_json['annotations'] ] logger.debug('inference results: {}'.format(inference_result)) with open(pjoin(self.basedir, 'snapshot.jpg'), 'wb') as f: f.write(jpg_bytes) self.comm.send('berrynet/dashboard/snapshot', 'snapshot.jpg') self.comm.send('berrynet/dashboard/inferenceResult', json.dumps(inference_result)) def run(self, args): """Infinite loop serving inference requests""" self.comm.run()
class DydaConfigUpdateClient(object): def __init__(self, comm_config, debug=False): self.comm_config = comm_config for topic, functor in self.comm_config['subscribe'].items(): self.comm_config['subscribe'][topic] = self.handleResult self.comm = Communicator(self.comm_config, debug=True) def sendConfig(self, jsonPayload): self.comm.send(self.comm_config['publish'], jsonPayload) def handleResult(self, pl): try: payload_json = payload.deserialize_payload(pl.decode('utf-8')) print(payload_json) self.comm.stop_nb() sys.exit(0) except Exception as e: logger.info(e) def run(self, args): """Infinite loop serving inference requests""" with open(args['payload']) as f: payload = f.read() self.sendConfig(payload) self.comm.run()
class DydaConfigUpdateService(object): def __init__(self, comm_config, debug=False): self.comm_config = comm_config for topic, functor in self.comm_config['subscribe'].items(): self.comm_config['subscribe'][topic] = self.handleConfig self.comm = Communicator(self.comm_config, debug=True) def sendConfig(self, jsonPayload): self.comm.send(self.comm_config['publish'], jsonPayload) def handleConfig(self, pl): payload_json = "" try: payload_json = payload.deserialize_payload(pl.decode('utf-8')) self.comm.send(self.comm_config['publish'], payload.serialize_payload(payload_json)) except Exception as e: logger.info(e) # output config file with open(self.comm_config['configfile'], 'w') as configfile: configfile.write(payload.serialize_payload(payload_json)) configfile.close() # restart service subprocess.run(["supervisorctl", "restart", "bnpipeline-bndyda"]) def run(self, args): """Infinite loop serving inference requests""" self.comm.run()
class EngineService(object): def __init__(self, service_name, engine, comm_config): self.service_name = service_name self.engine = engine self.comm_config = comm_config for topic, functor in self.comm_config['subscribe'].items(): self.comm_config['subscribe'][topic] = eval(functor) self.comm_config['subscribe'][ 'berrynet/data/rgbimage'] = self.inference self.comm = Communicator(self.comm_config, debug=True) def inference(self, pl): duration = lambda t: (datetime.now() - t).microseconds / 1000 t = datetime.now() logger.debug('payload size: {}'.format(len(pl))) logger.debug('payload type: {}'.format(type(pl))) jpg_json = payload.deserialize_payload(pl.decode('utf-8')) jpg_bytes = payload.destringify_jpg(jpg_json['bytes']) logger.debug('destringify_jpg: {} ms'.format(duration(t))) t = datetime.now() rgb_array = payload.jpg2rgb(jpg_bytes) logger.debug('jpg2rgb: {} ms'.format(duration(t))) t = datetime.now() image_data = self.engine.process_input(rgb_array) output = self.engine.inference(image_data) model_outputs = self.engine.process_output(output) logger.debug('Result: {}'.format(model_outputs)) logger.debug('Classification takes {} ms'.format(duration(t))) #self.engine.cache_data('model_output', model_outputs) #self.engine.cache_data('model_output_filepath', output_name) #self.engine.save_cache() self.result_hook(self.generalize_result(jpg_json, model_outputs)) def generalize_result(self, eng_input, eng_output): eng_input.update(eng_output) return eng_input def result_hook(self, generalized_result): logger.debug('base result_hook') def run(self, args): """Infinite loop serving inference requests""" self.engine.create() self.comm.run()
class PipelineRestarterService(object): def __init__(self, service_name, comm_config): self.service_name = service_name self.comm_config = comm_config self.comm_config['subscribe']['dlboxapi/config/update'] = \ self.restart_pipeline self.comm = Communicator(self.comm_config, debug=True) def restart_pipeline(self, pl): logger.debug('Restart pipeline') subprocess.call('dlbox-manager restart dlbox-pipeline.service', shell=True) def run(self, args): """Infinite loop serving pipeline restart requests""" self.comm.run()
class DydaConfigUpdateService(object): def __init__(self, comm_config, debug=False): self.comm_config = comm_config for topic, functor in self.comm_config['subscribe'].items(): self.comm_config['subscribe'][topic] = self.handleConfig self.comm = Communicator(self.comm_config, debug=True) idlistConfig = configparser.ConfigParser() idlistConfig.read(self.comm_config['idlist']) self.idlist = idlistConfig["ID"] def sendConfig(self, jsonPayload): self.comm.send(self.comm_config['publish'], jsonPayload) def handleConfig(self, pl): payload_json = "" try: id = pl.decode('utf-8') if (id in self.idlist): configFilename = self.idlist[id] f = open(configFilename) payload_json = payload.deserialize_payload(f.read()) self.sendConfig(payload.serialize_payload(payload_json)) else: logger.warning("ID %s is not in idlist" % (id)) return except Exception as e: logger.info(e) # output config file with open(self.comm_config['configfile'], 'w') as configfile: configfile.write(payload.serialize_payload(payload_json)) configfile.close() # restart service subprocess.run(["supervisorctl", "restart", "bnpipeline-bndyda"]) def run(self, args): """Infinite loop serving inference requests""" self.comm.run()
class SnapshotService(object): def __init__(self, comm_config): self.comm_config = comm_config for topic, functor in self.comm_config['subscribe'].items(): self.comm_config['subscribe'][topic] = eval(functor) self.comm_config['subscribe'][ 'berrynet/trigger/controller/snapshot'] = self.snapshot self.comm = Communicator(self.comm_config, debug=True) def snapshot(self, pl): '''Send camera snapshot. The functionality is the same as using camera client in file mode. The difference is that snapshot client retrieves image from camera instead of given filepath. ''' duration = lambda t: (datetime.now() - t).microseconds / 1000 # WORKAROUND: Prevent VideoCapture from buffering frames. # VideoCapture will buffer frames automatically, and we need # to find a way to disable it. self.capture = cv2.VideoCapture(0) status, im = self.capture.read() if (status is False): logger.warn('ERROR: Failure happened when reading frame') t = datetime.now() retval, jpg_bytes = cv2.imencode('.jpg', im) mqtt_payload = payload.serialize_jpg(jpg_bytes) self.comm.send('berrynet/data/rgbimage', mqtt_payload) logger.debug('send: {} ms'.format(duration(t))) self.capture.release() def run(self, args): """Infinite loop serving inference requests""" self.comm.run()
class DataCollectorService(object): def __init__(self, comm_config, data_dirpath): self.comm_config = comm_config for topic, functor in self.comm_config['subscribe'].items(): self.comm_config['subscribe'][topic] = eval(functor) #self.comm_config['subscribe']['berrynet/data/rgbimage'] = self.update self.comm_config['subscribe']['berrynet/engine/pipeline/result'] = self.save_pipeline_result self.comm = Communicator(self.comm_config, debug=True) self.data_dirpath = data_dirpath def update(self, pl): payload_json = payload.deserialize_payload(pl.decode('utf-8')) # update UI with the latest inference result self.ui.update(payload_json, 'bytes') if self.data_dirpath: if not os.path.exists(self.data_dirpath): try: os.mkdir(self.data_dirpath) except Exception as e: logger.warn('Failed to create {}'.format(self.data_dirpath)) raise(e) jpg_bytes = payload.destringify_jpg(payload_json['bytes']) payload_json.pop('bytes') logger.debug('inference text result: {}'.format(payload_json)) timestamp = datetime.now().isoformat() with open(pjoin(self.data_dirpath, timestamp + '.jpg'), 'wb') as f: f.write(jpg_bytes) with open(pjoin(self.data_dirpath, timestamp + '.json'), 'w') as f: f.write(json.dumps(payload_json, indent=4)) def save_pipeline_result(self, pl): payload_json = payload.deserialize_payload(pl.decode('utf-8')) # update UI with the latest inference result self.ui.update(payload_json, 'image_blob') if self.data_dirpath: if not os.path.exists(self.data_dirpath): try: os.mkdir(self.data_dirpath) except Exception as e: logger.warn('Failed to create {}'.format(self.data_dirpath)) raise(e) jpg_bytes = payload.destringify_jpg(payload_json['image_blob']) payload_json.pop('image_blob') logger.debug('inference text result: {}'.format(payload_json)) timestamp = datetime.now().isoformat() with open(pjoin(self.data_dirpath, timestamp + '.jpg'), 'wb') as f: f.write(jpg_bytes) with open(pjoin(self.data_dirpath, timestamp + '.json'), 'w') as f: f.write(json.dumps(payload_json, indent=4)) def send_snapshot_trigger(self): payload = {} payload['timestamp'] = datetime.now().isoformat() mqtt_payload = json.dumps(payload) self.comm.send('berrynet/trigger/controller/snapshot', mqtt_payload) def run(self, args): """Infinite loop serving inference requests""" self.comm.run()
class GmailService(object): def __init__(self, comm_config): self.comm_config = comm_config for topic, functor in self.comm_config['subscribe'].items(): self.comm_config['subscribe'][topic] = eval(functor) self.comm_config['subscribe'][ 'berrynet/engine/darknet/result'] = self.update self.comm_config['subscribe'][ 'berrynet/engine/tensorflow/result'] = self.update self.comm = Communicator(self.comm_config, debug=True) self.email = comm_config['email'] self.pipeline_compatible = comm_config['pipeline_compatible'] self.target_label = comm_config['target_label'] def find_target_label(self, target_label, generalized_result): label_list = [i['label'] for i in generalized_result['annotations']] logger.debug('Result labels: {}'.format(label_list)) return target_label in label_list def update(self, pl): payload_json = payload.deserialize_payload(pl.decode('utf-8')) if self.pipeline_compatible: b64img_key = 'image_blob' else: b64img_key = 'bytes' jpg_bytes = payload.destringify_jpg(payload_json[b64img_key]) payload_json.pop(b64img_key) logger.debug('inference text result: {}'.format(payload_json)) match_target_label = self.find_target_label(self.target_label, payload_json) logger.debug('Find target label {0}: {1}'.format( self.target_label, match_target_label)) if match_target_label: timestamp = datetime.now().isoformat() notification_image = pjoin('/tmp', timestamp + '.jpg') notification_text = pjoin('/tmp', timestamp + '.json') with open(notification_image, 'wb') as f: f.write(jpg_bytes) with open(notification_text, 'w') as f: f.write(json.dumps(payload_json, indent=4)) try: send_email_text(self.email['sender_address'], self.email['sender_password'], self.email['receiver_address'], body=('Target label {} is found. ' 'Please check the attachments.' ''.format(self.target_label)), subject='BerryNet mail client notification', attachments=set( [notification_image, notification_text])) except Exception as e: logger.warn(e) os.remove(notification_image) os.remove(notification_text) else: # target label is not in generalized result, do nothing pass def run(self, args): """Infinite loop serving inference requests""" self.comm.run()