def test_verify_mac(): table = { "AA:BB:CC:DD:EE:FF": True, "AA:BB:CC:DD:EE": False } for mac in table: assert hades_utils.verify_mac(mac) is table[mac]
def on_ping(self, client, userdata, msg): _, net, mac, _ = hades_utils.split_segments4(msg.topic) if not hades_utils.verify_mac(mac): logging.info("MAC address (%s) is invalid!", mac) return topic = f"{self.hermesPrefix}/node/{net}/{mac}/hades/pong" logging.debug("publishing on %s", topic) self.client.publish(topic, None, 0)
def on_stats(self, client, userdata, msg): data = {} first = False _, net, mac, _ = hades_utils.split_segments4(msg.topic) if not hades_utils.verify_mac(mac): logging.info("MAC address (%s) is invalid!", mac) return else: logging.info("Received statistics for %s", mac) # parse the currently read temperature payload = json.loads(msg.payload) if payload['temperature'] is None: logging.error("There is no Temperature entry for %s", mac) return state_file = os.path.join(self.states_dir, mac) if os.path.exists(state_file): # first read what values exist already - we don't want to lose them with open(state_file, 'r') as json_file: data = json.load(json_file) prev_delta = hades_utils.num(data['stats']['prev_delta']) prev_temp = hades_utils.num(data['stats']['prev_temperature']) send_interval = hades_utils.num(data['stats']['send_interval']) else: # its the first statistic from the device - # default values, roll out! prev_temp = payload['temperature'] prev_delta = 0 send_interval = 1 data['stats'] = { 'prev_temperature': prev_temp, 'prev_delta': prev_delta, 'curr_temperature': payload['temperature'], 'send_interval': send_interval, } with open(state_file, 'w') as outfile: json.dump(data, outfile) # at this point we should have dumped the received statistics to the # state file - we can start the training. if self.dqn_agent.device_exists(mac) is not True: first = True self.dqn_agent.add_device(mac) self.dqn_agent.train(mac) # if it was a first request - send a new interval if first is True: self.send_interval(net, mac) return
def on_request_send_interval(self, client, userdata, msg): """on_request will handle a request for a new model. A server may ask for a new model via this handler and the handler should respond with a new model. endpoint: /hades/+/+/interval/request """ _, net, mac, _ = hades_utils.split_segments4(msg.topic) if not hades_utils.verify_mac(mac): logging.info("MAC address (%s) is invalid!", mac) return self.send_interval(net, mac) return
def on_request(self, client, userdata, msg): _, net, mac, _ = hades_utils.split_segments4(msg.topic) if not hades_utils.verify_mac(mac): logging.info("MAC address (%s) is invalid!", mac) return # does a model for this device exist? if hades_utils.check_model(self.models_dir, mac): modelMac = os.path.join(self.models_dir, mac) # prepare data f = open(modelMac, 'rb') byteArray = bytes(f.read()) f.close() timeSent = time.localtime() currentTime = json.dumps({ "model": modelMac, "time_sent": time.strftime("%H:%M:%S", timeSent) }) # construct publish topics for hermes and iotctl. topic = f"{self.hermesPrefix}/node/{net}/{mac}/hades/model/receive" topicEvent = f"node/{net}/{mac}/hades/event/sent" logging.debug("publishing on %s", topic) self.client.publish(topic, byteArray, 0) # Notify IoT Controller about a sent model # TODO: implement an Event infrastructure. logging.debug("publishing on %s", topicEvent) self.client.publish(topicEvent, currentTime, 0) else: logging.info("no model for node (%s)", mac) return