示例#1
0
 def start_controller(self, section, options, **kwargs):
     """Start the controller
     """
     logger.info("Start the controller")
     cmd_classes = kwargs.pop('cmd_classes', [])
     if not COMMAND_CONTROLLER in cmd_classes:
         cmd_classes.append(COMMAND_CONTROLLER)
     self._controller = JNTNode( uuid=section, options=options, cmd_classes=cmd_classes, **kwargs)
     self._controller.add_internal_system_values()
     self._controller.add_internal_config_values()
     self._controller.hadd_get(section, None)
     self._controller.load_system_from_local()
     self.mqtt_controller = MQTTClient(options=options.data)
     self.mqtt_controller.connect()
     logger.debug("[%s] - Subscribe to topic %s", self.__class__.__name__, TOPIC_NODES_REQUEST%(self._controller.hadd))
     self.mqtt_controller.subscribe(topic=TOPIC_NODES_REQUEST%(self._controller.hadd), callback=self.on_controller_request)
     self.mqtt_controller.start()
示例#2
0
class JNTControllerManager(object):
    """A node dedicated for a special thread/server like the the DHCP server or the listener thread in the webapp
    """
    def __init__(self):
        self.mqtt_controller = None
        self._controller = None
        self.heartbeat_controller_timer = None
        self._requests = {'request_info_nodes' : self.request_info_nodes, 'request_info_users' : self.request_info_users, 'request_info_configs' : self.request_info_configs,
                          'request_info_systems' : self.request_info_systems, 'request_info_basics' : self.request_info_basics, 'request_info_commands' : self.request_info_commands }
        self.uuid = self.options.get_option(self.section, 'uuid')
        if self.uuid == None:
            self.uuid = muuid.uuid1()
            self.options.set_option(self.section, 'uuid', '%s'%self.uuid)


    def stop_controller_timer(self):
        """Stop the controller timer
        """
        if self.heartbeat_controller_timer is not None:
            self.heartbeat_controller_timer.cancel()
            self.heartbeat_controller_timer = None

    def start_controller_timer(self):
        """Start the controller tier
        """
        self.stop_controller_timer()
        self.heartbeat_controller_timer = threading.Timer(self._controller.heartbeat+5, self.heartbeat_controller)
        self.heartbeat_controller_timer.start()

    def stop_controller(self):
        """Stop the controller
        """
        logger.info("Stop the controller")
        if self.mqtt_controller is not None:
            self.mqtt_controller.unsubscribe(topic=TOPIC_NODES_REQUEST%(self._controller.hadd))
            self.mqtt_controller.stop()
            if self.mqtt_controller.is_alive():
                try:
                    self.mqtt_controller.join()
                except:
                    logger.exception("Catched exception")
            self.mqtt_controller = None

    def start_controller(self, section, options, **kwargs):
        """Start the controller
        """
        logger.info("Start the controller")
        cmd_classes = kwargs.pop('cmd_classes', [])
        if not COMMAND_CONTROLLER in cmd_classes:
            cmd_classes.append(COMMAND_CONTROLLER)
        self._controller = JNTNode( uuid=section, options=options, cmd_classes=cmd_classes, **kwargs)
        self._controller.add_internal_system_values()
        self._controller.add_internal_config_values()
        self._controller.hadd_get(section, None)
        self._controller.load_system_from_local()
        self.mqtt_controller = MQTTClient(options=options.data)
        self.mqtt_controller.connect()
        logger.debug("[%s] - Subscribe to topic %s", self.__class__.__name__, TOPIC_NODES_REQUEST%(self._controller.hadd))
        self.mqtt_controller.subscribe(topic=TOPIC_NODES_REQUEST%(self._controller.hadd), callback=self.on_controller_request)
        self.mqtt_controller.start()

    def heartbeat_controller(self):
        """Send a add_ctrl:-1 heartbeat message. It will ping all devices managed by this controller.
        """
        logger.debug("[%s] - Send heartbeat for controller", self.__class__.__name__)
        if self.heartbeat_controller_timer is not None:
            #The manager is started
            self.heartbeat_controller_timer.cancel()
            self.heartbeat_controller_timer = None
        self.heartbeat_controller_timer = threading.Timer(self._controller.heartbeat, self.heartbeat_controller)
        self.heartbeat_controller_timer.start()
        if self._controller.hadd is not None:
            #~ print self.nodes[node].hadd
            add_ctrl, add_node = self._controller.split_hadd()
            msg = {'add_ctrl':add_ctrl, 'add_node':add_node, 'state':'ONLINE'}
            self.mqtt_controller.publish_heartbeat_msg(msg)

    def get_controller_hadd(self):
        """Return the controller hadd"""
        if self._controller is None:
            return None
        return self._controller.hadd

    def get_controller(self):
        """Return the controller"""
        return self._controller

    def on_controller_request(self, client, userdata, message):
        """On request

        :param client: the Client instance that is calling the callback.
        :type client: paho.mqtt.client.Client
        :param userdata: user data of any type and can be set when creating a new client instance or with user_data_set(userdata).
        :type userdata: all
        :param message: The message variable is a MQTTMessage that describes all of the message parameters.
        :type message: paho.mqtt.client.MQTTMessage
        """
        logger.debug("on_request receive message %s", message.payload)
        try:
            data = json_loads(message.payload)
            #~ print data['uuid']
            #We should check what value is requested
            #{'hadd', 'cmd_class', 'type'='list', 'genre'='0x04', 'data'='node|value|config', 'uuid'='request_info'}
            if data['cmd_class'] == COMMAND_DISCOVERY:
                if data['genre'] == 0x04:
                    if data['uuid'] in self._requests:
                        resp = {}
                        resp.update(data)
                        try:
                            if message.topic.find('broadcast') != -1:
                                topic = "/broadcast/reply/%s" % data['data']
                                self._requests[data['uuid']](topic, resp)
                            else:
                                topic = "/nodes/%s/reply" % data['data']
                                self._requests[data['uuid']](topic, resp)
                            return
                        except:
                            logger.exception("Exception when running on_request method")
                            return
            logger.warning("Unknown request value %s", data)
        except:
            logger.exception("Exception in on_request")


    def request_info_nodes(self, reply_topic, resp):
        """
        """
        resp['data'] = self._controller.to_dict()
        msg = json_dumps(resp)
        self.publish_request(reply_topic, msg)

    def request_info_users(self, reply_topic, resp):
        """
        """
        resp['data'] = {}
        for kvalue in self._controller.values.keys():
            value = self._controller.values[kvalue]
            if value.genre == 0x02:
                if value.hadd not in resp['data']:
                    resp['data'][value.hadd] = {}
                resp['data'][value.hadd][value.uuid] = value.to_dict()
        msg = json_dumps(resp)
        self.publish_request(reply_topic, msg)

    def request_info_configs(self, reply_topic, resp):
        """
        """
        resp['data'] = {}
        for kvalue in self._controller.values.keys():
            value = self._controller.values[kvalue]
            if value.genre == 0x03:
                if value.hadd not in resp['data']:
                    resp['data'][value.hadd] = {}
                resp['data'][value.hadd][value.uuid] = value.to_dict()
        msg = json_dumps(resp)
        self.publish_request(reply_topic, msg)

    def request_info_basics(self, reply_topic, resp):
        """
        """
        resp['data'] = {}
        for kvalue in self._controller.values.keys():
            value = self._controller.values[kvalue]
            if value.genre == 0x01:
                if value.hadd not in resp['data']:
                    resp['data'][value.hadd] = {}
                resp['data'][value.hadd][value.uuid] = value.to_dict()
        msg = json_dumps(resp)
        self.publish_request(reply_topic, msg)

    def request_info_systems(self, reply_topic, resp):
        """
        """
        resp['data'] = {}
        for kvalue in self._controller.values.keys():
            value = self._controller.values[kvalue]
            if value.genre == 0x04:
                if value.hadd not in resp['data']:
                    resp['data'][value.hadd] = {}
                resp['data'][value.hadd][value.uuid] = value.to_dict()
        msg = json_dumps(resp)
        self.publish_request(reply_topic, msg)

    def request_info_commands(self, reply_topic, resp):
        """
        """
        resp['data'] = {}
        for kvalue in self._controller.values.keys():
            value = self._controller.values[kvalue]
            if value.genre == 0x04:
                if value.hadd not in resp['data']:
                    resp['data'][value.hadd] = {}
                resp['data'][value.hadd][value.uuid] = value.to_dict()
        msg = json_dumps(resp)
        self.publish_request(reply_topic, msg)

    def publish_request(self, reply_topic, msg):
        """
        """
        self.mqtt_controller.publish(topic=reply_topic, payload=msg)