Esempio n. 1
0
class XBMCNotificationListener(XplPlugin):
    """ Create listener for xPL messages about xbmc notifications
    """
    def __init__(self):
        """ Create lister for XBMC notifications
        """
        XplPlugin.__init__(self, name='xbmc_not')
        # Create logger
        self.log.debug("Listener for XBMC notifications created")

        # Get configuration
        self._config = Query(self.myxpl, self.log)
        address = self._config.query('xbmc_not', 'address')
        delay = self._config.query('xbmc_not', 'delay')
        maxdelay = self._config.query('xbmc_not', 'maxdelay')

        self.log.debug("Config : address = " + address)
        self.log.debug("Config : delay = " + delay)
        self.log.debug("Config : maxdelay = " + maxdelay)

        # Create XBMCNotification object
        self.xbmc_notification_manager = XBMCNotification(self.log, address, delay, \
                                                         maxdelay)

        # Create listeners
        Listener(self.xbmc_notification_cb, self.myxpl, {
            'schema': 'osd.basic',
            'xpltype': 'xpl-cmnd'
        })
        self.enable_hbeat()

        self.enable_hbeat()

    def xbmc_notification_cb(self, message):
        """ Call XBMC notification lib
            @param message : message to send
        """
        self.log.debug("Call xbmc_notification_cb")

        if 'command' in message.data:
            command = message.data['command']
        if 'text' in message.data:
            text = message.data['text']
        if 'row' in message.data:
            row = message.data['row']
        if 'delay' in message.data:
            delay = message.data['delay']

        self.log.debug("Call _notify")
        self.xbmc_notification_manager.notify(command, text, row, delay)
Esempio n. 2
0
class Mochad(XplPlugin):

    def __init__(self):
        # Connect to the socket

        XplPlugin.__init__(self, name = 'mochad')

        self.mochad_socket = None

        self._config = Query(self.myxpl, self.log)
        self.__host = self._config.query('mochad','mochad-host')
        self.__port = self._config.query('mochad','mochad-port')
        if self._config.query('mochad','cm15') == "True":
            self.__cm15 = True
        else:
            self.__cm15 = False
        if self._config.query('mochad','cm19') == "True":
            self.__cm19 = True
        else:
            self.__cm19 = False

        if self.__cm15:
            self.__itf = "pl"
        elif self.__cm19:
            self.__itf = "rf"

        self.connect()

        child_pid = os.fork()
        if child_pid == 0:
            self.listener()
        else:
            return None

    def connect(self):
        for res in socket.getaddrinfo(self.__host, self.__port, socket.AF_UNSPEC, socket.SOCK_STREAM):
            af, socktype, proto, canonname, sa = res
            try:
                self.mochad_socket = socket.socket(af, socktype, proto)
            except socket.error, msg:
                self.mochad_socket = None
                continue
            try:
                self.mochad_socket.connect(sa)
            except socket.error, msg:
                self.mochad_socket.close()
                self.mochad_socket = None
                continue
            break
Esempio n. 3
0
class CIDManager(XplPlugin):
    """ Manage the modem to get CID
    """

    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='cidmodem')

        # Configuration
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('cidmodem', 'device')

        cid_command = self._config.query('cidmodem', 'cid-command')

        # Init Modem
        cid  = CallerIdModem(self.log, self.send_xpl)
        
        # Open Modem
        try:
            cid.open(device, cid_command)
        except CallerIdModemException as e:
            self.log.error(e.value)
            print(e.value)
            self.force_leave()
            return
            
        # Start reading Modem
        cid_process = threading.Thread(None,
                                   cid.listen,
                                   "listen_cid",
                                   (),
                                   {})                                  
        cid_process.start()                              
        self.enable_hbeat()

    def send_xpl(self, num):
        """ Send xPL message on network
            @param num : call number
        """
        print("Input call : %s " % num)
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("cid.basic")
        msg.add_data({"calltype" : "INBOUND"})
        msg.add_data({"phone" : num})
        self.myxpl.send(msg)
Esempio n. 4
0
class Zwave(XplPlugin):
    def __init__(self):
        XplPlugin.__init__(self, name='zwave')
        Listener(self.zwave_cmd_cb, self.myxpl, {
            'schema': 'zwave.basic',
            'xpltype': 'xpl-cmnd'
        })
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('zwave', 'device')
        speed = self._config.query('zwave', 'speed')
        print(device, '  ', speed)
        #        device='/dev/ttyUSB0'
        self.myzwave = ZWave(device, speed, self.zwave_cb, self.log)
        self.myzwave.start()
        self.enable_hbeat()
        self.myzwave.send('Network Discovery')
        sleep(3)

    def zwave_cmd_cb(self, message):
        if 'command' in message.data:
            cmd = message.data['command']
            node = message.data['node']
            if cmd == 'level':
                lvl = message.data['level']
                self.myzwave.send(cmd, node, lvl)
            else:
                self.myzwave.send(cmd, node)

    def zwave_cb(self, read):
        mess = XplMessage()
        if 'info' in read:
            self.log.error("Error : Node %s unreponsive" % read['node'])
        elif 'Find' in read:
            print("node enregistré : %s" % read['Find'])
        elif 'event' in read:
            mess.set_type('xpl-trig')
            mess.set_schema('zwave.basic')
            mess.add_data({
                'event': read['event'],
                'node': read['node'],
                'level': read['level']
            })
            self.myxpl.send(mess)
        elif 'command' in read and read['command'] == 'Info':
            print("Home ID is %s" % read['Home ID'])
Esempio n. 5
0
class CIDManager(XplPlugin):
    """ Manage the modem to get CID
    """
    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='cidmodem')

        # Configuration
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('cidmodem', 'device')

        cid_command = self._config.query('cidmodem', 'cid-command')

        # Init Modem
        cid = CallerIdModem(self.log, self.send_xpl)

        # Open Modem
        try:
            cid.open(device, cid_command)
        except CallerIdModemException as e:
            self.log.error(e.value)
            print(e.value)
            self.force_leave()
            return

        # Start reading Modem
        cid_process = threading.Thread(None, cid.listen, "listen_cid", (), {})
        cid_process.start()
        self.enable_hbeat()

    def send_xpl(self, num):
        """ Send xPL message on network
            @param num : call number
        """
        print("Input call : %s " % num)
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("cid.basic")
        msg.add_data({"calltype": "INBOUND"})
        msg.add_data({"phone": num})
        self.myxpl.send(msg)
Esempio n. 6
0
class Zwave(XplPlugin):
    def __init__(self):
        XplPlugin.__init__(self, name = 'zwave')
        Listener(self.zwave_cmd_cb, self.myxpl,{'schema': 'zwave.basic',
                                                 'xpltype': 'xpl-cmnd'})
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('zwave', 'device')
        speed = self._config.query('zwave', 'speed')
        print(device, '  ', speed)
#        device='/dev/ttyUSB0'
        self.myzwave = ZWave(device, speed, self.zwave_cb, self.log)
        self.myzwave.start()
        self.enable_hbeat()
        self.myzwave.send('Network Discovery')
        sleep(3)

    def zwave_cmd_cb(self, message):
        if 'command' in message.data:
            cmd = message.data['command']
            node = message.data['node']
            if cmd == 'level':
                lvl = message.data['level']
                self.myzwave.send(cmd, node, lvl)
            else:
                self.myzwave.send(cmd, node)

    def zwave_cb(self, read):
        mess = XplMessage()
        if 'info' in read:
            self.log.error ("Error : Node %s unreponsive" % read['node'])
	elif 'Find' in read:
	    print("node enregistré : %s" % read['Find'])
        elif 'event' in read:
            mess.set_type('xpl-trig')
            mess.set_schema('zwave.basic')
            mess.add_data({'event' : read['event'],
                           'node' : read['node'],
                           'level' : read['level']})
            self.myxpl.send(mess)
        elif 'command' in read and read['command'] == 'Info':
            print("Home ID is %s" % read['Home ID'])
Esempio n. 7
0
class MirrorManager(XplPlugin):
    """ Manage the Mir:ror device and connect it to xPL
    """

    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='mirror')
        # Get config
        #   - device
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('mirror', 'device')

        # Init Mir:ror
        mirror  = Mirror(self.log, self.send_xpl)
        
        # Open Mir:ror
        try:
            mirror.open(device)
        except MirrorException as e:
            self.log.error(e.value)
            print(e.value)
            self.force_leave()
            return
            
        # Start reading Mir:ror
        mirror_process = threading.Thread(None,
                                   mirror.listen,
                                   "mirror-process-reader",
                                   (self.get_stop(),),
                                   {})
        self.register_thread(mirror_process)
        mirror_process.start()
        self.enable_hbeat()


    def send_xpl(self, device, type, current):
        """ Send xPL message on network
        """
        print("device:%s, type:%s, current:%s" % (device, type, current))
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("sensor.basic")
        msg.add_data({"device" : device})
        msg.add_data({"type" : type})
        msg.add_data({"current" : current})
        self.myxpl.send(msg)
Esempio n. 8
0
class TtsManager(XplPlugin):
    """ Manage Tts
    """

    def __init__(self):
        """ Init manager
        """
        XplPlugin.__init__(self, name = 'tts')

        # Configuration

        self._config = Query(self.myxpl, self.log)
        software = self._config.query('tts', 'software')

        self.log.debug("Init info for tts created")
        ### Create tts objects
        self.my_tts = Tts(self.log, software)
	self.log.debug("Create object for tts created")
        # Create listener
        Listener(self.tts_cb, self.myxpl, {'schema': 'tts.basic','xpltype': 'xpl-cmnd'})
        self.log.debug("Listener for tts created")

        self.enable_hbeat()


    def tts_cb(self, message):
        """ Call tts lib
            @param message : xPL message detected by listener
        """
        # body contains the message
	self.log.debug("Function call back : entry")
        if 'speech' in message.data:
            speech = message.data['speech']
        else:
            self._log.warning("Xpl message : missing 'speech' attribute")
            return

        try:
	    self.log.debug("function call back : before send")
            self.my_tts.send(speech)
	    self.log.debug("function call back : after send")
        except:
	       self.log.error("Error while sending tts : %s" % traceback.format_exc())
              
               return
Esempio n. 9
0
class MirrorManager(XplPlugin):
    """ Manage the Mir:ror device and connect it to xPL
    """
    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='mirror')
        # Get config
        #   - device
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('mirror', 'device')

        # Init Mir:ror
        mirror = Mirror(self.log, self.send_xpl)

        # Open Mir:ror
        try:
            mirror.open(device)
        except MirrorException as e:
            self.log.error(e.value)
            print(e.value)
            self.force_leave()
            return

        # Start reading Mir:ror
        mirror_process = threading.Thread(None, mirror.listen,
                                          "mirror-process-reader",
                                          (self.get_stop(), ), {})
        self.register_thread(mirror_process)
        mirror_process.start()
        self.enable_hbeat()

    def send_xpl(self, device, type, current):
        """ Send xPL message on network
        """
        print("device:%s, type:%s, current:%s" % (device, type, current))
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("sensor.basic")
        msg.add_data({"device": device})
        msg.add_data({"type": type})
        msg.add_data({"current": current})
        self.myxpl.send(msg)
Esempio n. 10
0
class RfxcomUsbManager(XplPlugin):
    """ Manage the Rfxcom Usb device and connect it to xPL
    """
    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='rfxcom')
        # Get config
        #   - device
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('rfxcom', 'device')
        if device == None:
            self.log.error('Device is not configured, exiting')
            print('Device is not configured, exiting')
            self.force_leave()
            return

        # Init RFXCOM
        self.rfxcom = RfxcomUsb(self.log, self.send_xpl, self.send_trig,
                                self.get_stop())

        # Create a listener for all messages used by RFXCOM
        # TODO !!!!!
        # Create listeners
        Listener(self.process_x10_basic, self.myxpl, {
            'schema': 'x10.basic',
            'xpltype': 'xpl-cmnd'
        })
        Listener(self.process_x10_security, self.myxpl, {
            'schema': 'x10.securiy',
            'xpltype': 'xpl-cmnd'
        })
        Listener(self.process_ac_basic, self.myxpl, {
            'schema': 'ac.basic',
            'xpltype': 'xpl-cmnd'
        })
        Listener(self.process_remote_basic, self.myxpl, {
            'schema': 'remote.basic',
            'xpltype': 'xpl-cmnd'
        })
        Listener(self.process_control_basic, self.myxpl, {
            'schema': 'control.basic',
            'xpltype': 'xpl-cmnd'
        })

        # Open RFXCOM
        try:
            self.rfxcom.open(device)
        except RfxcomException as e:
            self.log.error(e.value)
            print(e.value)
            self.force_leave()
            return

        # Start reading RFXCOM
        rfxcom_process = threading.Thread(None, self.rfxcom.listen,
                                          "rfxcom-process-reader",
                                          (self.get_stop(), ), {})
        self.register_thread(rfxcom_process)
        rfxcom_process.start()
        self.enable_hbeat()

    # lighting1
    def process_x10_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        address = message.data["device"].lower()
        command = message.data["command"].lower()
        if message.data.has_key("level"):
            level = message.data["level"].lower()
        else:
            level = 0
        if message.data.has_key("protocol"):
            protocol = message.data["protocol"].lower()
        else:
            protocol = "x10"

        # Prepare xpl-trig to send if success
        trig_msg = message
        trig_msg.set_type("xpl-trig")

        # call appropriate function
        if protocol in ("x10", "arc", "elro", "waveman", "chacon", "impuls"):
            self.rfxcom.command_10(address, command, protocol, trig_msg)
        elif protocol in ("koppla"):
            self.rfxcom.command_12(address, command, level, protocol, trig_msg)
        elif protocol in ("harrison"):
            self.rfxcom.command_18(address, command, protocol, trig_msg)

    def process_x10_security(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        address = message.data["device"].lower()
        command = message.data["command"].lower()
        if message.data.has_key("delay"):
            delay = message.data["delay"].lower()
        else:
            delay = None

        # Prepare xpl-trig to send if success
        trig_msg = message
        trig_msg.set_type("xpl-trig")

        self.rfxcom.command_20(address, command, delay, trig_msg)

    def process_ac_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        # TODO : finish
        address = message.data["address"].lower()
        unit = message.data["unit"]
        if unit.lower() == "group":
            unit = 0
            group = True
        else:
            unit = int(unit)
            group = False
        command = message.data["command"].lower()
        if command == "preset":
            level = int(message.data["level"])
        else:
            level = 0
        if message.data.has_key("eu"):
            eu = message.data["eu"]
        else:
            eu = False
        # Prepare xpl-trig to send if success
        trig_msg = message
        trig_msg.set_type("xpl-trig")
        self.rfxcom.command_11(address, unit, command, level, eu, group,
                               trig_msg)

    def process_remote_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        # TODO
        pass

    def process_control_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        msg_type = message.data["type"]
        msg_current = message.data["current"]
        msg_device = message.data["current"]
        self.log.debug(
            "CONTROL.BASIC received : device = %s, type = %s, current = %s" %
            (msg_device, msg_type, msg_current))
        self.rfxcom.xplcmd_control_basic(device=msg_device,
                                         type=msg_type,
                                         current=msg_current)

    def send_xpl(self, schema, data={}):
        """ Send xPL message on network
        """
        print("schema:%s, data:%s" % (schema, data))
        self.log.debug("schema:%s, data:%s" % (schema, data))
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema(schema)
        for key in data:
            msg.add_data({key: data[key]})
        self.myxpl.send(msg)

    def send_trig(self, message):
        """ Send xpl-trig given message
            @param message : xpl-trig message
        """
        self.myxpl.send(message)
Esempio n. 11
0
class X10Main(XplPlugin):
    '''Manage x10 technology using heyu
    '''
    def __init__(self):
        """
        Create the X10Main class
        This class is used to connect x10 (through heyu) to the xPL Network
        """
        XplPlugin.__init__(self, name='x10_heyu')
        self._heyu_cfg_path_res = ""
        self._config = Query(self.myxpl, self.log)
        self._heyu_cfg_path_res = self._config.query('x10_heyu',
                                                     'heyu-cfg-path')
        try:
            self.__myx10 = X10API(self._heyu_cfg_path_res, self.log)
        except Exception:
            self.log.error("Something went wrong during heyu init, check logs")
            self.log.error("Exception : %s" % traceback.format_exc())
            exit(1)
        #Create listeners
        Listener(self.x10_cmnd_cb, self.myxpl, {
            'schema': 'x10.basic',
            'xpltype': 'xpl-cmnd'
        })
        #One listener for system schema, allowing to reload config
        #Listener(self.heyu_reload_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd',
        #                                                'command': 'reload', 'plugin': 'x10'})
        #One listener for system schema, allowing to dump config
        #Listener(self.heyu_dump_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd',
        #                                              'command': 'push_config', 'plugin': 'x10'})
        self.log.debug("before start X10monitor")
        self._monitor = X10Monitor(self._heyu_cfg_path_res)
        self._monitor.get_monitor().add_cb(self.x10_monitor_cb)
        self._monitor.get_monitor().start()
        self.enable_hbeat()
        self.log.debug("Heyu correctly started")

    #def heyu_reload_config(self, message):
    #    """
    #    Regenerate the heyu config file
    #    First, it needs to get all config items, then rewrite the config file
    #    and finally restart heyu
    #    @param message : an XplMessage object
    #    """
    #    #Heyu config items
    #    result = self._config.query('x10', '')
    #    if result is not None:
    #        heyu_config_items = filter(lambda k : k.startswith("heyu-file-"), result.keys())
    #        heyu_config_values = []
    #        for key in heyu_config_items:
    #            heyu_config_values.append(result[key])
    #        #Heyu path
    #        myheyu = HeyuManager(self._heyu_cfg_path_res)
    #        try:
    #            myheyu.write(heyu_config_values)
    #        except IOError:
    #            self.log.warning("Heyu config file can't be opened")
    #        res = myheyu.restart()
    #        if res:
    #            self.log.warning("Error during heyu restart : %s" % res)
    #    else:
    #        print("empty res")


#
#def heyu_dump_config(self, message):
#    """
#    Send the heyu config file on the network
#    @param message : an XplMessage object
#    """
#    #Heyu path
#    myheyu = HeyuManager(self._heyu_cfg_path_res)
#    lines = myheyu.load()
#    mess = XplMessage()
#    mess.set_type('xpl-trig')
#    mess.set_schema('domogik.config')
#    count = 0
#    for line in lines:
#        key = "heyu_file_%s" % count
#        count = count + 1
#        mess.add_data({key :  line})
#    self.myxpl.send(mess)

    def x10_cmnd_cb(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        commands = {
            'on': lambda d, h, l: self.__myx10.on(d),
            'off': lambda d, h, l: self.__myx10.off(d),
            'all_units_on': lambda d, h, l: self.__myx10.house_on(h),
            'all_units_off': lambda d, h, l: self.__myx10.house_off(h),
            'all_lights_on': lambda d, h, l: self.__myx10.lights_on(h),
            'all_lights_off': lambda d, h, l: self.__myx10.lights_off(h),
            'bright': lambda d, h, l: self.__myx10.bright(d, l),
            'dim': lambda d, h, l: self.__myx10.dim(d, l),
            'brightb': lambda d, h, l: self.__myx10.brightb(d, l),
            'dimb': lambda d, h, l: self.__myx10.dimb(d, l),
        }
        cmd = None
        dev = None
        house = None
        level = None
        if 'command' in message.data:
            cmd = message.data['command']
        if 'device' in message.data:
            dev = message.data['device']
        if 'house' in message.data:
            house = message.data['house']
        if 'level' in message.data:
            level = message.data['level']
        self.log.debug("%s received : device = %s, house = %s, level = %s" %
                       (cmd, dev, house, level))
        commands[cmd](dev, house, level)
        self.x10_monitor_cb(dev, cmd)

    def x10_monitor_cb(self, unit, order, args=None):
        """
        Callback for x10 monitoring
        @param unit : the unit of the element controled
        @param order : the order sent to the unit
        """
        self.log.debug("X10 Callback for %s" % unit)
        mess = XplMessage()
        mess.set_type("xpl-trig")
        mess.set_schema("x10.basic")
        mess.add_data({"device": unit})
        mess.add_data({"command": order})
        if args:
            mess.add_data({"level": args})
        self.myxpl.send(mess)
Esempio n. 12
0
class KNXManager(XplPlugin):
    """ Implements a listener for KNX command messages 
        and launch background listening for KNX events
    """

    def __init__(self):
        """ Create listener and launch bg listening
        """
        XplPlugin.__init__(self, name = 'knx')

        # Configuration : KNX device
        self._config = Query(self.myxpl, self.log)
        try{
            device = self._config.query('knx', 'device')
        }except{
            self.log.error("Can get device parameter use ipt:192.168.0.148")
            device = "ipt:192.168.0.148"
        }
        ### Create KNX object
        try:
            self.knx = KNX(self.log, self.send_xpl)
            self.log.info("Open KNX")
            self.knx.open(device)

        except KNXException as err:
            self.log.error(err.value)
            print(err.value)
            self.force_leave()
            return

        ### Start listening 
        try:
            self.log.info("Start listening to KNX")
            knx_listen = threading.Thread(None,
                                          self.knx.listen,
                                          "listen_knx",
                                          (),
                                          {})
            knx_listen.start()
        except KNXException as err:
            self.log.error(err.value)
            print(err.value)
            self.force_leave()
            return


        ### Create listeners for commands
        self.log.info("Creating listener for KNX")
        Listener(self.knx_cmd, self.myxpl,{'schema':'knx.basic'})
        self.add_stop_cb(self.knx.close)
        self.enable_hbeat()

        ### test if config file exist
        path = self.get_data_files_directory()
        if os.path.exists(path)== False:
           try:
               os.mkdir(path)
               self.log.info("create KNX data folder")
           except:
               self.log.error("can't create KNX data folder as %s" %path)
        path = path+"/knx.txt"
        if os.path.exists(path)== False:
           try:
               fichier= open(path,'w')
               fichier.write('')
               fichier.close()
               print "Création du fichier de stockage %s"  %path
               self.log.info("Create KNX data file")
           except:
               self.log.error("Can't create KNX data file")

        ### Load the configuration file in the plugin
        self.log.info("Start read knx data file")
        filetoopen= self.get_data_files_directory()
        filetoopen= filetoopen+"/knx.txt"
        fichier=open(filetoopen,"r")
        for ligne in fichier:
           if ligne[:1]!="#":
              listknx.append(ligne)
              print ligne
        fichier.close
        self.log.info("Finish to read KNX data file")
        for i in range(len(listknx)):
           stat=listknx[i]
           if stat.find("check:true")>=0:
              stat=stat[stat.find("adr_stat:")+9:]
              stat=stat[:stat.find(" ")]
              print stat  
              command="groupread ip:127.0.0.1 %s" %stat
              subp2=subprocess.Popen(command, shell=True)

        self.log.info("Plugin ready :)")

    def send_xpl(self, data):
        """ Send xpl-trig to give status change
        """
        self.log.info("receive an xpl message")
        ### Identify the sender of the message
        lignetest=""
        command = ""
        dmgadr =""
        msg_type=""
        test = ""
        val=""
        sender = 'None'
        sender = data[data.find('from')+4:data.find('to')-1]
        sender = sender.strip()
        groups = 'None'
        val = 'None'
        msg_type = 'None'
        command = 'None'
        if sender!="pageinatio":
           print "emetteur |%s|" %sender
           command = data[0:4]  
           lignetest=""
           groups = data[data.find('to')+2:data.find(':')]
           groups =":"+groups.strip()+" "
           print "groups |%s|" %groups

        ### Search the sender in the config list
           i=0
           lignetest=""
           for i in range(len(listknx)):
              if listknx[i].find(groups)>=0:
                 lignetest = listknx[i]
                 typeadr=lignetest[lignetest.find(groups)-4:lignetest.find(groups)]
                 typeadr=typeadr.replace("_","")
                 test=lignetest[lignetest.find('datatype:')+9:]
                 datatype=test[:test.find(' ')]
                 if typeadr=="stat":
                    if lignetest.find('dpt_stat')!=-1:
                       test=lignetest[lignetest.find('dpt_stat:')+9:]
                       datatype=test[:test.find(' ')]
                 test=lignetest[lignetest.find('adr_dmg:')+8:]
                 dmgadr=test[:test.find(' ')]
                 datatype=lignetest[lignetest.find('datatype:')+9:lignetest.find(' adr_dmg')]
                 msg=XplMessage()
                 msg.set_schema('knx.basic')

                 if command != 'Read':
                    val=data[data.find(':')+1:-1]
                    val = val.strip()
                    print "valeur=|%s|" %val
                    print "datapoint type=|%s|" %datatype
                    msg_type = datatype

                    val=decodeKNX(datatype,val)

                    print "Valeur decode=|%s|" %val

                    if command == 'Writ':
                       print("knx Write xpl-trig")
                       command = 'Write'
                       msg.set_type("xpl-trig")
                    if command == 'Resp':
                       print("knx Response xpl-stat")
                       command = 'Response'
                       if sender!="0.0.0":
                          msg.set_type("xpl-stat")
                       else:
                          msg.set_type("xpl-trig")

                 if command == 'Read':
                    print("knx Read xpl-cmnd")
                    if sender!="0.0.0":
                       msg.set_type("xpl-cmnd")
                    else:
                       msg.set_type("xpl-trig")

                 if sender!="0.0.0":
                    msg.add_data({'command' : command+' bus'})
                 else:
                    msg.add_data({'command': command+' ack'})

                 msg.add_data({'group' :  dmgadr})
                 msg.add_data({'type' :  msg_type})
                 msg.add_data({'data': val})
                 print "sender: %s typeadr:%s" %(sender, typeadr)

                 self.myxpl.send(msg)

    def knx_cmd(self, message):
        type_cmd = message.data['command']
        groups = message.data['group']
        groups = "adr_dmg:"+groups+" "
        lignetest=""
        valeur=message.data['data']
        print "Message XPL %s" %message
        for i in range(len(listknx)):
           if listknx[i].find(groups)>=0:
              lignetest=listknx[i]
              break
        print "ligne test=|%s|" %lignetest

           #si wirte groups_cmd/si read, groups stat
        if lignetest!="":
           datatype=lignetest[lignetest.find('datatype:')+9:lignetest.find(' adr_dmg')]
           cmdadr=lignetest[lignetest.find('adr_cmd:')+8:lignetest.find(' adr_stat')]
           command=""
           print "Command: |%s|" %type_cmd
           print "Groups: |%s|" %cmdadr
           print "datatype: |%s|" %datatype
           print "valeur avant codage: |%s|" %valeur

           if type_cmd=="Write":
              print("dmg Write %s") %type_cmd
              valeur = message.data['data']
              data_type = message.data['type']
              print "valeur avant modif:%s" %valeur
              val=valeur

              value=encodeKNX(datatype, val)
              data_type=value[0]
              valeur=value[1]   
              print "Valeur modifier |%s|" %valeur
              
              if data_type=="s":
                 command="groupswrite ip:127.0.0.1 %s %s" %(cmdadr, valeur)
              if data_type=="l":
                 command="groupwrite ip:127.0.0.1 %s %s" %(cmdadr, valeur)

           if type_cmd == "Read":
              print("dmg Read")
              command="groupread ip:127.0.0.1 %s" %cmdadr
           if type_cmd == "Response":
              print("dmg Response")
              data_type=message.data['type']
              valeur = message.data['data']
              if data_type=="s":
                 command="groupsresponse ip:127.0.0.1 %s %s" %(cmdadr,valeur)
              if data_type=="l":
                 command="groupresponse ip:127.0.0.1 %s %s" %(cmdadr,valeur)
           if command!="":
              print "envoie de la command %s" %command
              subp=subprocess.Popen(command, shell=True)
           if command=="":
              print("erreur command non définir, type cmd= %s" %type_cmd)

        ### ajout d'un device dans le fichier de configuration du KNX

        if type_cmd=="Add":
           groups = message.data['group']
           test=""
           print "Commande Add Valeur=|%s|" %valeur
           print groups
           if groups=="UI":
              print "Add device"
              Adr_dmg=valeur[:valeur.find(":")]
              valeur=valeur[valeur.find(":")+1:]
              Adr_cmd=valeur[:valeur.find(":")]
              valeur=valeur[valeur.find(":")+1:]
              dptype=valeur[:valeur.find(":")]
              valeur=valeur[valeur.find(":")+1:]
              Adr_stat=valeur[:valeur.find(":")]
              valeur=valeur[valeur.find(":")+1:]
              dpt_stat=valeur[:valeur.find(":")]
              valeur=valeur[valeur.find(":")+1:]
              check=valeur[:valeur.find(":")]
              valeur=valeur[valeur.find(":")+1:]
              comentaire=valeur
              test=""
              
              for i in range(len(listknx)):
                 print listknx[i]
                 if listknx[i].find(Adr_dmg)>=0:
                    test=listknx[i]
                    print test
                    break

           if groups=="Delete":
              test=""
              filetoopen= self.get_data_files_directory()
              filetoopen= filetoopen+"/knx.txt"
              e=open(filetoopen,"r")
              o=e.read().split("\n")
              e.close()
              f=open(filetoopen,"w")
              ligne=int(valeur,10)-1
              print ligne
              for i in range(len(o)):
                 if i!=ligne:
                    if o[i]!="":
                       f.write(o[i]+"\n")
                    else:
                       print "ligne a supprimer:|%s|" %o[ligne]
                       testy=str(o[ligne])+"\n"
                       if listknx.count(testy)>=1:
                          listknx.remove(testy)
                       else:
                          print listknx
                    print o[i]
              f.close()

              msg=XplMessage()
              msg.set_schema('knx.basic')
              msg.set_type("xpl-trig")
              msg.add_data({'command': 'Add-ack'})
              msg.add_data({'group' : 'Delete'})
              msg.add_data({'type' : 's'})
              msg.add_data({'data': 'OK'})
              self.myxpl.send(msg)
           
           if groups=="UI":

              msg=XplMessage()
              msg.set_schema('knx.basic')
              msg.set_type("xpl-trig")
              msg.add_data({'command': 'Add-ack'})
              msg.add_data({'group' : 'UI'})
              msg.add_data({'type' : 's'})

              if test == "":
                 filetoopen= self.get_data_files_directory()
                 filetoopen= filetoopen+"/knx.txt"
                 fichier=open(filetoopen,"a")
                 ligne1="# %s \n" %comentaire
                 ligne2="datatype:%s adr_dmg:%s adr_cmd:%s adr_stat:%s dpt_stat:%s check:%s end \n" %(dptype,Adr_dmg,Adr_cmd,Adr_stat,dpt_stat,check)
                 fichier.write(ligne1)
                 fichier.write(ligne2)
                 fichier.close
                 listknx.append(ligne2)
                 print "Retour du xPL"
                 msg.add_data({'data': 'OK'})
              else:
                 print "Error"
                 msg.add_data({'data': 'Error domogik address:'+Adr_dmg+' already existe'})

              self.myxpl.send(msg)

           if groups=="Request":
              print "Requette de fichier"
              msg=XplMessage()
              msg.set_schema('knx.basic')
              msg.set_type("xpl-trig")
              msg.add_data({'command': 'Add-ack'})
              msg.add_data({'group' : 'Request'})
              msg.add_data({'type' : 's'})

              print "Resquest files"
              filetoopen= self.get_data_files_directory()
              filetoopen= filetoopen+"/knx.txt"
              fichier=open(filetoopen,"r")
              data=[]
              for ligne in fichier:
                 data.append(ligne[:ligne.find("end")])
              message=""
              msg.add_data({'dim': len(data)})
              for i in range(len(data)):
                 message=message+data[i]+","
                 msg.add_data({'data[%s]' %i : data[i]})
              if message=="":
                 message="None"
              msg.add_data({'data': message})
              fichier.close
              self.myxpl.send(msg)
Esempio n. 13
0
class Earth(XplPlugin):
    '''
    The plugin itself.

    '''
    def __init__(self):
        """
        Create the cron class
        """
        XplPlugin.__init__(self, name = 'earth')
        self.log.debug("__init__ : Start ...")

        self.config = Query(self.myxpl, self.log)
        try:
            delay_cron = int(self.config.query('earth', 'delay-cron'))
        except:
            delay_cron = 30
            error = "Can't get configuration from XPL : %s" %  (traceback.format_exc())
            self.log.warning("__init__ : " + error)
            self.log.warning("Continue with default values.")

        cron = CronQuery(self.myxpl, self.log)
        cont = 3
        cron_started = False
        while not self.get_stop().isSet() and cont>=0:
            try :
                res = cron.is_running_server()
            except :
                pass
            if res :
                cron_started = True
                cont = -1
            else:
                self.log.debug("Can't talk to cron plugin. Retries=%s" % cont)
                self.get_stop().wait(delay_cron)
                cont -= 1
        if not cron_started :
            self.force_leave()
            error = "Can't talk to cron plugin. Exiting ..."
            self.log.error("__init__ : "+error)
            return
        else :
            self.log.info("Communication with the cron plugin established.")
        self.log.debug("__init__ : Try to start the earth API")
        try:
            self._earth = EarthAPI(self.log, self.config, self.myxpl, \
                            self.get_data_files_directory(), \
                            self.get_stop(), self.get_sanitized_hostname())
        except:
            self.force_leave()
            error = "Something went wrong during EarthAPI init : %s" %  \
                     (traceback.format_exc())
            self.log.error("__init__ : "+error)
            return

        self.log.debug("__init__ : Try to create listeners")
        Listener(self.request_cb, self.myxpl,
             {'schema': 'earth.request', 'xpltype': 'xpl-cmnd'})
        Listener(self.fired_cb, self.myxpl,
              {'schema': 'earth.basic', 'xpltype': 'xpl-trig', 'current': 'fired'})
        Listener(self.basic_cb, self.myxpl,
             {'schema': 'earth.basic', 'xpltype': 'xpl-cmnd'})

        self.add_stop_cb(self._earth.stop_all)

        self.log.debug("__init__ : Enable the heartbeat")
        self.enable_hbeat()

        self._earth.plugin_enabled(True)

        self.log.info("Plugin earth correctly started.")

    def request_cb(self, message):
        """
        General callback for timer.request messages

        @param message : an XplMessage object

        """
        self.log.debug("request_cb() : Start ...")
        self._earth.command_listener(self.myxpl, message)
        self.log.debug("request_cb() : Done :)")

    def basic_cb(self, message):
        """
        General callback for timer.basic messages

        @param message : an XplMessage object

        """
        self.log.debug("basic_cb() : Start ...")
        self._earth.action_listener(self.myxpl, message)
        self.log.debug("basic_cb() : Done :)")

    def fired_cb(self, message):
        """
        General callback for timer.basic messages

        @param message : an XplMessage object

        """
        self.log.debug("fired_cb() : Start ...")
        self._earth.fired_listener(self.myxpl, message)
        self.log.debug("fired_cb() : Done :)")
Esempio n. 14
0
class IPXManager(XplPlugin):
    """ Implements a listener for IPX command messages 
        and launch background listening for relay board status
    """

    def __init__(self):
        """ Create lister and launch bg listening
        """
        XplPlugin.__init__(self, name="ipx800")

        # Configuration : list of IPX800
        self.ipx_list = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            model = self._config.query("ipx800", "model-%s" % str(num))
            login = self._config.query("ipx800", "login-%s" % str(num))
            password = self._config.query("ipx800", "password-%s" % str(num))
            name = self._config.query("ipx800", "name-%s" % str(num))
            address = self._config.query("ipx800", "ip-%s" % str(num))
            inter = self._config.query("ipx800", "int-%s" % str(num))
            if name != None:
                self.log.info(
                    "Configuration : login=%s, password=***, name=%s, ip=%s, interval=%s"
                    % (login, name, address, inter)
                )
                self.ipx_list[name] = {
                    "login": login,
                    "password": password,
                    "model": model,
                    "ip": address,
                    "interval": float(inter),
                }
                num += 1
            else:
                loop = False

        # no ipx configured
        if num == 1:
            msg = "No ipx800 board configured. Exiting plugin"
            self.log.info(msg)
            print (msg)
            self.force_leave()
            return

        ### Create IPX objects
        num_ok = 0
        for ipx in self.ipx_list:
            self.ipx_list[ipx]["obj"] = IPX(self.log, self.send_xpl, self.get_stop())
            try:
                self.log.info("Opening IPX800 named '%s' (ip : %s)" % (ipx, self.ipx_list[ipx]["ip"]))
                self.ipx_list[ipx]["obj"].open(
                    ipx,
                    self.ipx_list[ipx]["ip"],
                    self.ipx_list[ipx]["model"],
                    self.ipx_list[ipx]["login"],
                    self.ipx_list[ipx]["password"],
                )
            except:
                self.log.error("Error opening board '%s' : %s " % (ipx, traceback.format_exc()))
                print ("Error opening board '%s' : check logs" % ipx)
            else:
                num_ok += 1

        # no valid ipx800 board detected
        if num_ok == 0:
            msg = "No valid IPX800 board configured. Exiting plugin..."
            self.log.info(msg)
            print (msg)
            self.force_leave()
            return

        ### Start listening each IPX800
        for ipx in self.ipx_list:
            try:
                self.log.info("Start listening to IPX800 named '%s'" % ipx)
                ipx_listen = threading.Thread(
                    None, self.ipx_list[ipx]["obj"].listen, "listen_ipx", (self.ipx_list[ipx]["interval"],), {}
                )
                ipx_listen.start()
            except IPXException as err:
                self.log.error(err.value)
                print (err.value)
                # we don't quit plugin if an error occured
                # we can loose a board for a little time
                # self.force_leave()
                # return

        ### Create listeners for commands
        self.log.info("Creating listener for IPX 800")
        # Listener(self.ipx_command, self.myxpl, {'schema': 'control.basic',
        #        'xpltype': 'xpl-cmnd', 'type': ['output', 'count']})
        Listener(self.ipx_command, self.myxpl, {"schema": "control.basic", "xpltype": "xpl-cmnd", "type": "output"})

        self.enable_hbeat()
        self.log.info("Plugin ready :)")

    def send_xpl(self, msg_device, msg_current, msg_type):
        """ Send xpl-trig to give status change
            @param msg_device : device
            @param msg_current : device's value
            @param msg_type : device's type
        """
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("sensor.basic")
        msg.add_data({"device": msg_device})
        if msg_type != None:
            msg.add_data({"type": msg_type})
        msg.add_data({"current": msg_current})
        self.myxpl.send(msg)

    def ipx_command(self, message):
        """ Call ipx800 lib function in function of given xpl message
            @param message : xpl message
        """
        if "device" in message.data:
            msg_device = message.data["device"]
        if "type" in message.data:
            msg_type = message.data["type"].lower()
        if "current" in message.data:
            msg_current = message.data["current"].lower()

        data = "device=%s, type=%s, current=%s" % (msg_device, msg_type, msg_current)
        print data
        data_name = msg_device.split("-")
        ipx_name = data_name[0]
        elt = data_name[1][0:-1]
        num = int(data_name[1][-1])

        if not ipx_name in self.ipx_list:
            self.log.warning("No IPX800 board called '%s' defined" % ipx_name)
            return

        # check data
        if elt == "led" and msg_current not in ["high", "low", "pulse"] and msg_type != "output":
            self.log.warning("Bad data : %s" % data)
            return

        # TODO in a next release : other checks : counter

        # action in function of type
        if elt == "led" and msg_type == "output" and msg_current in ["high", "low"]:
            self.ipx_list[ipx_name]["obj"].set_relay(num, msg_current)
        elif elt == "led" and msg_type == "output" and msg_current == "pulse":
            self.ipx_list[ipx_name]["obj"].pulse_relay(num)
Esempio n. 15
0
class KarotzMain(XplPlugin):
    '''Manage ZiBase
    '''    
    def __init__(self):
        """ Create lister and launch bg listening
        """
        try:
            XplPlugin.__init__(self, name = 'karotz')
        except:
            self.log.error("Error to create Karotz Xplplugin=%s" % (traceback.format_exc()))
            return
            
        self._config = Query(self.myxpl, self.log)

        self.instid = self._config.query('karotz', 'installid')
        self.lang = self._config.query('karotz', 'language')
        
        try:
            self.log.info("Starting library")
            self.karotz=Karotz(self.log,self.instid)
            self.log.info("Started")
        except:
            self.log.error("Error to create Karotz object=%s" % (traceback.format_exc()))
            return

                
        self.log.info("Creating listener for Karotz")
        Listener(self.xpl_command, self.myxpl, {'schema': 'karotz.basic', 'xpltype': 'xpl-cmnd'})
        

        #self.add_stop_cb(self.stop)
        self.enable_hbeat()

        self.log.info("Plugin ready :)")
        
    def xpl_command(self, message):
        """ Call karotz lib function in function of given xpl message
            @param message : xpl message
        """
        cmd = None
        dev = None
        value = None
        
        if 'command' in message.data:
            cmd = message.data['command']
        if 'device' in message.data:
            device = message.data['device']
        if 'value' in message.data:
            value=message.data['value']
        if 'time' in message.data:
            tps=message.data['time']
        if 'right' in message.data:
            right=message.data['right']
            value=right
        if 'left' in message.data:
            left=message.data['left']

        self.log.debug(message.data)
        if value == None :
            self.log.warning("value not specified")
            return
        else:
            #self.log.debug("xpl %s received : device = %s value=%s " % (cmd, device, value))
            self.log.debug("xpl %s received " % (cmd) )    

            try:
                if cmd=='tts':
                    self.log.debug("xpl command=%s language=%s" % (cmd, self.lang))
                    self.karotz.tts(value,self.lang.upper())
                if cmd=='led':
                    self.log.debug("xpl command=%s color=%s time=%s" % (cmd, value,tps))
                    self.karotz.led(value,tps)
                if cmd=='ears':
                    self.log.debug("xpl command=%s right=%s left=%s" % (cmd, right, left))
                    self.karotz.ears(right,left)
            except:
                self.log.error("Error to send command=%s" % (traceback.format_exc()))
Esempio n. 16
0
class GAgendaListener(XplPlugin):
    """ Listen for xPL messages to get infos from agenda
    """

    def __init__(self):
        """ Create lister for google agenda requets
        """
        XplPlugin.__init__(self, name = 'gagenda')

        # Create logger
        self.log.debug("Listener for Google agenda created")

        # Get config
        self._config = Query(self.myxpl, self.log)
        self._email = self._config.query('gagenda', 'email')
        self._password = self._config.query('gagenda', 'password')
        self._calendar_name = self._config.query('gagenda', 'calendarname')

        # Create object
        self._gagenda_manager = GAgenda(self.log, \
                                       self._email, \
                                       self._password, \
                                       self._calendar_name, \
                                       self._broadcast_events)

        # Create listener for today
        Listener(self.gagenda_cb, self.myxpl, {'schema': 'calendar.request',
                'xpltype': 'xpl-cmnd', 'command': 'REQUEST'})
        self.enable_hbeat()

    def gagenda_cb(self, message):
        """ Call google agenda lib
            @param message : xlp message received
        """
        self.log.debug("Call gagenda_cb")
        if 'command' in message.data:
            command = message.data['command']
        if 'date' in message.data:
            date = message.data['date']

        # if it is a request command
        if command == "REQUEST":
            self.log.debug("Google agende request command received for " + \
                            str(date))
            if date == "TODAY":
                self._gagenda_manager.get_today_events()
            elif date == "TOMORROW":
                self._gagenda_manager.get_tomorrow_events()
            else:
                self._gagenda_manager.get_events_at_date(date)


    def _broadcast_events(self, events):
        """ Send xPL message on network
            @param events : list of events
        """
        for entry in events:
            my_temp_message = XplMessage()
            my_temp_message.set_type("xpl-trig")
            my_temp_message.set_schema("calendar.basic")
            print("entry = ")
            print(entry)
            my_temp_message.add_data({"object" : entry["object"]})
            my_temp_message.add_data({"startdate" : entry["startdate"]})
            self.myxpl.send(my_temp_message)
Esempio n. 17
0
File: sms.py Progetto: capof/domogik
class SmsManager(XplPlugin):
    """ Manage Sms
    """

    def __init__(self):
        """ Init manager
        """
        XplPlugin.__init__(self, name = 'sms')

        # Configuration

        self._config = Query(self.myxpl, self.log)
        login = self._config.query('sms', 'login')
        password = self._config.query('sms', 'password')
        phone = self._config.query('sms', 'phone')
	operator = self._config.query('sms', 'operator')
	operator = operator.lower()

        if (operator == "orange"):
		from domogik_packages.xpl.lib.sms_orange import Sms
	if (operator == "sfr"):
		from domogik_packages.xpl.lib.sms_sfr import Sms
	if (operator == "bouygues"):
		from domogik_packages.xpl.lib.sms_bouygues import Sms		
        self.log.debug("Init info for sms created")
        ### Create Sms objects
        self.my_sms = Sms(self.log,login,password,phone)
	self.log.debug("Create object for sms created")
        # Create listener
        Listener(self.sms_cb, self.myxpl, {'schema': 'sendmsg.basic','xpltype': 'xpl-cmnd'})
        self.log.debug("Listener for sms created")

        self.enable_hbeat()


    def sms_cb(self, message):
        """ Call sms lib
            @param message : xPL message detected by listener
        """
        # body contains the message
	self.log.debug("Function call back : entry")
        if 'body' in message.data:
            body = message.data['body']
        else:
            self._log.warning("Xpl message : missing 'body' attribute")
            return
        if 'to' in message.data:
            to = message.data['to']
        else:
            self._log.warning("Xpl message : missing 'to' attribute")
            return

        try:
	    self.log.debug("function call back : before send")
            self.my_sms.send(to,body)
	    self.log.debug("function call back : after send")
        except:
	       self.log.error("Error while sending sms : %s" % traceback.format_exc())
               mess = XplMessage()
               mess.set_type('xpl-trig')
               mess.set_schema('sendmsg.confirm')
               mess.add_data({'status' :  'Sms not send'})
               mess.add_data({'error' :  'function send'})
               self.myxpl.send(mess)
               return



        # Send xpl-trig to say plugin receive command
        mess = XplMessage()
        mess.set_type('xpl-trig')
        mess.set_schema('sendmsg.confirm')
	if self.my_sms.status_send == 0:
        	mess.add_data({'status' :  'Sms not send'})
		mess.add_data({'error' :  self.my_sms.status_error})
	else:
        	mess.add_data({'status' :  'Sms send'})
	
        self.myxpl.send(mess)
Esempio n. 18
0
class RelayBoardUSBmanager(XplPlugin):
    """ Manage USB Relay Board
    """

    def __init__(self):
        """ Init manager
        """
        XplPlugin.__init__(self, name = 'gceusbrb')

        # Configuration : list of relayboard
        self.relayboards = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            name = self._config.query('gceusbrb', 'rb-%s-name' % str(num))
            device = self._config.query('gceusbrb', 'rb-%s-device' % str(num))
            if name != None:
                self.log.info("Configuration : name=%s, device=%s" % (name, device))
                self.relayboards[name] = {"device" : device}
            else:
                loop = False
            num += 1

        ### Create Relayboardusb objects ex.SamsungTV
        for relayboard in self.relayboards:
            self.relayboards[relayboard]['obj'] = Relayboardusb(self.log,self.send_xpl)
            try:
                self.log.info("Opening RelayBoard named '%s' (device : %s)" %
                               (relayboard, self.relayboards[relayboard]['device']))
                self.relayboards[relayboard]['obj'].open(self.relayboards[relayboard]['device'],relayboard)
            except RelayboardusbException as err:
                self.log.error(err.value)
                print err.value
                self.force_leave()
                return

        # Create listener
        Listener(self.relayboard_cb, self.myxpl, {'schema': 'control.basic','xpltype': 'xpl-cmnd', 'type': 'output'})
        self.log.debug("Listener for gceusbrb created")

        self.enable_hbeat()
        self.log.info("RB Plugin ready :)")

    def send_xpl(self, msg_device, msg_current, msg_type):
        """ Send xpl-trig to give status change
            @param msg_device : device
            @param msg_current : device's value
            @param msg_type : device's type
        """
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema('sensor.basic')
        msg.add_data({'device' :  msg_device})
        msg.add_data({'type' :  msg_type})
        msg.add_data({'current' :  msg_current})
        self.myxpl.send(msg)

    def relayboard_cb(self, message):
        """ Call gceusbrb lib
            @param message : xPL message detected by listener
        """
        # device contains name of relayboard which will be used to get device
        if 'device' in message.data:
            msg_device = message.data['device']
        if 'type' in message.data:
            msg_type = message.data['type'].lower()
        if 'current' in message.data:
            msg_current = message.data['current'].upper()

        data = "device=%s, type=%s, current=%s" % (msg_device, msg_type, msg_current)
        data_name = msg_device.split("-")
        rb_name = data_name[0]
        elt = data_name[1][0:-1]
        num = int(data_name[1][-1])

        self.log.info("RelayBoard command received for '%s' on '%s'" % (rb_name, msg_device))

        if not rb_name in self.relayboards:
           self.log.warning("No Relay board called '%s' defined" % rb_name)
           return

        # check data
        if elt == 'led' and msg_current not in ['HIGH', 'LOW'] and msg_type != 'output':
            self.log.warning("Bad data : %s" % data)
            return
        
        # action in function of type
        self.relayboards[rb_name]['obj'].set_relay(num, msg_current)
Esempio n. 19
0
class Dawndusk(XplPlugin):
    '''
    Send Dawn and Dusk messages over XPL
    '''
    def __init__(self):
        """
        Create the dawndusk class
        """
        XplPlugin.__init__(self, name='dawndusk')
        self.log.info("dawndusk.__init__ : Start ...")
        self._config = Query(self.myxpl, self.log)

        self.log.debug("dawndusk.__init__ : Try to get configuration from XPL")
        try:
            longitude = str(self._config.query('dawndusk', 'longitude'))
            latitude = str(self._config.query('dawndusk', 'latitude'))
            if latitude == None:
                latitude = "47.352"
            if longitude == None:
                longitude = "5.043"
            boo = self._config.query('dawndusk', 'cron')
            if boo == None:
                boo = "False"
            use_cron = eval(boo)
            boo = self._config.query('dawndusk', 'test')
            if boo == None:
                boo = "False"
            test = eval(boo)
            self.devices = {}
            num = 1
            loop = True
            while loop == True:
                xpltype = self._config.query('dawndusk', \
                    'xpltype-%s' % str(num))
                schema = self._config.query('dawndusk', \
                    'schema-%s' % str(num))
                addname = self._config.query('dawndusk', \
                    'addname-%s' % str(num))
                add = self._config.query('dawndusk', 'add-%s' % str(num))
                command = self._config.query('dawndusk', \
                    'command-%s' % str(num))
                dawn = self._config.query('dawndusk', 'dawn-%s' % str(num))
                dusk = self._config.query('dawndusk', 'dusk-%s' % str(num))
                if schema != None:
                    self.log.debug("dawndusk.__init__ : Device from \
                        xpl : device=%s," % (add))
                    self.devices[add] = {
                        "schema": schema,
                        "command": command,
                        "dawn": dawn,
                        "dusk": dusk,
                        "addname": addname,
                        "xpltype": xpltype
                    }
                else:
                    loop = False
                num += 1

        except:
            error = "Can't get configuration from XPL : %s" %  \
                     (traceback.format_exc())
            self.log.error("dawndusk.__init__ : " + error)
            longitude = "5.043"
            latitude = "47.352"
            use_cron = False
            test = False
            raise DawnduskException(error)

        self.log.debug(
            "dawndusk.__init__ : Try to start the dawndusk librairy")
        try:
            self._mydawndusk = DawnduskAPI(longitude, latitude, use_cron, \
                self.myxpl, self.log)
        except:
            error = "Something went wrong during dawnduskAPI init : %s" %  \
                     (traceback.format_exc())
            self.log.error("dawndusk.__init__ : " + error)
            raise DawnduskException(error)

        self.log.debug("dawndusk.__init__ : Try to add the next event \
            to the scheduler")
        try:
            self.add_next_event()
            #for test only
            if test == True:
                self._mydawndusk.sched_add(datetime.datetime.today() + \
                    datetime.timedelta(minutes=1), \
                    self.send_dawndusk,"dawn-test")
                self._mydawndusk.sched_add(datetime.datetime.today() + \
                    datetime.timedelta(minutes=6), \
                        self.send_dawndusk,"dusk-test")
        except:
            error = "Something went wrong during dawnduskScheduler \
                init : %s" % (traceback.format_exc())
            self.log.error("dawndusk.__init__ : " + error)
            raise DawnduskException(error)

        self.log.debug("dawndusk.__init__ : Try to create listeners")
        Listener(self.dawndusk_cmnd_cb, self.myxpl, {
            'schema': 'dawndusk.request',
            'xpltype': 'xpl-cmnd'
        })
        if use_cron == True:
            #We need to catch the dawndusk trig message to schedule the next one
            Listener(self.dawndusk_trig_cb, self.myxpl, {
                'schema': 'dawndusk.basic',
                'xpltype': 'xpl-trig'
            })
        self.enable_hbeat()
        self.log.info("dawndusk plugin correctly started")

    def __del__(self):
        """
        Kill the dawndusk plugin
        """
        del (self._mydawndusk)

    def dawndusk_trig_cb(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("dawndusk.dawndusk_trig_cb() : Start ...")
        mtype = None
        if 'type' in message.data:
            mtype = message.data['type']
        status = None
        if 'status' in message.data:
            status = message.data['status']
        self.log.debug("dawndusk.dawndusk_trig_cb :  type %s received \
            with status %s" % (mtype, status))
        if mtype == "dawndusk" and status != None:
            #We receive a trig indicating that the dawn or dus has occured.
            #We need to schedule the next one
            self.add_next_event()
            for dev in self.devices:
                self.log.debug("sendMessages() : Send message to device %s" %
                               dev)
                mess = XplMessage()
                mess.set_type(self.devices[dev]["xpltype"])
                mess.set_schema(self.devices[dev]["schema"])
                mess.add_data({self.devices[dev]["command"] : \
                    self.devices[dev][status]})
                mess.add_data({self.devices[dev]["addname"]: dev})
                self.myxpl.send(mess)
        self.log.debug("dawndusk.dawndusk_trig_cb() : Done :)")

    def dawndusk_cmnd_cb(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("dawndusk.dawndusk_cmnd_cb() : Start ...")
        cmd = None
        if 'command' in message.data:
            cmd = message.data['command']
        query = None
        if 'query' in message.data:
            query = message.data['query']
        self.log.debug("dawndusk.dawndusk_cmnd_cb :  command %s received \
            with query %s" % (cmd, query))
        mess = XplMessage()
        mess.set_type("xpl-stat")
        sendit = False
        if cmd == 'status':
            if query == "dawn":
                mess.set_schema("datetime.basic")
                dawn = self._mydawndusk.get_next_dawn()
                mess.add_data({"status": dawn.strftime("%Y%m%d%H%M%S"), \
                    "type": "dawn" })
                sendit = True
                self.log.debug("dawndusk.dawndusk_cmnd_cb :  query= %s, \
                    status= %s" % (query, dawn))
            elif query == "dusk":
                mess.set_schema("datetime.basic")
                dusk = self._mydawndusk.get_next_dusk()
                mess.add_data({"status" :  dusk.strftime("%Y%m%d%H%M%S"), \
                    "type": "dusk" })
                sendit = True
                self.log.debug("dawndusk.dawndusk_cmnd_cb :  query= %s, \
                    satus= %s" % (query, dusk))
            elif query == "fullmoon":
                mess.set_schema("datetime.basic")
                dusk = self._mydawndusk.get_next_fullmoon()
                mess.add_data({"status" :  dusk.strftime("%Y%m%d%H%M%S"), \
                    "type": "fullmoon" })
                sendit = True
                self.log.debug("dawndusk.dawndusk_cmnd_cb :  query= %s, \
                    satus= %s" % (query, dusk))
            if query == "fullmoondawn":
                mess.set_schema("datetime.basic")
                fullmoondawn = self._mydawndusk.get_next_fullmoon_dawn()
                mess.add_data({"status": \
                    fullmoondawn.strftime("%Y%m%d%H%M%S"), \
                    "type": "fullmoondawn" })
                sendit = True
                self.log.debug("dawndusk.dawndusk_cmnd_cb :  query= %s, \
                    status= %s" % (query, fullmoondawn))
            elif query == "fullmoondusk":
                mess.set_schema("datetime.basic")
                fullmoondusk = self._mydawndusk.get_next_fullmoon_dusk()
                mess.add_data({"status" :  \
                    fullmoondusk.strftime("%Y%m%d%H%M%S"), \
                    "type": "fullmoondusk" })
                sendit = True
                self.log.debug("dawndusk.dawndusk_cmnd_cb :  query= %s, \
                    satus= %s" % (query, fullmoondusk))
            elif query == "daynight":
                dawn = self._mydawndusk.get_next_dawn()
                dusk = self._mydawndusk.get_next_dusk()
                mess.set_schema("dawndusk.basic")
                mess.add_data({"type": "daynight"})
                if dusk < dawn:
                    mess.add_data({"status": "day"})
                    self.log.debug("dawndusk.dawndusk_cmnd_cb() : \
                        status= day")
                else:
                    mess.add_data({"status": "night"})
                    self.log.debug("dawndusk.dawndusk_cmnd_cb() : \
                        status= night")
                sendit = True
        if sendit:
            self.myxpl.send(mess)
        self.log.debug("dawndusk.dawndusk_cmnd_cb() : Done :)")

    def add_next_event(self):
        """
        Get the next event date : dawn or dusk
        """
        ddate, dstate = self.get_next_event()
        self._mydawndusk.sched_add(ddate, self.send_dawndusk, dstate)

    def get_next_event(self):
        """
        Get the next event date : dawn or dusk
        @return rdate : the next event date
        @return rstate : the event type : DAWN or DUSK
        """
        dawn = self._mydawndusk.get_next_dawn()
        dusk = self._mydawndusk.get_next_dusk()
        if dusk < dawn:
            rdate = dusk
            rstate = "dusk"
        else:
            rdate = dawn
            rstate = "dawn"
        return rdate, rstate

    def send_dawndusk(self, state):
        """
        Send a xPL message of the type DAWNDUSK.BASIC when the sun goes down or up.
        This function is called by the internal cron
        @param state : DAWN or DUSK
        """
        self.log.debug("dawndusk.sendDawnDusk() : Start ...")
        mess = XplMessage()
        mess.set_type("xpl-trig")
        mess.set_schema("dawndusk.basic")
        mess.add_data({"type": "dawndusk"})
        mess.add_data({"status": state})
        self.myxpl.send(mess)
        self.add_next_event()
        for dev in self.devices:
            self.log.debug("sendMessages() : Send message to device %s" % dev)
            mess = XplMessage()
            mess.set_type(self.devices[dev]["xpltype"])
            mess.set_schema(self.devices[dev]["schema"])
            mess.add_data({self.devices[dev]["command"] : \
                self.devices[dev][state]})
            mess.add_data({self.devices[dev]["addname"]: dev})
            self.myxpl.send(mess)
        self.log.info("dawndusk : send signal for %s" % state)
        self.log.debug("dawndusk.sendDawnDusk() : Done :-)")
Esempio n. 20
0
class roowifi(XplPlugin):
    ## Implements a listener for RooWifi messages on xPL network

    def __init__(self):
        #####
        ## Create listeners
        ##  Listener(self._plcbus_cmnd_cb, self.myxpl, {'schema': 'plcbus.basic','xpltype': 'xpl-cmnd',})
        ##
        ##  device = self._config.query('plcbus', 'device')
        #####
        ##Create listener for roowifi
        ##
        print("On rentre dans __init__")
        XplPlugin.__init__(self, name='roowifi')
        self._config = Query(self.myxpl, self.log)
        # creation d'un tableau pour recuperer les eventuels roombas
        self.roombas = {}
        num = 1
        loop = True
        while loop == True:
            #Get each roomba settings
            print("On rentre dans while")
            name = self._config.query('roowifi', 'name-%s' % str(num))
            ip = self._config.query('roowifi', 'ip-%s' % str(num))
            port = self._config.query('roowifi', 'port-%s' % str(num))
            user = self._config.query('roowifi', 'user-%s' % str(num))
            password = self._config.query('roowifi', 'password-%s' % str(num))
            delay = self._config.query('roowifi', 'delay-%s' % str(num))

            ## retirer les valeurs default, une fois le pb de reuperation de config du plugin regler
            if name == None:
                name = "roomba"
            if ip == None:
                ip = "192.168.1.64"
            if port == None:
                port = 9001
            if user == None:
                user = "******"
            if password == None:
                password = "******"
            if delay == None:
                delay = 60
            print(
                "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s"
                % (name, ip, port, user, delay))
            loop = False
            ##

            if name != None:
                self.log.info(
                    "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s"
                    % (name, ip, port, user, delay))
                print(
                    "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s"
                    % (name, ip, port, user, delay))
                self.roombas[name] = {
                    "ip": ip,
                    "port": port,
                    "user": user,
                    "password": password,
                    "delay": delay
                }
            else:
                loop = False
            num += 1

### Create Roomba object
        self._roombamanager = command(self.log)
        # Create listeners
        ##Listener(self.roowifi_command, self.myxpl, {'schema': 'control.basic', 'xpltype': 'xpl-cmnd', 'type': 'command'})
        Listener(self.roowifi_command, self.myxpl, {
            'schema': 'control.basic',
            'xpltype': 'xpl-cmnd'
        })
        self.log.info("Listener for roowifi created")
        #print ("Listener for roowifi created")
        self.enable_hbeat()
        print(" FIN  __init__")

    def roowifi_command(self, message):
        ##Call roowifi lib
        ##@param message : xPL message detected by listener
        print(" On rentre dans roowifi_comand")

        #except KeyError:
        #	self.log.warning("Roomba named '%s' is not defined" % device)
        #	return false
        if 'device' in message.data:
            device = message.data['device']

        ip = self.roombas[device]["ip"]
        port = int(self.roombas[device]["port"])
        #user = self.roombas[device]["user"]
        #password = self.roombas[device]["password"]
        delay = int(self.roombas[device]["delay"])

        ##if 'current' in message.data:
        ##	msg_current = message.data['current'].upper()
        ##if 'type' in message.data:
        ##	msg_type = message.data['type'].lower()
        ##if msg_type == 'command' and msg_current.lower() in ['clean']:
        #if msg_type == 'command' and msg_current.lower() in ['clean']:
        if 'command' in message.data:
            print(" Une commande est recue !")
            lacommand = message.data['command']
            print("La comande est : clean !")
            self.log.debug("Clean command receive for '%s'" % device)
            # Our listener catch a Message with low output command
            status = self._roombamanager.command(ip, port, device, lacommand)
            # Send xpl-trig to say plugin whell receive high command
            if status == True:
                #print ("high ACKed")
                self.log.debug("high command Ack on relay '%s'" % device)
                mess = XplMessage()
                mess.set_type('xpl-trig')
                mess.set_schema('sensor.basic')
                mess.add_data({'device': device})
                mess.add_data({'type': 'command'})
                mess.add_data({'current': 'clean'})
                self.myxpl.send(mess)
            if 'dock' in message.data['command']:
                print("La comande est : dock !")
Esempio n. 21
0
class Lighting(XplPlugin):
    '''
    Manage lighting schema over XPL
    '''
    def __init__(self):
        """
        Create the lighting class
        """
        XplPlugin.__init__(self, name='lighting')
        self.log.debug("lighting.__init__ : Start ...")
        self._config = Query(self.myxpl, self.log)

        self.log.debug("lighting.__init__ : Try to get configuration from XPL")
        try:
            #self.use_cron = bool(self._config.query('lighting', 'usecron'))
            self.broadcast = bool(self._config.query('lighting', 'broadcast'))
            #self.presence = bool(self._config.query('lighting', 'presence'))
        except:
            error = "Can't get configuration from XPL : %s" %  \
                     (traceback.format_exc())
            self.log.exception("lighting.__init__ : " + error)
            #self.use_cron = True
            self.broadcast = True
            #self.presence = True
            raise LightingException(error)

        self.log.debug(
            "lighting.__init__ : Try to start the lighting librairy")
        try:
            self._mylighting = LightingAPI(self.broadcast, \
                self.myxpl, self.log, self.get_data_files_directory())
        except:
            error = "Something went wrong during lightingAPI init : %s" %  \
                     (traceback.format_exc())
            self.log.error("lighting.__init__ : " + error)
            self.force_leave()
            raise LightingException(error)

        self.log.debug("lighting.__init__ : Try to create listeners")
        Listener(self.lighting_config_cmnd, self.myxpl, {
            'schema': 'lighting.config',
            'xpltype': 'xpl-cmnd'
        })
        Listener(self.lighting_basic_cmnd, self.myxpl, {
            'schema': 'lighting.basic',
            'xpltype': 'xpl-cmnd'
        })
        #        Listener(self.lighting_basic_trig, self.myxpl,
        #                 {'schema': 'lighting.basic', 'xpltype': 'xpl-trig'})
        self.enable_hbeat()
        self._mylighting.reload_config()
        self.log.info("Plugin lighting correctly started.")

    def lighting_basic_trig(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("lighting_basic_trig() : Start ...")
        self._mylighting.basic_trig_listener(message)
        self.log.debug("lighting_basic_trig() : Done :)")

    def lighting_config_cmnd(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("lighting_config_cmnd() : Start ...")
        self._mylighting.config_cmnd_listener(message)
        self.log.debug("lighting_config_cmnd() : Done :)")

    def lighting_basic_cmnd(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("lighting_basic_cmnd() : Start ...")
        self._mylighting.basic_cmnd_listener(message)
        self.log.debug("lighting_basic_cmnd() : Done :)")
Esempio n. 22
0
class ZiBaseMain(XplPlugin):
    '''Manage ZiBase
    '''	
    def __init__(self):
        """ Create lister and launch bg listening
        """
        XplPlugin.__init__(self, name = 'zibase')

        self._config = Query(self.myxpl, self.log)

        self.address = self._config.query('zibase', 'ip')
        self.inter = self._config.query('zibase', 'interface')
        self.port = int(self._config.query('zibase', 'port'))
        self.valvar=self._config.query('zibase', 'envar')
        self.interv=int(self._config.query('zibase', 'interv'))

        self.log.info("Creating listener for ZiBase")
        Listener(self.zibase_command, self.myxpl, {'schema': 'zibase.basic',
                'xpltype': 'xpl-cmnd'})
        
        try:
            self.ip_host=get_ip_address(self.inter)
            self.log.debug("Adress IP Host=%s" % (self.ip_host))
        except:
            self.log.error("IP Host not found=%s" % (traceback.format_exc()))
            return

        try:
            self.api = APIZiBase(self.log,self.address)
        except:
            self.log.error("API ZiBase error=%s" % (traceback.format_exc()))
            return

        try:
            self.th=ServerZiBase(self.log,self.ip_host,self.port,self.myxpl)
            self.th.start()
        except:
            self.log.error("Server ZiBase error=%s" % (traceback.format_exc()))
            self.stop()

        try:
            self.api.Connect(self.ip_host,self.port)
        except:
            self.log.error("Connection ZiBase error=%s" % (traceback.format_exc()))
            self.stop()

        if self.valvar=="True" :
            try:
                self.log.info("Start reading internal variables")
                var_read=XplTimer(self.interv,self.zibase_read_var,self.myxpl)
                var_read.start()
            except:
                self.log.error("reading internal variables error")
                return

        self.add_stop_cb(self.stop)
        self.enable_hbeat()

        self.log.info("Plugin ready :)")
        
    def zibase_command(self, message):
        """ Call zibase lib function in function of given xpl message
            @param message : xpl message
        """
        commands = {
            'off': 0,
            'on': 1,
            'preset-dim' : 2,
        }
        protocols = {
            'PRESET': 0,
            'VISONIC433' : 1,
            'VISONIC868' : 2,
            'CHACON' : 3,
            'DOMIA' : 4,
            'X10' : 5,
            'ZWAVE' : 6,
            'RFS10' : 7,
            'XDD433AL' : 8,
            'XDD868AL' : 9,
            'XDD868INSH' : 10,
            'XDD868PILOT' : 11,
            'XDD868BOAC' : 12,
        }

        cmd = None
        dev = None
        protocol = None
        preset_dim = 0
        
        if 'command' in message.data:
            cmd = message.data['command']
        if 'device' in message.data:
            chaine=message.data['device'].split(':')
            try:
                dev = chaine[0].upper()
                protocol=chaine[1].upper()
            except:
                self.log.error("Syntax device not valid")
        if 'preset-dim' in message.data:
            preset_dim=message.data['preset-dim']

        self.log.debug(message.data)
        if protocol == None :
            self.log.warning("Protocol not specified")
            return
        else:
            self.log.debug("%s received : device = %s protocol = %s number protocol=%s preset=%s" % (cmd, dev, protocol, protocols[protocol],str(preset_dim)))
            try:
                self.api.sendCommand(dev, commands[cmd], protocols[protocol],int(preset_dim))
            except:
                self.log.error("Sendcommand error")
                return

            self.th.send_xpl_cmd(message.data['device'], cmd, preset_dim)



    def stop(self):
        self.log.debug("Stop plugin in progress...")
        self.var_read.stop()
        self.api.Disconnect(self.ip_host,self.port)
        self.th.stop()
        return
    
    def zibase_read_var(self):
        try:
            datas=self.api.getVariables()
            for data in datas:
                elmt=data.split(':')
                stats=['sta:' + elmt[1]]
                self.th.send_xpl_sensor(stats,elmt[0],'xpl-stat')
        except:
            self.log.error("Read var error=%s" % (traceback.format_exc()))
Esempio n. 23
0
class X10Main(XplPlugin):
    '''Manage x10 technology using heyu
    '''

    def __init__(self):
        """
        Create the X10Main class
        This class is used to connect x10 (through heyu) to the xPL Network
        """
        XplPlugin.__init__(self, name = 'x10_heyu')
        self._heyu_cfg_path_res = ""
        self._config = Query(self.myxpl, self.log)
        self._heyu_cfg_path_res = self._config.query('x10_heyu', 'heyu-cfg-path')
        try:
            self.__myx10 = X10API(self._heyu_cfg_path_res, self.log)
        except Exception:
            self.log.error("Something went wrong during heyu init, check logs")
            self.log.error("Exception : %s" % traceback.format_exc())
            exit(1)
        #Create listeners
        Listener(self.x10_cmnd_cb, self.myxpl, {'schema': 'x10.basic', 'xpltype': 'xpl-cmnd'})
        #One listener for system schema, allowing to reload config
        #Listener(self.heyu_reload_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd',
        #                                                'command': 'reload', 'plugin': 'x10'})
        #One listener for system schema, allowing to dump config
        #Listener(self.heyu_dump_config, self.myxpl, {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd',
        #                                              'command': 'push_config', 'plugin': 'x10'})
        self.log.debug("before start X10monitor")
        self._monitor = X10Monitor(self._heyu_cfg_path_res)
        self._monitor.get_monitor().add_cb(self.x10_monitor_cb)
        self._monitor.get_monitor().start()
        self.enable_hbeat()
        self.log.debug("Heyu correctly started")

    #def heyu_reload_config(self, message):
    #    """
    #    Regenerate the heyu config file
    #    First, it needs to get all config items, then rewrite the config file
    #    and finally restart heyu
    #    @param message : an XplMessage object
    #    """
    #    #Heyu config items
    #    result = self._config.query('x10', '')
    #    if result is not None:
    #        heyu_config_items = filter(lambda k : k.startswith("heyu-file-"), result.keys())
    #        heyu_config_values = []
    #        for key in heyu_config_items:
    #            heyu_config_values.append(result[key])
    #        #Heyu path
    #        myheyu = HeyuManager(self._heyu_cfg_path_res)
    #        try:
    #            myheyu.write(heyu_config_values)
    #        except IOError:
    #            self.log.warning("Heyu config file can't be opened")
    #        res = myheyu.restart()
    #        if res:
    #            self.log.warning("Error during heyu restart : %s" % res)
    #    else:
    #        print("empty res")
#
    #def heyu_dump_config(self, message):
    #    """
    #    Send the heyu config file on the network
    #    @param message : an XplMessage object
    #    """
    #    #Heyu path
    #    myheyu = HeyuManager(self._heyu_cfg_path_res)
    #    lines = myheyu.load()
    #    mess = XplMessage()
    #    mess.set_type('xpl-trig')
    #    mess.set_schema('domogik.config')
    #    count = 0
    #    for line in lines:
    #        key = "heyu_file_%s" % count
    #        count = count + 1
    #        mess.add_data({key :  line})
    #    self.myxpl.send(mess)

    def x10_cmnd_cb(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        commands = {
            'on': lambda d, h, l: self.__myx10.on(d),
            'off': lambda d, h, l: self.__myx10.off(d),
            'all_units_on': lambda d, h, l: self.__myx10.house_on(h),
            'all_units_off': lambda d, h, l: self.__myx10.house_off(h),
            'all_lights_on': lambda d, h, l: self.__myx10.lights_on(h),
            'all_lights_off': lambda d, h, l: self.__myx10.lights_off(h),
            'bright': lambda d, h, l: self.__myx10.bright(d, l),
            'dim': lambda d, h, l: self.__myx10.dim(d, l),
            'brightb': lambda d, h, l: self.__myx10.brightb(d, l),
            'dimb': lambda d, h, l: self.__myx10.dimb(d, l),
        }
        cmd = None
        dev = None
        house = None
        level = None
        if 'command' in message.data:
            cmd = message.data['command']
        if 'device' in message.data:
            dev = message.data['device']
        if 'house' in message.data:
            house = message.data['house']
        if 'level' in message.data:
            level = message.data['level']
        self.log.debug("%s received : device = %s, house = %s, level = %s" % (cmd, dev, house, level))
        commands[cmd](dev, house, level)
        self.x10_monitor_cb(dev, cmd)

    def x10_monitor_cb(self, unit, order, args = None):
        """
        Callback for x10 monitoring
        @param unit : the unit of the element controled
        @param order : the order sent to the unit
        """
        self.log.debug("X10 Callback for %s" % unit)
        mess = XplMessage()
        mess.set_type("xpl-trig")
        mess.set_schema("x10.basic")
        mess.add_data({"device" :  unit})
        mess.add_data({"command" :  order})
        if args:
            mess.add_data({"level" : args})
        self.myxpl.send(mess)
Esempio n. 24
0
class SamsungTVManager(XplPlugin):
    """ Manage Samsung televisions
    """

    def __init__(self):
        """ Init manager
        """
        XplPlugin.__init__(self, name = 'tv_samsg')

        # Configuration : list of televisions
        self.televisions = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            name = self._config.query('tv_samsg', 'tv-%s-name' % str(num))
            device = self._config.query('tv_samsg', 'tv-%s-device' % str(num))
            if name != None:
                self.log.info("Configuration : name=%s, device=%s" % (name, device))
                self.televisions[name] = {"device" : device}
            else:
                loop = False
            num += 1

        ### Create SamsungTV objects
        for television in self.televisions:
            self.televisions[television]['obj'] = SamsungTV(self.log)
            try:
                self.log.info("Opening Samsung Television named '%s' (device : %s)" %
                               (television, self.televisions[television]['device']))
                self.televisions[television]['obj'].open(self.televisions[television]['device'])
            except SamsungTVException as err:
                self.log.error(err.value)
                print(err.value)
                self.force_leave()
                return

        # Create listener
        Listener(self.television_cb, self.myxpl, {'schema': 'control.basic',
                'xpltype': 'xpl-cmnd', 'type': 'television'})
        self.log.debug("Listener for tv_samsg created")

        self.enable_hbeat()

    def television_cb(self, message):
        """ Call tv_samsg lib
            @param message : xPL message detected by listener
        """
        # device contains name of television which will be used to get device
        if 'device' in message.data:
            name = message.data['device']
        if 'current' in message.data:
            command = message.data['current']
        else:
            self._log.warning("Xpl message : missing 'current' attribute")
            return
        if 'data1' in message.data:
            data1 = int(message.data['data1'])
        else:
            data1 = None

        try:
            device = self.televisions[name]["device"]
        except KeyError:
            self.log.warning("Television named '%s' is not defined" % name)
            return
        
        self.log.info("Television command received for '%s' on '%s'" % (name, device))
        status = self.televisions[name]['obj'].send(command, data1)

        # Send xpl-trig to say plugin receive command
        print("S=%s" % status)
        if status == True:
            mess = XplMessage()
            mess.set_type('xpl-trig')
            mess.set_schema('sensor.basic')
            mess.add_data({'device' :  device})
            mess.add_data({'type' :  'television'})
            mess.add_data({'current' :  command})
            if data1 != None:
                mess.add_data({'data1' :  data1})
            print(mess)
            self.myxpl.send(mess)
Esempio n. 25
0
class XplBridgeManager(XplPlugin):
    """ Send xpl message from hub to serial device
                    and vice versa
    """
    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='xpl2ser')

        # Configuration
        self._config = Query(self.myxpl, self.log)

        # Configuration : list of devices to check
        self.dev_list = {}
        num = 1
        loop = True
        while loop == True:
            dev = self._config.query('xpl2ser', 'device-%s' % str(num))
            if dev != None:
                self.log.info("Configuration : device=%s" % dev)
                # init object
                baudrate = self._config.query('xpl2ser',
                                              'baudrate-%s' % str(num))
                self.dev_list[dev] = {"baudrate": baudrate}
                num += 1
            else:
                loop = False

        # no device configured
        if num == 1:
            msg = "No device configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        ### Start listening each device
        for dev in self.dev_list:
            try:
                self.dev_list[dev]["obj"] = XplBridge(self.log, self.send_xpl,
                                                      self.get_stop())
                # Open serial device
                self.log.info("Open '%s'" % dev)
                try:
                    self.dev_list[dev]["obj"].open(
                        dev, self.dev_list[dev]["baudrate"])
                except XplBridgeException as e:
                    self.log.error(e.value)
                    print(e.value)
                    self.force_leave()
                    return
                self.log.info("Start listening for '%s'" % dev)
                dev_listen = threading.Thread(None,
                                              self.dev_list[dev]["obj"].listen,
                                              "listen_serial", (), {})
                dev_listen.start()
            except:
                self.log.error(traceback.format_exc())
                print(traceback.format_exc())
                # We don't quit plugin if an error occured
                # a device may have disappeared
                # Notice that it won't be read if device come back
                #self.force_leave()
                #return

        # Create listeners
        # Notice : this listener and callback function make this plugin send
        # on serial port each xpl message it reads on serial port
        # TODO : update this !
        #Listener(self.xplbridge_cb, self.myxpl)

        self.enable_hbeat()
        self.log.info("Plugin ready :)")

    def send_xpl(self, resp):
        """ Send xPL message on network
            @param resp : xpl message
        """
        print("Input xpl message : %s " % resp)
        try:
            msg = XplMessage(resp)
            self.myxpl.send(msg)
        except XplMessageError:
            error = "Bad data : %s" % traceback.format_exc()
            print(error)
            self.log.error(error)

    def xplbridge_cb(self, message):
        """ Call xplbridge lib for sending xpl message to serial
            @param message : xpl message to send
        """
        self.log.debug("Call xplbridge_cb")
        mesg = message.to_packet()
        # Write on serial device
        self.log.debug("Call write() ")
        self.br.write(mesg)
Esempio n. 26
0
class foscam(XplPlugin):
    """ Implements a listener for Foscam relay messages on xPL network
    """
    def __init__(self):
        """ Create listener for Foscam Relay
        """
        XplPlugin.__init__(self, name='foscam')

        self._config = Query(self.myxpl, self.log)
        # Configuration : list of cameras
        self.cameras = {}
        num = 1
        loop = True
        while loop == True:
            #Get each camera settings
            name = self._config.query('foscam', 'name-%s' % str(num))
            ip = self._config.query('foscam', 'ip-%s' % str(num))
            port = self._config.query('foscam', 'port-%s' % str(num))
            user = self._config.query('foscam', 'user-%s' % str(num))
            password = self._config.query('foscam', 'password-%s' % str(num))
            delay = self._config.query('foscam', 'delay-%s' % str(num))
            if port == None:
                port = 80
            if user == None:
                user = ""
            if password == None:
                password = ""
            if delay == None:
                delay = 0
            if name != None:
                self.log.info(
                    "Configuration : name=%s, ip=%s, port=%s, user=%s, password=No_Log, delay=%s"
                    % (name, ip, port, user, delay))
                self.cameras[name] = {
                    "ip": ip,
                    "port": port,
                    "user": user,
                    "password": password,
                    "delay": delay
                }
            else:
                loop = False
            num += 1

        ### Create FOSCAM object
        self._foscammanager = RELAY(self.log)
        # Create listeners
        Listener(self.foscam_command, self.myxpl, {
            'schema': 'control.basic',
            'xpltype': 'xpl-cmnd',
            'type': 'output'
        })
        self.log.info("Listener for Foscam relay created")
        #print ("Listener for Foscam relay created")
        self.enable_hbeat()

    def foscam_command(self, message):
        """ Call Foscamn lib
            @param message : xPL message detected by listener
        """
        if 'device' in message.data:
            device = message.data['device']
        if 'current' in message.data:
            msg_current = message.data['current'].upper()

        if 'type' in message.data:
            msg_type = message.data['type'].lower()
        try:
            ip = self.cameras[device]["ip"]
            port = int(self.cameras[device]["port"])
            user = self.cameras[device]["user"]
            password = self.cameras[device]["password"]
            delay = int(self.cameras[device]["delay"])
        except KeyError:
            self.log.warning("Camera named '%s' is not defined" % device)
            return
        if msg_type == 'output' and msg_current.lower() in ['high']:
            print("high recu")
            self.log.debug("high command receive on relay '%s'" % device)
            # Our listener catch a Message with low output command
            status = self._foscammanager.close_relay(ip, port, user, password,
                                                     device)
            # Send xpl-trig to say plugin whell receive high command
            if status == True:
                #print ("high ACKed")
                self.log.debug("high command Ack on relay '%s'" % device)
                mess = XplMessage()
                mess.set_type('xpl-trig')
                mess.set_schema('sensor.basic')
                mess.add_data({'device': device})
                mess.add_data({'type': 'output'})
                mess.add_data({'current': 'high'})
                self.myxpl.send(mess)
        if msg_type == 'output' and msg_current.lower() in ['low']:
            print("low recu")
            self.log.debug("low command receive on relay '%s'" % device)
            # Our listener catch a Message with low output command
            status = self._foscammanager.open_relay(ip, port, user, password,
                                                    device)
            # Send xpl-trig to say plugin whell receive low command
            if status == True:
                #print ("low ACKed")
                self.log.debug("low command Ack on relay '%s'" % device)
                mess = XplMessage()
                mess.set_type('xpl-trig')
                mess.set_schema('sensor.basic')
                mess.add_data({'device': device})
                mess.add_data({'type': 'output'})
                mess.add_data({'current': 'low'})
                self.myxpl.send(mess)

        if msg_type == 'output' and msg_current.lower() in ['pulse']:
            print("pulse recu")
            self.log.debug("pulse command receive on relay '%s'" % device)
            # Our listener catch a Message with output pulse output command
            status = self._foscammanager.pulse_relay(ip, port, user, password,
                                                     delay, device)
            # Send xpl-trig to say plugin whell receive pulse command
            if status == True:
                print("pulse ACKed")
                self.log.debug("pulse command Ack on relay '%s'" % device)
                mess = XplMessage()
                mess.set_type('xpl-trig')
                mess.set_schema('sensor.basic')
                mess.add_data({'device': device})
                mess.add_data({'type': 'output'})
                mess.add_data({'current': 'pulse'})
                self.myxpl.send(mess)
Esempio n. 27
0
class VelbusManager(XplPlugin):
    """
	Managages the velbus domogik plugin
    """
    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='velbus')
        self._config = Query(self.myxpl, self.log)
        # get the config values
        device_type = self._config.query('velbus', 'connection-type')
        if device_type == None:
            self.log.error('Devicetype is not configured, exitting') 
            print('Devicetype is not configured, exitting')
            self.force_leave()
            return
        device = self._config.query('velbus', 'device')
        #device = '192.168.1.101:3788'
        if device == None:
            self.log.error('Device is not configured, exitting') 
            print('Device is not configured, exitting')
            self.force_leave()
            return
        # validate the config vars
        if (device_type != 'serial') and (device_type != 'socket'):
            self.log.error('Devicetype must be socket or serial, exitting') 
            print('Devicetype must be socket or serial, exitting')
            self.force_leave()
            return
        if device_type == 'socket' and not re.match('[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}:[0-9]+', device):
            self.log.error('A socket device is in the form of <ip>:<port>, exitting') 
            print('A socket device is in the form of <ip>:<port>, exitting')
            self.force_leave()
            return

        # Init RFXCOM
        self.manager  = VelbusDev(self.log, self.send_xpl,
			self.send_trig, self.get_stop())
        self.add_stop_cb(self.manager.close)
        
        # Create a listener for all messages used by RFXCOM
        Listener(self.process_lighting_basic, self.myxpl,
                 {'xpltype': 'xpl-cmnd', 'schema': 'lighting.basic'})
        Listener(self.process_shutter_basic, self.myxpl,
                 {'xpltype': 'xpl-cmnd', 'schema': 'shutter.basic'})
        # Create listeners
        try:
            self.manager.open(device, device_type)
        except VelbusException as ex:
            self.log.error(ex.value)
            self.force_leave()
            return
        self.manager.scan()
            
        # Start reading RFXCOM
        listenthread = threading.Thread(None,
                                   self.manager.listen,
                                   "velbus-process-reader",
                                   (self.get_stop(),),
                                   {})
        self.register_thread(listenthread)
        listenthread.start()
        self.enable_hbeat()

    def send_xpl(self, schema, data):
        """ Send xPL message on network
        """
        self.log.info("schema:%s, data:%s" % (schema, data))
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema(schema)
        for key in data:
            msg.add_data({key : data[key]})
        self.myxpl.send(msg)

    def send_trig(self, message):
        """ Send xpl-trig given message
            @param message : xpl-trig message
        """
        self.myxpl.send(message)

    def process_lighting_basic(self, message):
        """ Process xpl chema lightning.basic
        """
        print message
        #self.send_xpl("lighting.device", message.data)
        device = message.data['device']
        chan = message.data['channel']
        if message.data["level"] == 'None':
            message.data["level"] = 0
        self.manager.send_level( device, chan, message.data["level"])

    def process_shutter_basic(self, message):
        """ Process xpl chema shutter.basic
        """
        self.send_xpl("shutter.device", message.data)
        add = message.data['device'].split('-')
        chan = int(add[1])
        address = add[0]
        if message.data["command"] == "up":
            self.log.debug("set shutter up")
            self.manager.send_shutterup( address, chan )
        elif message.data["command"] == "down":
            self.log.debug("set shutter down")
            self.manager.send_shutterdown( address, chan )
        else:
            self.log.debug("Unknown command in shutter.basic message")
Esempio n. 28
0
class XplBridgeManager(XplPlugin):
    """ Send xpl message from hub to serial device
                    and vice versa
    """

    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='xpl2ser')

        # Configuration
        self._config = Query(self.myxpl, self.log)

        # Configuration : list of devices to check
        self.dev_list = {}
        num = 1
        loop = True
        while loop == True:
            dev = self._config.query('xpl2ser', 'device-%s' % str(num))
            if dev != None:
                self.log.info("Configuration : device=%s" % dev)
                # init object 
                baudrate = self._config.query('xpl2ser', 'baudrate-%s' % str(num))
                self.dev_list[dev] = { "baudrate" : baudrate }
                num += 1
            else:
                loop = False

        # no device configured
        if num == 1:
            msg = "No device configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        ### Start listening each device
        for dev in self.dev_list:
            try:
                self.dev_list[dev]["obj"] = XplBridge(self.log, self.send_xpl, self.get_stop())
                # Open serial device
                self.log.info("Open '%s'" % dev)
                try:
                    self.dev_list[dev]["obj"].open(dev, 
                                              self.dev_list[dev]["baudrate"])
                except XplBridgeException as e:
                    self.log.error(e.value)
                    print(e.value)
                    self.force_leave()
                    return
                self.log.info("Start listening for '%s'" % dev)
                dev_listen = threading.Thread(None,
                                              self.dev_list[dev]["obj"].listen,
                                              "listen_serial",
                                              (),
                                              {})
                dev_listen.start()
            except:
                self.log.error(traceback.format_exc())
                print(traceback.format_exc())
                # We don't quit plugin if an error occured
                # a device may have disappeared
                # Notice that it won't be read if device come back
                #self.force_leave()
                #return

        # Create listeners
        # Notice : this listener and callback function make this plugin send
        # on serial port each xpl message it reads on serial port
        # TODO : update this !
        #Listener(self.xplbridge_cb, self.myxpl)
 
        self.enable_hbeat()
        self.log.info("Plugin ready :)")

    def send_xpl(self, resp):
        """ Send xPL message on network
            @param resp : xpl message
        """
        print("Input xpl message : %s " % resp)
        try:
            msg = XplMessage(resp)
            self.myxpl.send(msg)
        except XplMessageError:
            error = "Bad data : %s" % traceback.format_exc()
            print(error)
            self.log.error(error)

    def xplbridge_cb(self, message):
        """ Call xplbridge lib for sending xpl message to serial
            @param message : xpl message to send
        """
        self.log.debug("Call xplbridge_cb")
        mesg = message.to_packet()
        # Write on serial device
        self.log.debug("Call write() ")
        self.br.write(mesg)
Esempio n. 29
0
class OneWireManager(XplPlugin):

    def __init__(self):
        """ Init onewire 
        """
        XplPlugin.__init__(self, name='onewire')
        try:
            ### get all config keys
            self._config = Query(self.myxpl, self.log)
            device = self._config.query('onewire', 'device')

            cache = self._config.query('onewire', 'cache')
            if cache == "True":
                cache = True
            else:
                cache = False
            ### Add Event listener
            Listener(self.read_xpl, self.myxpl,{'schema':'sensor.basic'})

            ### DS18B20 config
            ds18b20_enabled = self._config.query('onewire', 'ds18b20-en')

            ds18b20_interval = self._config.query('onewire', 'ds18b20-int')
    
            ds18b20_resolution = self._config.query('onewire', 'ds18b20-res')
    
            ### DS18S20 config
            ds18s20_enabled = self._config.query('onewire', 'ds18s20-en')

            ds18s20_interval = self._config.query('onewire', 'ds18s20-int')
    
            ### DS2401 config
            ds2401_enabled = self._config.query('onewire', 'ds2401-en')

            ds2401_interval = self._config.query('onewire', 'ds2401-int')
    
            ### DS2438 config
            ds2438_enabled = self._config.query('onewire', 'ds2438-en')

            ds2438_interval = self._config.query('onewire', 'ds2438-int')
    

            ### DS2408 config
            ds2408_enabled = self._config.query('onewire', 'ds2408-en')

            ds2408_interval = self._config.query('onewire', 'ds2408-int')


            ### Open one wire network
            try:
                ow = OneWireNetwork(self.log, device, cache)
                self.ow = ow
            except OneWireException as e:
                self.log.error(e.value)
                print(e.value)
                self.force_leave()
                return
            
    
            ### DS18B20 support
            if ds18b20_enabled == "True":
                self.log.info("DS18B20 support enabled")
                ds18b20 = threading.Thread(None, 
                                           ComponentDs18b20, 
                                           "ds18b20",
                                           (self.log,
                                            ow, 
                                            float(ds18b20_interval), 
                                            ds18b20_resolution,
                                            self.send_xpl,
                                            self.get_stop()),
                                           {})
                ds18b20.start()
    
            ### DS18S20 support
            if ds18s20_enabled == "True":
                self.log.info("DS18S20 support enabled")
                ds18s20 = threading.Thread(None, 
                                           ComponentDs18s20, 
                                           "ds18s20",
                                           (self.log,
                                            ow, 
                                            float(ds18s20_interval), 
                                            self.send_xpl,
                                            self.get_stop()),
                                           {})
                ds18s20.start()
    
            ### DS2401 support
            if ds2401_enabled == "True":
                self.log.info("DS2401 support enabled")
                ds2401 = threading.Thread(None, 
                                           ComponentDs2401, 
                                           "ds2401",
                                           (self.log,
                                            ow, 
                                            float(ds2401_interval), 
                                            self.send_xpl,
                                            self.get_stop()),
                                           {})
                ds2401.start()
    
            ### DS2438 support
            if ds2438_enabled == "True":
                self.log.info("DS2438 support enabled")
                ds2438 = threading.Thread(None, 
                                           ComponentDs2438, 
                                           "ds2438",
                                           (self.log,
                                            ow, 
                                            float(ds2438_interval), 
                                            self.send_xpl,
                                            self.get_stop()),
                                           {})
                ds2438.start()
    


            ### DS2408 support
            if ds2408_enabled == "True":
                self.log.info("DS2408 support enabled")
                ds2408 = threading.Thread(None,
                                           ComponentDs2408,
                                           "ds2408",
                                           (self.log,
                                            ow,
                                            float(ds2408_interval),
                                            self.send_xpl,
                                            self.get_stop()),
                                           {})
                ds2408.start()




        except:
            self.log.error("Plugin error : stopping plugin... Trace : %s" % traceback.format_exc())
            print(traceback.format_exc())
            self.force_leave()
        self.enable_hbeat()



    def send_xpl(self, type, data):
        """ Send data on xPL network
            @param data : data to send (dict)
        """
        msg = XplMessage()
        msg.set_type(type)
        msg.set_schema("sensor.basic")
        for element in data:
            msg.add_data({element : data[element]})
        self.log.debug("Send xpl message...")
        self.myxpl.send(msg)


    def read_xpl(self, message):
        switch = None
        device = None
        data = None
        
        if 'switch' in message.data:
            switch = message.data['switch']
        if 'device' in message.data:
            device = message.data['device']
        if 'data' in message.data:
            data = message.data['data']

        print("Message XPL %s" %message)
        if (switch != None and device != None and data != None):
            r = self.ow.write(device, switch, data)
            mess = XplMessage()
            mess.set_type("xpl-trig")
            mess.set_schema("sensor.basic")
            mess.add_data({"device" :  device})
            mess.add_data({"command" :  "switch"+switch})
            self.myxpl.send(mess)
            print("Setting PIO "+switch+"="+data+" for device "+device)

            mess2 = XplMessage()
            mess2.set_type("xpl-trig")
            mess2.set_schema("sensor.basic")
            mess2.add_data({"device" :  device})
            mess2.add_data({"data"+switch : r })
            mess2.add_data({"type" : "PIO_ALL"})
            self.myxpl.send(mess2)
Esempio n. 30
0
class OZwave(XplHlpPlugin):
    """ Implement a listener for Zwave command messages
        and launch background  manager to listening zwave events by callback
    """
    def __init__(self):
        """ Create listener and background zwave manager
        """
        XplHlpPlugin.__init__(self, name = 'ozwave')
        
        # Récupère la config 
        # - device
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('ozwave', 'device')
        ozwlogConf = self._config.query('ozwave', 'ozwlog')
        self._config = Query(self.myxpl, self.log)
        print ('Mode log openzwave :',  ozwlogConf)
        # Recupère l'emplacement des fichiers de configuration OZW
        pathUser = self.get_data_files_directory()  +'/'
        pathConfig = self._config.query('ozwave', 'configpath') + '/'
        # Initialise le manager Open zwave
        try:
            self.myzwave = OZWavemanager(self._config, self.send_xPL, self.sendxPL_trig, self.get_stop(), self.log, configPath = pathConfig,  userPath = pathUser,  ozwlog = ozwlogConf)
        except OZwaveException as e:
            self.log.error(e.value)
            print e.value
            self.force_leave()
            return
        self.log.debug("__init__ : Enable heplers")
        self.helpers =   \
           {
             "infostate" :
              {
                "cb" : self.myzwave.GetPluginInfo,
                "desc" : "Show Info status. Experimental.",
                "usage" : "memory",
              }
            }
        self.enable_helper()
        # Crée le listener pour les messages de commande xPL traités par les devices zwave
        Listener(self.ozwave_cmd_cb, self.myxpl,{'schema': 'ozwave.basic',
                                                                        'xpltype': 'xpl-cmnd'})
        # Validation avant l'ouverture du controleur, la découverte du réseaux zwave prends trop de temps -> RINOR Timeout
        self.add_stop_cb(self.myzwave.stop)
        self.enable_hbeat()
        # Ouverture du controleur principal
        self.myzwave.openDevice(device)
    
    def __sizeof__(self):
        return XplHlpPlugin.__sizeof__(self) + sum(sys.getsizeof(v) for v in self.__dict__.values())
    

    def ozwave_cmd_cb(self, message):
        """" Envoie la cmd xpl vers le OZWmanager"""
        print ("commande xpl recue")
        print message
        self.log.debug(message)
        if 'command' in message.data:
            if 'group'in message.data:
                # en provenance de l'UI spéciale
                self.ui_cmd_cb(message)
            else :
                cmd = message.data['command']
                device = message.data['device']
                if cmd == 'level' :
                    print ("appel envoi zwave command %s" %cmd)
                    lvl = message.data['level']
                    self.myzwave.sendNetworkZW(cmd, device, lvl)
                elif cmd == "on"  or cmd == "off" :
                    print ("appel envoi zwave command %s" %cmd)
                    self.myzwave.sendNetworkZW(cmd, device)
                else:
                    self.myzwave.sendNetworkZW(cmd, device)
                    
    def getdict2UIdata(self, UIdata):
        """ retourne un format dict en provenance de l'UI (passage outre le format xPL)"""
        retval = UIdata.replace('&quot;', '"').replace('&squot;', "'").replace("&ouvr;", '{').replace("&ferm;", '}') ;
        try :
            return eval(retval)
        except OZwaveException as e:
            print retval
            self.log.debug ("Format data to UI : eval in getdict2UIdata error : " +   retval)
            return {'error': 'invalid format'}
            
    def getUIdata2dict(self, ddict):
        """Retourne le dict formatter pour UI (passage outre le format xPL)"""
        print "conversion pour transfertvers UI , " , str(ddict)
        for k in ddict :   # TODO: pour passer les 1452 chars dans RINOR, à supprimer quand MQ OK, 
            if isinstance(ddict[k], str) :
                ddict[k] = ddict[k].replace("'", "&squot;")  # remplace les caractères interdits pour rinor
                if len(str(ddict[k])) >800 : 
                    ddict[k] = ddict[k][:800]
                    print("value raccourccis : ", k, ddict[k])
                    self.log.debug ("Format data to UI : value to large, cut to 800, key : %s, value : %s" % (str(k), str(ddict[k])))
        return str(ddict).replace('{', '&ouvr;').replace('}', '&ferm;').replace('"','&quot;').replace("'",'&quot;').replace('False', 'false').replace('True', 'true').replace('None', '""')
        
    def ui_cmd_cb(self, message):
        """xpl en provenace de l'UI (config/special)"""
        response = True
        info = "essais"
        request = self.getdict2UIdata(message.data['value'])
        print("Commande UI")
        if message.data['group'] =='UI' :
            mess = XplMessage()
            mess.set_type('xpl-trig') 
            mess.set_schema('ozwave.basic')
            if request['request'] == 'ctrlAction' :
                action = dict(request)
                del action['request']
                report = self.myzwave.handle_ControllerAction(action)
                info = self.getUIdata2dict(report)
                mess.add_data({'command' : 'Refresh-ack', 
                                    'group' :'UI', 
                                    'ctrlaction' : request['action'], 
                                    'data': info})
                if request['cmd'] =='getState' and report['cmdstate'] != 'stop' : response = False
            elif request['request'] == 'ctrlSoftReset' :
                info = self.getUIdata2dict(self.myzwave.handle_ControllerSoftReset())
                mess.add_data({'command' : 'Refresh-ack', 
                                    'group' :'UI', 
                                    'data': info})
            elif request['request'] == 'ctrlHardReset' :
                info = self.getUIdata2dict(self.myzwave.handle_ControllerHardReset())
                mess.add_data({'command' : 'Refresh-ack', 
                                    'group' :'UI', 
                                    'data': info})   
            elif request['request'] == 'GetPluginInfo' :
                info = self.getUIdata2dict(self.myzwave.GetPluginInfo())
                mess.add_data({'command' : 'Refresh-ack', 
                                    'group' :'UI', 
                                    'node' : 0, 
                                    'data': info})
            else :
                mess.add_data({'command' : 'Refresh-ack', 
                                    'group' :'UI', 
                                    'data': "unknown request", 
                                    'error': "unknown request"})
                print "commande inconnue"
            if response : self.myxpl.send(mess)
                                  
                                    
    def send_xPL(self, xPLmsg,  args = None):
        """ Envoie une commande ou message zwave vers xPL"""
        mess = XplMessage()
        mess.set_type(xPLmsg['type']) 
        mess.set_schema(xPLmsg['schema'])
        if xPLmsg.has_key('data') : mess.add_data(xPLmsg['data'])
        print '********************* Dans send_xPL *****************'
        if args :
            mess.add_data({'data': self.getUIdata2dict(args)})
        print mess
        self.myxpl.send(mess)
        
    def sendxPL_trig(self, msgtrig):
        """Envoie un message trig sur le hub xPL"""
        mess = XplMessage()
        if 'info' in msgtrig:
            self.log.error ("Error : Node %s unreponsive" % msgtrig['node'])
        elif 'Find' in msgtrig:
            print("node enregistré : %s" % msgtrig['Find'])
        elif 'typexpl' in msgtrig:
            mess.set_type(msgtrig['typexpl'])
            mess.set_schema(msgtrig['schema'])
            if msgtrig['genre'] == 'actuator' :
                if msgtrig['level'] in [0, 'False', False] : cmd ="off"
                elif msgtrig['level'] in [255, 'True',  True]: cmd ="on"
                else: cmd ='level'
                mess.add_data({'device' : msgtrig['device'],
                            'command' : cmd,
                            'level': msgtrig['level']})
                if msgtrig.has_key('type'): mess.add_data({'type' : msgtrig['type'] })
            elif msgtrig['genre'] == 'sensor' :  # tout sensor
                if msgtrig['type'] =='status' :  # gestion du sensor binary pour widget binary
                    mess.add_data({'device' : msgtrig['device'],
                            'type' : msgtrig['type'] ,
                            'current' : 'true' if msgtrig['value']   else 'false'})
                else : mess.add_data({'device' : msgtrig['device'],  
                            'type' : msgtrig['type'] ,
                            'current' : msgtrig['value'] })
            if msgtrig.has_key('units') and msgtrig['units'] !='' : mess.add_data({'units' : msgtrig['units'] })
            print mess
            self.myxpl.send(mess)
        elif 'command' in msgtrig and msgtrig['command'] == 'Info':
            print("Home ID is %s" % msgtrig['Home ID'])
Esempio n. 31
0
class GAgendaListener(XplPlugin):
    """ Listen for xPL messages to get infos from agenda
    """
    def __init__(self):
        """ Create lister for google agenda requets
        """
        XplPlugin.__init__(self, name='gagenda')

        # Create logger
        self.log.debug("Listener for Google agenda created")

        # Get config
        self._config = Query(self.myxpl, self.log)
        self._email = self._config.query('gagenda', 'email')
        self._password = self._config.query('gagenda', 'password')
        self._calendar_name = self._config.query('gagenda', 'calendarname')

        # Create object
        self._gagenda_manager = GAgenda(self.log, \
                                       self._email, \
                                       self._password, \
                                       self._calendar_name, \
                                       self._broadcast_events)

        # Create listener for today
        Listener(
            self.gagenda_cb, self.myxpl, {
                'schema': 'calendar.request',
                'xpltype': 'xpl-cmnd',
                'command': 'REQUEST'
            })
        self.enable_hbeat()

    def gagenda_cb(self, message):
        """ Call google agenda lib
            @param message : xlp message received
        """
        self.log.debug("Call gagenda_cb")
        if 'command' in message.data:
            command = message.data['command']
        if 'date' in message.data:
            date = message.data['date']

        # if it is a request command
        if command == "REQUEST":
            self.log.debug("Google agende request command received for " + \
                            str(date))
            if date == "TODAY":
                self._gagenda_manager.get_today_events()
            elif date == "TOMORROW":
                self._gagenda_manager.get_tomorrow_events()
            else:
                self._gagenda_manager.get_events_at_date(date)

    def _broadcast_events(self, events):
        """ Send xPL message on network
            @param events : list of events
        """
        for entry in events:
            my_temp_message = XplMessage()
            my_temp_message.set_type("xpl-trig")
            my_temp_message.set_schema("calendar.basic")
            print("entry = ")
            print(entry)
            my_temp_message.add_data({"object": entry["object"]})
            my_temp_message.add_data({"startdate": entry["startdate"]})
            self.myxpl.send(my_temp_message)
Esempio n. 32
0
class Proxy(XplPlugin):
    """ REST Proxy
        - create a HTTP server
        - process REST proxy requests
    """

    def __init__(self, proxy_ip, proxy_port):
        """
        Initiate properties
        Then, start HTTP server and give it initialized data
        @param proxy_ip :  ip of the proxy server
        @param proxy_port :  port of proxy server
        """

        XplPlugin.__init__(self, name = 'proxy',
            reload_cb = self.reload_config)
        # logging initialization
        self.log.info("Proxy initialisation ...")
        self.log.debug("locale : %s %s" % locale.getdefaultlocale())
        self._config = Query(self.myxpl, self.log)
        self.server = None
        self.server_process = None
        self.proxy_ip = None
        self.proxy_port = None
        self.use_ssl = False
        self.ssl_certificate = None
        self.server_ip = None
        self.server_port = None
        self.auth_method = None
        self.username = None
        self.password = None
        self.add_stop_cb(self.stop_http)
        self.enable_hbeat()
        self.reload_config()
        #self.log.info("Proxy initialisation done")

    def reload_config(self):
        '''
        Load configuration an start proxy server
        '''
        if self.server != None:
            self.stop_http()
            self.server = None
            self.server_process = None
        try:
            cfg_rest = Loader('rest')
            config_rest = cfg_rest.load()
            conf_rest = dict(config_rest[1])
            self.server_ip = conf_rest['rest_server_ip']
            self.server_port = conf_rest['rest_server_port']
        except KeyError:
            self.log.error("Can't retrieve REST configuration from domogik.cfg. Leave plugin.")
            self.force_leave()
        try:
            self.proxy_ip = self._config.query('proxy', 'proxy-ip')
            self.proxy_port = self._config.query('proxy', 'proxy-port')
        except:
            self.log.warning("Can't get proxy address configuration from XPL. Use default value.")
        finally:
            if self.proxy_ip == None:
                self.proxy_ip = self.server_ip
            try :
                self.proxy_port = int(self.proxy_port)
            except:
                self.proxy_port = str(int(self.server_port)+1)
        try:
            self.auth_method = self._config.query('proxy', 'auth-method')
        except:
            self.log.warning("Can't get authentification method from XPL. Use basic by default.")
        finally:
            if self.auth_method == None:
                self.auth_method = "basic"
        try:
            self.username = self._config.query('proxy', 'username')
            self.password = self._config.query('proxy', 'password')
        except:
            self.log.warning("Can't get username/password from XPL. Use defaults.")
        finally:
            if self.username == None or self.username == "None" :
                self.username = "******"
            if self.password == None or self.password == "None" :
                self.password = "******"
        try:
            boo = self._config.query('proxy', 'use-ssl')
            #print boo
            self.use_ssl = True if boo == "True" else False
            if self.use_ssl:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.ssl_certificate = conf_rest['rest_ssl_certificate']
        except KeyError:
            self.log.warning("Can't get ssl configuration from XPL. Do not use it.")
            self.use_ssl = False
            self.ssl_certificate = None
        self.log.info("Proxy configuration  : ip:port = %s:%s" % (self.proxy_ip, self.proxy_port))
        if self.use_ssl == True:
            self.log.info("Proxy configuration : SSL support activated (certificate : %s)" % self.ssl_certificate)
        else:
            self.log.info("Proxy configuration : SSL support not activated")
        self.log.info("Proxy authentification  : %s" % (self.auth_method))
        self.log.info("Rest configuration : ip:port = %s:%s" % (self.server_ip, self.server_port))
        try:
            self.start_http()
        except :
            self.log.error("Can't start proxy. Leave plugin.")
            self.log.error("%s" % str(traceback.format_exc()).replace('"', "'"))
            self.force_leave()

    def start_http(self):
        """
        Start HTTP proxy
        """
        # Start HTTP proxy
        self.log.info("Start HTTP proxy on %s:%s..." % (self.proxy_ip, self.proxy_port))
        if self.use_ssl:
            self.server = HTTPSServerWithParam((self.proxy_ip, int(self.proxy_port)), \
                                            (self.server_ip, int(self.server_port)), \
                                            self.get_stop(), self.log, self.auth_method, \
                                            self.username, self.password, \
                                            ProxyHandler, bind_and_activate=True, handler_params = [self])
        else:
            self.server = HTTPServerWithParam((self.proxy_ip, int(self.proxy_port)), \
                                            (self.server_ip, int(self.server_port)), \
                                            self.get_stop(), self.log, self.auth_method, \
                                            self.username, self.password, \
                                            ProxyHandler, bind_and_activate=True, handler_params = [self])
        self.server.serve_forever()
        #self.log.info("HTTP proxy started.")
        #self.server.server_bind()
        #self.server.server_activate()
        #self.server_process = threading.Thread(None,
        #                    self.server.serve_forever(),
        #                    "rest_proxy",
        #                    (),
        #                    {})
        #self.log.info("HTTP proxy started.")
        #self.server_process.start()

    def stop_http(self):
        """
        Stop HTTP proxy
        """
        if self.server != None:
            self.server.stop_handling()
Esempio n. 33
0
class PlcBusMain(XplPlugin):
    ''' Manage PLCBus technology, send and receive order/state
    '''

    def __init__(self):
        '''
        Create the plcbusMain class
        This class is used to connect PLCBUS to the xPL Network
        '''
        # Load config
        XplPlugin.__init__(self, name = 'plcbus')
        # Create listeners
        Listener(self._plcbus_cmnd_cb, self.myxpl, {
            'schema': 'plcbus.basic',
            'xpltype': 'xpl-cmnd',
        })
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('plcbus', 'device')
        self._usercode = self._config.query('plcbus', 'usercode')
        self._probe_inter = int( self._config.query('plcbus', 'probe-interval'))
        self._probe_list = self._config.query('plcbus', 'probe-list')

        # Create log instance
        self.api = PLCBUSAPI(self.log, device, self._command_cb, self._message_cb)
        self.add_stop_cb(self.api.stop)
        if self._probe_inter == 0:
            self.log.warning("The probe interval has been set to 0. This is not correct. The plugin will use a probe interval of 5 seconds")
            self._probe_inter = 5 
        self._probe_status = {}
        self._probe_thr = XplTimer(self._probe_inter, self._send_probe, self.myxpl)
        self._probe_thr.start()
#       self.register_timer(self._probe_thr)
        self.enable_hbeat()

    def _send_probe(self):
        """ Send probe message 

        """
        for h in self._probe_list:
            self.log.debug("send get_all_id")
            self.api.send("GET_ALL_ID_PULSE", h, self._usercode, 0, 0)
            time.sleep(1)
            self.log.debug("send get_all_on_id")
            self.api.send("GET_ALL_ON_ID_PULSE", h, self._usercode, 0, 0)
            time.sleep(1)

    def _plcbus_cmnd_cb(self, message):
        '''
        General callback for all command messages
        '''
        cmd = None
        dev = None
        user = '******'
        level = 0
        rate = 0
        if 'command' in message.data:
            cmd = message.data['command']
        if 'device' in message.data:
            dev = message.data['device'].upper()
        if 'usercode' in message.data:
            user = message.data['usercode']
        else:
            user = self._usercode
        if 'data1' in message.data:
            level = message.data['data1']
        if 'data2' in message.data:
            rate = message.data['data2']
        self.log.debug("%s received : device = %s, user code = %s, level = "\
                "%s, rate = %s" % (cmd.upper(), dev, user, level, rate))
#        if cmd == 'GET_ALL_ON_ID_PULSE':
#            self.api.get_all_on_id(user, dev)
#        else:
        self.api.send(cmd.upper(), dev, user, level, rate)
#       Workaround to send an ON command when dimmer = 0
        if cmd == 'PRESET_DIM' and level == 0:
            print("cmd : %s " % cmd)
            print("level : %s " % level)     
            self.api.send("OFF", dev, user)

        if cmd == 'PRESET_DIM' and level != 0:
            print('WORKAROUD : on fait suivre le DIM d un ON pour garder les widgets switch allumes')
            print("DEBUG cmd : %s " % cmd)
            print("DEBUG level : %s " % level)
            self.api.send("ON", dev, user)


    def _command_cb(self, f):
        ''' Called by the plcbus library when a command has been sent.
        If the commands need an ack, this callback will be called only after the ACK has been received
        @param : plcbus frame as an array
        '''
        if f["d_command"] == "GET_ALL_ID_PULSE":
            data = int("%s%s" % (f["d_data1"], f["d_data2"]))
            house = f["d_home_unit"][0]
            for i in range(0,16):
                unit = data >> i & 1
                code = "%s%s" % (house, i+1)
                if unit and not code in self._probe_status:
                    self._probe_status[code] = ""
                    self.log.info("New device discovered : %s" % code)
                elif (not unit) and code in self._probe_status:
                    del self._probe_status[code]
        elif f["d_command"] == "GET_ALL_ON_ID_PULSE":
            data = "%s%s" % (bin(f["d_data1"])[2:].zfill(8), bin(f["d_data2"])[2:].zfill(8))
            print("f : %s" % f)
            print("data : %s" % data)
            house = f["d_home_unit"][0]
            item = 16
            for c in data:
                unit=int(c)
                code = "%s%s" % (house, item)
                print("Etat : %s " % code, unit)
                if code in self._probe_status and (self._probe_status[code] != str(unit)):
                    print('DEBUG in rentre dans le IF detection GET_ALL_ON')
                    self._probe_status[code] = str(unit)
                    if unit == 1:
                        command = "ON"
                    else:
                        command ="OFF"
                    mess = XplMessage()
                    mess.set_type('xpl-trig')
                    mess.set_schema('plcbus.basic')
                    mess.add_data({"usercode" : f["d_user_code"], "device": code,
                                   "command": command})
                    self.myxpl.send(mess)
                item = item - 1
        else:
            mess = XplMessage()
            mess.set_type('xpl-trig')
            mess.set_schema('plcbus.basic')
            mess.add_data({"usercode" : f["d_user_code"], "device": f["d_home_unit"],
                           "command": f["d_command"], "data1": f["d_data1"], "data2": f["d_data2"]})
            self.myxpl.send(mess)

#           Workaround to for switch widget go ON when dimmer is send
#        if f["d_command"] == 'PRESET_DIM' and f["d_data1"] != 0 : 
#            print('WORKAROUD : on fait suivre le DIM d un ON pour garder les widgets switch allumes')
            #print("data1 : %s " % f["d_data1"])
#            mess = XplMessage()
#            mess.set_type('xpl-stat')
#            mess.set_schema('plcbus.basic')
#            mess.add_data({"usercode" : f["d_user_code"], "device": f["d_home_unit"], "command": 'ON'})
#            self.myxpl.send(mess)

    def _message_cb(self, message):
        print("Message : %s " % message)
Esempio n. 34
0
class NBZNotificationListener(XplPlugin):
    """ Create listener for xPL messages about Nabaztag TTS notification
    """
    def __init__(self):
        """ Create listener for Nabaztag TTS notification
        """
        XplPlugin.__init__(self, name='nbz_tts')
        # Create logger
        self.log.debug("Listener for Nabaztag TTS notification created")

        # Configuration : list of nabaztag whith serial, token and voice
        self.alias_list = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            nabaztag = self._config.query('nbz_tts', 'name-%s' % str(num))
            serial = self._config.query('nbz_tts', 'serial-%s' % str(num))
            token = self._config.query('nbz_tts', 'token-%s' % str(num))
            voice = self._config.query('nbz_tts', 'voice-%s' % str(num))
            if nabaztag != None:
                mess = "Configuration : nabaztag=" + str(
                    nabaztag) + " , serial=" + str(serial) + ", token=" + str(
                        token) + ", voice=" + str(voice)
                self.log.info(mess)
                print(mess)
                self.alias_list[nabaztag] = {
                    "nabaztag": nabaztag,
                    "serial": serial,
                    "token": token,
                    "voice": voice
                }
                num += 1
            else:
                loop = False

        # no nabaztag configured
        if num == 1:
            msg = "No nabaztag configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        # Check serial
        for alias in self.alias_list:
            if str(self.alias_list[alias]['serial']) != "None":
                self.log.debug("Serial for nabaztag " +
                               str(self.alias_list[alias]['nabaztag']) +
                               " is " + str(self.alias_list[alias]['serial']))
            else:
                self.log.error(
                    "Can't find the serial for the nabaztag " +
                    str(self.alias_list[alias]['nabaztag']) +
                    " , please check the configuration page of this plugin")
                self.force_leave()
                return

        # Check token
        for alias in self.alias_list:
            if str(self.alias_list[alias]['token']) != "None":
                self.log.debug("Token for nabaztag " +
                               str(self.alias_list[alias]['nabaztag']) +
                               " is " + str(self.alias_list[alias]['token']))
            else:
                self.log.error(
                    "Can't find the Token for the nabaztag " +
                    str(self.alias_list[alias]['nabaztag']) +
                    " , please check the configuration page of this plugin")
                self.force_leave()
                return

        # Check voice
        for alias in self.alias_list:
            if str(self.alias_list[alias]['voice']) != "None":
                self.log.debug("Voice for nabaztag " +
                               str(self.alias_list[alias]['nabaztag']) +
                               " is " + str(self.alias_list[alias]['voice']))
            else:
                self.log.error(
                    "Can't find the Voice for the nabaztag " +
                    str(self.alias_list[alias]['nabaztag']) +
                    " , please check the configuration page of this plugin")
                self.force_leave()
                return

        # Create NBZNotification object
        self.nbz_notification_manager = NBZNotification(self.log)

        # Create listeners
        Listener(self.nbz_notification_cb, self.myxpl, {
            'schema': 'sendmsg.push',
            'xpltype': 'xpl-cmnd'
        })
        self.enable_hbeat()

    def nbz_notification_cb(self, message):
        """ Call Nabaztag TTS lib
            @param message : message to send
        """
        self.log.debug("Call nbz_notification_cb")

        # mandatory keys
        if 'to' in message.data:
            to = message.data['to']
            for alias in self.alias_list:
                try:
                    if str(self.alias_list[alias]['nabaztag']) == str(to):
                        serialkey = self.alias_list[alias]['serial']
                        tokenkey = self.alias_list[alias]['token']
                        voicekey = self.alias_list[alias]['voice']
                except:
                    self.log.debug(
                        "Can't find the recipient, please check the configuration page of this plugin"
                    )
                    self.force_leave()
                    return
        else:
            self.log.warning("No recipient was found in the xpl message")
            return

        if 'body' in message.data:
            body = message.data['body']
        else:
            self.log.warning("No message was found in the xpl message")
            return

        self.log.debug("Call send_tts with following parameters : serial=" +
                       serialkey + ", token=" + tokenkey + ", message=" +
                       body + ", voice=" + voicekey)
        self.nbz_notification_manager.send_tts(serialkey, tokenkey, body,
                                               voicekey)
Esempio n. 35
0
class Rest(XplPlugin):
    """ REST Server 
        - create a HTTP server 
        - process REST requests
    """
    def __init__(self, server_ip, server_port):
        """ Initiate DbHelper, Logs and config
            Then, start HTTP server and give it initialized data
            @param server_ip :  ip of HTTP server
            @param server_port :  port of HTTP server
        """

        XplPlugin.__init__(self, name='rest')
        # logging initialization
        self.log.info("Rest Server initialisation...")
        self.log.debug("locale : %s %s" % locale.getdefaultlocale())

        # logging Queue activities
        log_queue = logger.Logger('rest-queues')
        self.log_queue = log_queue.get_logger('rest-queues')
        self.log_queue.info("Rest's queues activities...")

        # logging data manipulation initialization
        log_dm = logger.Logger('rest-dm')
        self.log_dm = log_dm.get_logger('rest-dm')
        self.log_dm.info("Rest Server Data Manipulation...")

        # API version
        self._rest_api_version = REST_API_VERSION

        # Hosts list
        self._hosts_list = {
            self.get_sanitized_hostname(): {
                "id": self.get_sanitized_hostname(),
                "status": "on",
                "primary": True,
                "last_seen": time.time(),
                "ip": "",
                "interval": "1"
            }
        }

        try:

            ### Config

            # directory data
            cfg = Loader('domogik')
            config = cfg.load()
            conf = dict(config[1])
            self.log_dir_path = conf['log_dir_path']

            # plugin installation path
            if conf.has_key('package_path'):
                self._package_path = conf['package_path']
                self._src_prefix = None
                self.log.info("Set package path to '%s' " % self._package_path)
                print("Set package path to '%s' " % self._package_path)
                self._design_dir = "%s/domogik_packages/design/" % self._package_path
                self.package_mode = True
            else:
                self.log.info("No package path defined in config file")
                self._package_path = None
                self._src_prefix = conf['src_prefix']
                self._design_dir = "%s/share/domogik/design/" % conf[
                    'src_prefix']
                self.package_mode = False

            # HTTP server ip and port
            try:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.server_ip = conf_rest['rest_server_ip']
                self.server_port = conf_rest['rest_server_port']
            except KeyError:
                # default parameters
                self.server_ip = server_ip
                self.server_port = server_port
            self.log.info("Configuration : ip:port = %s:%s" %
                          (self.server_ip, self.server_port))

            # SSL configuration
            try:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.use_ssl = conf_rest['rest_use_ssl']
                if self.use_ssl == "True":
                    self.use_ssl = True
                else:
                    self.use_ssl = False
                self.ssl_certificate = conf_rest['rest_ssl_certificate']
            except KeyError:
                # default parameters
                self.use_ssl = USE_SSL
                self.ssl_certificate = SSL_CERTIFICATE
            if self.use_ssl == True:
                self.log.info(
                    "Configuration : SSL support activated (certificate : %s)"
                    % self.ssl_certificate)
            else:
                self.log.info("Configuration : SSL support not activated")

            # File repository
            try:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.repo_dir = conf_rest['rest_repository']
            except KeyError:
                # default parameters
                self.repo_dir = DEFAULT_REPO_DIR

            # Gloal Queues config
            self.log.debug("Get queues configuration")
            self._config = Query(self.myxpl, self.log)

            self._queue_timeout = self._config.query('rest', 'q-timeout')
            if self._queue_timeout == None:
                self._queue_timeout = QUEUE_TIMEOUT
            self._queue_timeout = float(self._queue_timeout)

            self._queue_package_size = self._config.query('rest', 'q-pkg-size')
            if self._queue_package_size == None:
                self._queue_package_size = QUEUE_PACKAGE_SIZE
            self._queue_package_size = float(self._queue_package_size)

            self._queue_size = self._config.query('rest', 'q-size')
            if self._queue_size == None:
                self._queue_size = QUEUE_SIZE
            self._queue_size = float(self._queue_size)

            self._queue_life_expectancy = self._config.query(
                'rest', 'q-life-exp')
            if self._queue_life_expectancy == None:
                self._queue_life_expectancy = QUEUE_LIFE_EXPECTANCY
            self._queue_life_expectancy = float(self._queue_life_expectancy)

            self._queue_sleep = self._config.query('rest', 'q-sleep')
            if self._queue_sleep == None:
                self._queue_sleep = QUEUE_SLEEP
            self._queue_sleep = float(self._queue_sleep)

            # /command Queues config
            self._queue_command_size = self._config.query('rest', 'q-cmd-size')
            if self._queue_command_size == None:
                self._queue_command_size = QUEUE_COMMAND_SIZE
            self._queue_command_size = float(self._queue_command_size)

            # /event Queues config
            self._event_timeout = self._config.query('rest', 'evt-timeout')
            if self._event_timeout == None:
                self._event_timeout = EVENT_TIMEOUT
            self._event_timeout = float(self._event_timeout)

            self._queue_event_size = self._config.query('rest', 'q-evt-size')
            if self._queue_event_size == None:
                self._queue_event_size = QUEUE_EVENT_SIZE
            self._queue_event_size = float(self._queue_event_size)

            self._queue_event_timeout = self._config.query(
                'rest', 'q-evt-timeout')
            if self._queue_event_timeout == None:
                self._queue_event_timeout = QUEUE_EVENT_TIMEOUT
            self._queue_event_timeout = float(self._queue_event_timeout)

            self._queue_event_life_expectancy = self._config.query(
                'rest', 'q-evt-life-exp')
            if self._queue_event_life_expectancy == None:
                self._queue_event_life_expectancy = QUEUE_EVENT_LIFE_EXPECTANCY
            self._queue_event_life_expectancy = float(
                self._queue_event_life_expectancy)

            # Queues for xPL
            # Queues for packages management
            self._queue_package = Queue(self._queue_package_size)

            # Queues for domogik system actions
            self._queue_system_list = Queue(self._queue_size)
            self._queue_system_detail = Queue(self._queue_size)
            self._queue_system_start = Queue(self._queue_size)
            self._queue_system_stop = Queue(self._queue_size)

            # Queues for /command
            self._queue_command = Queue(self._queue_command_size)

            # Queues for /events/domogik
            self._queue_event_dmg = Queue(self._queue_event_size)

            # Queues for /events/request
            # this queue will be fill by stat manager
            self._event_requests = RequestEvents(
                self.get_stop, self.log, self._event_timeout,
                self._queue_event_size, self._queue_event_timeout,
                self._queue_event_life_expectancy)
            self.add_stop_cb(self._event_requests.set_stop_clean)

            # Queues for /events/domogik
            # this queue will be fill by stat manager
            self._event_dmg = DmgEvents(self.get_stop, self.log,
                                        self._event_timeout,
                                        self._queue_event_size,
                                        self._queue_event_timeout,
                                        self._queue_event_life_expectancy)
            # notice : adding data in queue is made in _add_to_queue_system_list
            self.add_stop_cb(self._event_dmg.set_stop_clean)

            # define listeners for queues
            self.log.debug("Create listeners")
            if self.package_mode == True:
                Listener(self._list_installed_packages, self.myxpl, \
                         {'schema': 'domogik.package',
                          'xpltype': 'xpl-trig',
                          'command' : 'installed-packages-list'})
            Listener(self._add_to_queue_package, self.myxpl, \
                     {'schema': 'domogik.package',
                      'xpltype': 'xpl-trig'})
            Listener(self._add_to_queue_system_list, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'list'})
            Listener(self._add_to_queue_system_list, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'enable'})
            Listener(self._add_to_queue_system_list, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'disable'})
            Listener(self._add_to_queue_system_detail, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'detail'})
            Listener(self._add_to_queue_system_start, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'start'})
            Listener(self._add_to_queue_system_stop, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'stop'})
            Listener(self._add_to_queue_command, self.myxpl, \
                     {'xpltype': 'xpl-trig'})

            # Listener for hosts list
            Listener(self._list_hosts, self.myxpl, \
                     {'schema': 'hbeat.app',
                      'xpltype': 'xpl-stat'})

            # Background process to check if hosts has disappeared
            thr_hbeat = XplTimer(10, \
                                 self._refresh_status_for_list_hosts, \
                                 self.myxpl)
            thr_hbeat.start()

            self._discover_hosts()

            # Enable hbeat
            self.enable_hbeat()

            # Ask for installed packages on all hosts
            # Semaphore init for installed package list update
            self.sema_installed = Semaphore(value=1)
            self._installed_packages = {}
            if self.package_mode == True:
                self._get_installed_packages_from_manager()

            # Launch server, stats
            self.log.info("REST Initialisation OK")
            self.add_stop_cb(self.stop_http)
            self.server = None
            self.start_stats()

            self.start_http()
        except:
            self.log.error("%s" % self.get_exception())

    def _add_to_queue_package(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_package, message)

    def _add_to_queue_system_list(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_list, message)
        current_date = calendar.timegm(time.gmtime())
        self._event_dmg.add_in_queues({
            "timestamp": current_date,
            "data": "plugin-list-updated"
        })

    def _add_to_queue_system_detail(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_detail, message)

    def _add_to_queue_system_start(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_start, message)

    def _add_to_queue_system_stop(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_stop, message)

    def _add_to_queue_command(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_command, message)

    def _get_from_queue(self,
                        my_queue,
                        filter_type=None,
                        filter_schema=None,
                        filter_data=None,
                        nb_rec=0,
                        timeout=None):
        """ Encapsulation for _get_from_queue_in
            If timeout not elapsed and _get_from_queue didn't find a valid data
            call again _get_from_queue until timeout
            This encapsulation is used to process case where queue is not empty but there is
            no valid data in it and we want to wait for timeout
        """
        if timeout == None:
            timeout = self._queue_timeout
        start_time = time.time()
        while time.time() - start_time < timeout:
            try:
                return self._get_from_queue_without_waiting(
                    my_queue, filter_type, filter_schema, filter_data, nb_rec,
                    timeout)
            except Empty:
                # no data in queue for us.... let's continue until time elapsed
                # in order not rest not working so much, let it make a pause
                time.sleep(self._queue_sleep)
        # time elapsed... we can raise the Empty exception
        raise Empty

    def _get_from_queue_without_waiting(self,
                                        my_queue,
                                        filter_type=None,
                                        filter_schema=None,
                                        filter_data=None,
                                        nb_rec=0,
                                        timeout=None):
        """ Get an item from queue (recursive function)
            Checks are made on : 
            - life expectancy of message
            - filter given
            - size of queue
            If necessary, each item of queue is read.
            @param my_queue : queue to get data from
            @param filter_type : filter on a schema type
            @param filter_schema : filter on a specific schema
            @param filter_data : dictionnay of filters. Examples :
                - {"command" : "start", ...}
                - {"plugin" : "wol%", ...} : here "%" indicate that we search for something starting with "wol"
            @param nb_rec : internal parameter (do not use it for first call). Used to check recursivity VS queue size
            @param timeout : to use a different timeout from default one
        """
        if timeout == None:
            timeout = self._queue_timeout
        self.log_queue.debug("Get from queue : %s (recursivity deepth : %s)" %
                             (str(my_queue), nb_rec))
        # check if recursivity doesn't exceed queue size
        if nb_rec > my_queue.qsize():
            self.log_queue.warning(
                "Get from queue %s : number of call exceed queue size (%s) : return None"
                % (str(my_queue), my_queue.qsize()))
            # we raise an "Empty" exception because we consider that if we don't find
            # the good data, it is as if it was "empty"
            raise Empty

        msg_time, message = my_queue.get(True, timeout)

        # if message not too old, we process it
        if time.time() - msg_time < self._queue_life_expectancy:
            # no filter defined
            if filter_type == None and filter_schema == None and filter_data == None:
                self.log_queue.debug("Get from queue %s : return %s" %
                                     (str(my_queue), str(message)))
                return message

            # we want to filter data
            else:
                keep_data = True
                if filter_type != None and filter_type.lower(
                ) != message.type.lower():
                    keep_data = False
                if filter_schema != None and filter_schema.lower(
                ) != message.schema.lower():
                    keep_data = False

                if filter_data != None and keep_data == True:
                    # data
                    self.log_queue.debug("Filter on message %s WITH %s" %
                                         (message.data, filter_data))
                    for key in filter_data:
                        # take care of final "%" in order to search data starting by filter_data[key]
                        if filter_data[key][-1] == "%":
                            if message.data.has_key(key):
                                msg_data = str(message.data[key])
                                my_filter_data = str(filter_data[key])
                                len_data = len(my_filter_data) - 1
                                if msg_data[0:len_data] != my_filter_data[0:-1]:
                                    keep_data = False
                            else:
                                keep_data = False
                        # normal search
                        else:
                            if message.data.has_key(key):
                                if message.data[key].lower(
                                ) != filter_data[key].lower():
                                    keep_data = False
                            else:
                                keep_data = False

                # if message is ok for us, return it
                if keep_data == True:
                    self.log_queue.debug("Get from queue %s : return %s" %
                                         (str(my_queue), str(message)))
                    return message

                # else, message get back in queue and get another one
                else:
                    self.log_queue.debug(
                        "Get from queue %s : bad data, check another one..." %
                        (str(my_queue)))
                    self._put_in_queue(my_queue, message)
                    return self._get_from_queue_without_waiting(
                        my_queue, filter_type, filter_schema, filter_data,
                        nb_rec + 1, timeout)

        # if message too old : get an other message
        else:
            self.log_queue.debug(
                "Get from queue %s : data too old, check another one..." %
                (str(my_queue)))
            return self._get_from_queue_without_waiting(
                my_queue, filter_type, filter_schema, filter_data, nb_rec + 1,
                timeout)

    def _put_in_queue(self, my_queue, message):
        """ put a message in a named queue
            @param my_queue : queue 
            @param message : data to put in queue
        """
        self.log_queue.debug("Put in queue %s : %s" %
                             (str(my_queue), str(message)))
        try:
            my_queue.put((time.time(), message), True, self._queue_timeout)

        # Clean queue to make space
        except Full:
            msg = "Queue '%s' is full : cleaning it to make some space..." % my_queue
            self.log_queue.debug(msg)
            print(msg)
            # queue is full : start cleaning it
            nb_ck = 0
            while nb_ck < my_queue.qsize():
                (q_time, q_data) = my_queue.get()
                # data to keep
                if time.time() - self._queue_life_expectancy < q_time:
                    my_queue.put((q_time, q_data), True, self._queue_timeout)
                nb_ck += 1
            my_queue.put((time.time(), message), True, self._queue_timeout)
            self.log_queue.debug("Cleaning finished")

    def _discover_hosts(self):
        """ Send a hbeat.request to discover managers
        """
        mess = XplMessage()
        mess.set_type('xpl-cmnd')
        mess.set_target("*")
        mess.set_schema('hbeat.request')
        mess.add_data({'command': 'request'})
        self.myxpl.send(mess)

    def _list_hosts(self, message):
        """ Maintain list of Domogik hosts
            @param message : hbeat.app xpl message
        """
        tmp1 = message.source.split(".")
        tmp2 = tmp1[0].split("-")
        vendor = tmp2[0]
        device = tmp2[1]
        instance = tmp1[1]
        if vendor == "domogik" and device == "manager":
            # host not in the list
            if self._hosts_list.has_key(instance) == False:
                self._hosts_list[instance] = {"primary": False}
            self._hosts_list[instance]["status"] = "on"
            self._hosts_list[instance]["last_seen"] = time.time()
            self._hosts_list[instance]["interval"] = 60 * int(
                message.data["interval"])
            self._hosts_list[instance]["ip"] = message.data["remote-ip"]
            self._hosts_list[instance]["id"] = instance

    def _refresh_status_for_list_hosts(self):
        """ Check if hosts has disappeared
        """
        now = time.time()
        for instance in self._hosts_list:
            if (now - self._hosts_list[instance]["last_seen"] >
                    self._hosts_list[instance]["interval"]):
                self._hosts_list[instance]["status"] = "off"

    def _get_installed_packages_from_manager(self):
        """ Send a xpl message to all managers to get installed packages list
        """

        ### Send xpl message to get list
        message = XplMessage()
        message.set_type("xpl-cmnd")
        message.set_schema("domogik.package")
        message.add_data({"command": "installed-packages-list"})
        message.add_data({"host": "*"})
        self.myxpl.send(message)

    def get_installed_packages(self):
        """ return list of installed packages
            There is a semaphore in order not to return the list when it is
            updated (may be incomplete)
        """
        # developper mode : all plugins are installed

        # TODO : remove log lines after tests
        self.log.debug("*** get_installed_packages")
        self.sema_installed.acquire()
        self.log.debug("*** sema acquired")
        ret = self._installed_packages
        self.sema_installed.release()
        self.log.debug("*** sema released")
        return ret

    def _list_installed_packages(self, message):
        """ Called when a list of installed packages is received
            @param host : host
            @param pkg_type : type of package
        """
        print("Get new installed packages list")
        self.log.debug("Get new installed packages list")
        self.sema_installed.acquire()
        self.log.debug("*** sema acquired")
        self.log.debug("*** msg = %s" % message)
        # process message
        host = message.data["host"]
        self._installed_packages[host] = {}

        pkg_mgr = PackageManager()
        idx = 0
        loop_again = True
        self.log.debug("*** before while")
        while loop_again:
            try:
                self.log.debug("*** in while : idx=%s" % idx)
                pkg_type = message.data["type" + str(idx)]
                if message.data["enabled" + str(idx)].lower() == "yes":
                    enabled = True
                else:
                    enabled = False
                data = {
                    "fullname": message.data["fullname" + str(idx)],
                    "id": message.data["id" + str(idx)],
                    "version": message.data["version" + str(idx)],
                    "type": message.data["type" + str(idx)],
                    #"source" : message.data["source"+str(idx)],
                    "enabled": enabled
                }
                self.log.debug("*** call get_available_updates(%s, %s, %s)" %
                               (data["type"], data["id"], data["version"]))
                updates = pkg_mgr.get_available_updates(
                    data["type"], data["id"], data["version"])
                self.log.debug("*** after get_available_updates")
                data["updates"] = updates
                if self._installed_packages[host].has_key(pkg_type) == False:
                    self._installed_packages[host][pkg_type] = []
                self._installed_packages[host][pkg_type].append(data)
                self.log.debug("*** before idx += 1")
                idx += 1
            except KeyError:
                self.log.debug("*** except keyerror")
                loop_again = False
            except:
                self.log.debug("*** except global")
                self.log.error(
                    "Error while creating list of installed packages : %s" %
                    traceback.format_exc())
                loop_again = False
        self.log.debug("*** before release")
        self.sema_installed.release()
        self.log.debug("*** sema released")

    def start_http(self):
        """ Start HTTP Server
        """
        # Start HTTP server
        self.log.info("Start HTTP Server on %s:%s..." %
                      (self.server_ip, self.server_port))

        if self.use_ssl:
            self.server = HTTPSServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \
                                         handler_params = [self])
        else:
            self.server = HTTPServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \
                                         handler_params = [self])

        self.server.serve_forever()

    def stop_http(self):
        """ Stop HTTP Server
        """
        self.server.stop_handling()

    def start_stats(self):
        """ Start Statistics manager
        """
        print("Start Stats")
        self.log.info(
            "Starting statistics manager. Its logs will be in a dedicated log file"
        )
        self.stat_mgr = StatsManager(handler_params=[self], xpl=self.myxpl)
        self.stat_mgr.load()
        self.log.info("Stat manager started")

    def reload_stats(self):
        """ Reload Statistics manager
        """
        time.sleep(1)
        print("Reload Stats")
        self.log.info(
            "Reloading statistics manager. Its logs will be in a dedicated log file"
        )
        self.stat_mgr.load()

    def get_exception(self):
        """ Get exception and display it on stdout
        """
        my_exception = str(traceback.format_exc()).replace('"', "'")
        print("==== Error in REST ====")
        print(my_exception)
        print("=======================")
        return my_exception
Esempio n. 36
0
class DemoDataManager(XplPlugin):
    """ Sends demo data over xPL
    """

    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='demodata')

        ### Get config
        self._config = Query(self.myxpl, self.log)
        port = self._config.query('demodata', 'port')
        if port == None:
            port = DEFAULT_PORT 
        else:
            port = int(port)
        self.log.info("Listen port is %s" % port)

        self.log.info("Start creating the listeners")

        ### Create listeners for the fake actuator devices
        # RGB controller
        Listener(self.cmd_arduino_rgb, self.myxpl, {
            'schema': 'arduino.rgb',
            'xpltype': 'xpl-cmnd',
        })

        # Switch
        # Dimmer
        Listener(self.cmd_lighting_basic, self.myxpl, {
            'schema': 'lighting.basic',
            'xpltype': 'xpl-cmnd',
        })

        self.log.info("All listeners are created")

        ### Call the data creators
        self.log.info("Start all the data creator threads")
        demo = DemoData(self.log, self.send_sensor_basic, \
                                  self.send_teleinfo_basic)

        # weather data each minute
        self._weather_thr = XplTimer(60, \
                                     demo.weather_data, \
                                     self.myxpl)
        self._weather_thr.start()

        # teleinfo data each 10min
        self._teleinfo_thr = XplTimer(600, \
                                     demo.teleinfo_data, \
                                     self.myxpl)
        self._teleinfo_thr.start()

        # tank data each 1min
        self._tank_thr = XplTimer(60, \
                                  demo.tank_data, \
                                  self.myxpl)
        self._tank_thr.start()

        # water data each 1min
        self._water_thr = XplTimer(60, \
                                  demo.water_data, \
                                  self.myxpl)
        self._water_thr.start()

        self.log.info("All the data creator threads created")

        self.enable_hbeat()

        # Launch the web UI
        #demo_ui = DemoUI()
        msg = "Launch the Web UI on port %s" % port
        print(msg)
        self.log.info(msg)
        self.add_stop_cb(self.stop_http)
        self.server = None
        self.server_ip = ''
        self.server_port = port
        self.start_http()

    def start_http(self):
        """ Start HTTP Server
        """
        self.server = HTTPServerWithParam((self.server_ip, int(self.server_port)), UIHandler, \
                                         handler_params = [self])
        self.server.serve_forever()

    def stop_http(self):
        """ Stop HTTP Server
        """
        self.server.stop_handling()

    def send_sensor_basic(self, device, type, current, units = None):
        """ Send sensor.basic xPL schema
            @param device : device
            @param type : type
            @param current : current
        """
        mess = "sensor.basic { device=%s, type=%s, current=%s}" % (device, type, current)
        print(mess)
        self.log.debug(mess)
        if current == "":
            return
        msg = XplMessage()
        msg.set_type("xpl-stat")
        msg.set_schema("sensor.basic")
        msg.add_data({"device" : device})
        msg.add_data({"type" : type})
        msg.add_data({"current" : current})
        if units != None:
            msg.add_data({"units" : units})
        self.myxpl.send(msg)

    def send_teleinfo_basic(self, frame):
        ''' Send a frame from teleinfo device to xpl
        @param frame : a dictionnary mapping teleinfo informations
        '''
        mess = "teleinfo.basic : %s" % frame
        print(mess)
        self.log.debug(mess)
        msg = XplMessage()
        msg.set_type("xpl-stat")
        msg.set_schema("teleinfo.basic")
        for key in frame:
            msg.add_data({ key : frame[key] })
        self.myxpl.send(msg)

    # RGB controller
    def cmd_arduino_rgb(self, message):
        device = message.data['device']
        command = message.data['command']
        color = message.data['color']
        # send symetric answer to simulate the device
        self.send_arduino_rgb(device, command, color)

    def send_arduino_rgb(self, device, command, color):
        mess = "arduino.rgb : device=%s, command=%s, color=%s" % (device, command, color)
        print(mess)
        self.log.debug(mess)
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("arduino.rgb")
        msg.add_data({ 'device' : device })
        msg.add_data({ 'command' : command })
        msg.add_data({ 'color' : color })
        self.myxpl.send(msg)

    # Switch
    # Dimmer
    def cmd_lighting_basic(self, message):
        device = message.data['device']
        command = message.data['command']
        if message.data.has_key('fade-rate'):
            fade_rate = message.data['fade-rate']
        else: 
            fade_rate = None
        if message.data.has_key('level'):
            level = message.data['level']
        else: 
            level = None
        # send symetric answer to simulate the device
        self.send_lighting_device(device, command, level, fade_rate)

    def send_lighting_device(self, device, command, level = None, fade_rate = None):
        mess = "lighting.device : device=%s, command=%s, level=%s, fade_rate=%s" % (device, command, level, fade_rate)
        print(mess)
        self.log.debug(mess)
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("lighting.device")
        msg.add_data({ 'device' : device })
        if level != None:
            msg.add_data({ 'level' : level })
        if fade_rate != None:
            msg.add_data({ 'fade-rate' : fade_rate })
        self.myxpl.send(msg)

    # Caller id
    def send_cid_basic(self, device, calltype, phone_number):
        # Notice that device is not used in this xpl schema
        mess = "cid.basic : calltype=%s, phone=%s" % (calltype, phone_number)
        print(mess)
        self.log.debug(mess)
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema("cid.basic")
        msg.add_data({ 'calltype' : calltype })
        msg.add_data({ 'phone' : phone_number })
        self.myxpl.send(msg)
Esempio n. 37
0
class IPXManager(XplPlugin):
    """ Implements a listener for IPX command messages 
        and launch background listening for relay board status
    """
    def __init__(self):
        """ Create lister and launch bg listening
        """
        XplPlugin.__init__(self, name='ipx800')

        # Configuration : list of IPX800
        self.ipx_list = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            model = self._config.query('ipx800', 'model-%s' % str(num))
            login = self._config.query('ipx800', 'login-%s' % str(num))
            password = self._config.query('ipx800', 'password-%s' % str(num))
            name = self._config.query('ipx800', 'name-%s' % str(num))
            address = self._config.query('ipx800', 'ip-%s' % str(num))
            inter = self._config.query('ipx800', 'int-%s' % str(num))
            if name != None:
                self.log.info(
                    "Configuration : login=%s, password=***, name=%s, ip=%s, interval=%s"
                    % (login, name, address, inter))
                self.ipx_list[name] = {
                    "login": login,
                    "password": password,
                    "model": model,
                    "ip": address,
                    "interval": float(inter)
                }
                num += 1
            else:
                loop = False

        # no ipx configured
        if num == 1:
            msg = "No ipx800 board configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        ### Create IPX objects
        num_ok = 0
        for ipx in self.ipx_list:
            self.ipx_list[ipx]['obj'] = IPX(self.log, self.send_xpl,
                                            self.get_stop())
            try:
                self.log.info("Opening IPX800 named '%s' (ip : %s)" %
                              (ipx, self.ipx_list[ipx]['ip']))
                self.ipx_list[ipx]['obj'].open(ipx, self.ipx_list[ipx]['ip'],
                                               self.ipx_list[ipx]['model'],
                                               self.ipx_list[ipx]['login'],
                                               self.ipx_list[ipx]['password'])
            except:
                self.log.error("Error opening board '%s' : %s " %
                               (ipx, traceback.format_exc()))
                print("Error opening board '%s' : check logs" % ipx)
            else:
                num_ok += 1

        # no valid ipx800 board detected
        if num_ok == 0:
            msg = "No valid IPX800 board configured. Exiting plugin..."
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        ### Start listening each IPX800
        for ipx in self.ipx_list:
            try:
                self.log.info("Start listening to IPX800 named '%s'" % ipx)
                ipx_listen = threading.Thread(
                    None, self.ipx_list[ipx]['obj'].listen, "listen_ipx",
                    (self.ipx_list[ipx]['interval'], ), {})
                ipx_listen.start()
            except IPXException as err:
                self.log.error(err.value)
                print(err.value)
                # we don't quit plugin if an error occured
                # we can loose a board for a little time
                #self.force_leave()
                #return

        ### Create listeners for commands
        self.log.info("Creating listener for IPX 800")
        #Listener(self.ipx_command, self.myxpl, {'schema': 'control.basic',
        #        'xpltype': 'xpl-cmnd', 'type': ['output', 'count']})
        Listener(self.ipx_command, self.myxpl, {
            'schema': 'control.basic',
            'xpltype': 'xpl-cmnd',
            'type': 'output'
        })

        self.enable_hbeat()
        self.log.info("Plugin ready :)")

    def send_xpl(self, msg_device, msg_current, msg_type):
        """ Send xpl-trig to give status change
            @param msg_device : device
            @param msg_current : device's value
            @param msg_type : device's type
        """
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema('sensor.basic')
        msg.add_data({'device': msg_device})
        if msg_type != None:
            msg.add_data({'type': msg_type})
        msg.add_data({'current': msg_current})
        self.myxpl.send(msg)

    def ipx_command(self, message):
        """ Call ipx800 lib function in function of given xpl message
            @param message : xpl message
        """
        if 'device' in message.data:
            msg_device = message.data['device']
        if 'type' in message.data:
            msg_type = message.data['type'].lower()
        if 'current' in message.data:
            msg_current = message.data['current'].lower()

        data = "device=%s, type=%s, current=%s" % (msg_device, msg_type,
                                                   msg_current)
        print data
        data_name = msg_device.split("-")
        ipx_name = data_name[0]
        elt = data_name[1][0:-1]
        num = int(data_name[1][-1])

        if not ipx_name in self.ipx_list:
            self.log.warning("No IPX800 board called '%s' defined" % ipx_name)
            return

        # check data
        if elt == 'led' and msg_current not in ['high', 'low', 'pulse'] \
           and msg_type != 'output':
            self.log.warning("Bad data : %s" % data)
            return

        # TODO in a next release : other checks : counter

        # action in function of type
        if elt == 'led' and msg_type == 'output' and msg_current in [
                'high', 'low'
        ]:
            self.ipx_list[ipx_name]['obj'].set_relay(num, msg_current)
        elif elt == 'led' and msg_type == 'output' and msg_current == 'pulse':
            self.ipx_list[ipx_name]['obj'].pulse_relay(num)
Esempio n. 38
0
class Lighting(XplPlugin):
    '''
    Manage lighting schema over XPL
    '''
    def __init__(self):
        """
        Create the lighting class
        """
        XplPlugin.__init__(self, name = 'lighting')
        self.log.debug("lighting.__init__ : Start ...")
        self._config = Query(self.myxpl, self.log)

        self.log.debug("lighting.__init__ : Try to get configuration from XPL")
        try:
            #self.use_cron = bool(self._config.query('lighting', 'usecron'))
            self.broadcast = bool(self._config.query('lighting', 'broadcast'))
            #self.presence = bool(self._config.query('lighting', 'presence'))
        except:
            error = "Can't get configuration from XPL : %s" %  \
                     (traceback.format_exc())
            self.log.exception("lighting.__init__ : " + error)
            #self.use_cron = True
            self.broadcast = True
            #self.presence = True
            raise LightingException(error)

        self.log.debug("lighting.__init__ : Try to start the lighting librairy")
        try:
            self._mylighting = LightingAPI(self.broadcast, \
                self.myxpl, self.log, self.get_data_files_directory())
        except:
            error = "Something went wrong during lightingAPI init : %s" %  \
                     (traceback.format_exc())
            self.log.error("lighting.__init__ : "+error)
            self.force_leave()
            raise LightingException(error)

        self.log.debug("lighting.__init__ : Try to create listeners")
        Listener(self.lighting_config_cmnd, self.myxpl,
                 {'schema': 'lighting.config', 'xpltype': 'xpl-cmnd'})
        Listener(self.lighting_basic_cmnd, self.myxpl,
                 {'schema': 'lighting.basic', 'xpltype': 'xpl-cmnd'})
#        Listener(self.lighting_basic_trig, self.myxpl,
#                 {'schema': 'lighting.basic', 'xpltype': 'xpl-trig'})
        self.enable_hbeat()
        self._mylighting.reload_config()
        self.log.info("Plugin lighting correctly started.")

    def lighting_basic_trig(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("lighting_basic_trig() : Start ...")
        self._mylighting.basic_trig_listener(message)
        self.log.debug("lighting_basic_trig() : Done :)")

    def lighting_config_cmnd(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("lighting_config_cmnd() : Start ...")
        self._mylighting.config_cmnd_listener(message)
        self.log.debug("lighting_config_cmnd() : Done :)")

    def lighting_basic_cmnd(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("lighting_basic_cmnd() : Start ...")
        self._mylighting.basic_cmnd_listener(message)
        self.log.debug("lighting_basic_cmnd() : Done :)")
Esempio n. 39
0
class Telldus(XplHlpPlugin):
    '''
    Manage chacon devices through the TellStick device
    '''
    def __init__(self):
        """
        Create the telldus class
        This class is used to connect devices (through telldus) to
        the xPL Network
        """
        XplHlpPlugin.__init__(self,
                              name='telldus',
                              reload_cb=self.telldus_reload_config_cb)
        self.log.debug("telldus.__init__ : Start ...")
        self._device = "/dev/tellstick"
        #Check if the device exists
        if not os.path.exists(self._device):
            self.log.warning(self._device +
                             " is not present but Tellstick Duo don't use it.")
        else:
            self.log.debug("Device present as " + self._device)
        self._config = Query(self.myxpl, self.log)
        self.log.debug("telldus.__init__ : Try to load API")
        try:
            self._mytelldus = TelldusAPI(self, self.send_xpl, self.log,
                                         self._config,
                                         self.get_data_files_directory(),
                                         self.myxpl)
        except Exception:
            self.log.error("Something went wrong during telldus API init.")
            self.log.error("%s" % (traceback.format_exc()))
            self.force_leave()
            exit(1)
        self.add_stop_cb(self._mytelldus.unregister)
        self.log.debug("telldus.__init__ : Create listeners")
        Listener(self.telldus_cmnd_cb, self.myxpl, {
            'schema': 'telldus.basic',
            'xpltype': 'xpl-cmnd'
        })
        Listener(
            self.telldus_reload_config_cb, self.myxpl, {
                'schema': 'domogik.system',
                'xpltype': 'xpl-cmnd',
                'command': 'reload',
                'plugin': 'telldus'
            })
        self.enable_hbeat()
        try:
            boo = self._config.query('telldus', 'lightext')
            if boo == None:
                boo = "False"
            self.lightext = eval(boo)
        except:
            self.log.warning(
                "Can't get delay configuration from XPL. Disable lighting extensions."
            )
            self.lightext = False
        if self.lightext == True:
            self.log.debug(
                "telldus.__init__ : Try to load the lighting extension.")
            self.lighting = LightingExtension(self, self._name, \
                self._mytelldus.lighting_activate_device, \
                self._mytelldus.lighting_deactivate_device, \
                self._mytelldus.lighting_valid_device)
        self.helpers =   \
           { "list" :
              {
                "cb" : self._mytelldus.helper.helper_list,
                "desc" : "List devices in telldus daemon.",
                "usage" : "list [devicetype]",
                "param-list" : "devicetype",
                "min-args" : 0,
                "devicetype" : "the type of device to find",
              },
             "info" :
              {
                "cb" : self._mytelldus.helper.helper_info,
                "desc" : "Display device information.",
                "usage" : "info <device>",
                "param-list" : "device",
                "min-args" : 1,
                "device" : "device address",
              },
             "memory" :
              {
                "cb" : self._mytelldus.helper.helper_memory,
                "desc" : "Show memory usage of variables. Experimental.",
                "usage" : "memory",
                "param-list" : "",
                "min-args" : 0,
              },
            }
        if self.lightext == True:
            self.log.debug(
                "telldus.__init__ : Try to enable the lighting extension.")
            self.lighting.enable_lighting()
        self.log.debug("telldus.__init__ : Try to load the helpers.")
        self.enable_helper()
        self.log.info("Telldus plugin correctly started")

    def telldus_cmnd_cb(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("telldus.telldus_cmnd_cb : Receive message.")
        commands = {
            'on': lambda hu, l, f: self._mytelldus.send_on(hu),
            'off': lambda hu, l, f: self._mytelldus.send_off(hu),
            'dim': lambda hu, l, f: self._mytelldus.send_dim(hu, l),
            'bright': lambda hu, l, f: self._mytelldus.send_bright(hu, l, f),
            'shine': lambda hu, l, f: self._mytelldus.send_shine(hu, l, f),
            'change': lambda hu, l, f: self._mytelldus.send_change(hu, l, f),
            'up': lambda hu, l, f: self._mytelldus.send_up(hu),
            'down': lambda hu, l, f: self._mytelldus.send_down(hu),
            'stop': lambda hu, l, f: self._mytelldus.send_stop(hu),
            'shut': lambda hu, l, f: self._mytelldus.send_shut(hu, l),
        }
        try:
            cmd = None
            if 'command' in message.data:
                cmd = message.data['command']
            device = None
            if 'device' in message.data:
                device = message.data['device']
            level = "0"
            if 'level' in message.data:
                level = message.data['level']
            faderate = "0"
            if 'faderate' in message.data:
                faderate = message.data['faderate']
            self.log.debug("%s received : device= %s, level=%s, faderate=%s" %
                           (cmd, device, level, faderate))
            commands[cmd](device, level, faderate)
        except Exception:
            self.log.error("action _ %s _ unknown." % (cmd))
            error = "Exception : %s" % (traceback.format_exc())
            self.log.info("TelldusException : " + error)

    def telldus_reload_config_cb(self):
        """
        Callback for telldus reload config
        @param message : xpl message
        """
        self.log.debug("Telldus reload config received")
        self._mytelldus.reload_config()

    def send_xpl(self, message):
        """
        Callback for sending xpl
        @param add : address of the module
        @param order : the order sent to the unit
        """
        self.log.debug("Telldus send_xpl")
        self.myxpl.send(message)
Esempio n. 40
0
class SamsungTVManager(XplPlugin):
    """ Manage Samsung televisions
    """
    def __init__(self):
        """ Init manager
        """
        XplPlugin.__init__(self, name='tv_samsg')

        # Configuration : list of televisions
        self.televisions = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            name = self._config.query('tv_samsg', 'tv-%s-name' % str(num))
            device = self._config.query('tv_samsg', 'tv-%s-device' % str(num))
            if name != None:
                self.log.info("Configuration : name=%s, device=%s" %
                              (name, device))
                self.televisions[name] = {"device": device}
            else:
                loop = False
            num += 1

        ### Create SamsungTV objects
        for television in self.televisions:
            self.televisions[television]['obj'] = SamsungTV(self.log)
            try:
                self.log.info(
                    "Opening Samsung Television named '%s' (device : %s)" %
                    (television, self.televisions[television]['device']))
                self.televisions[television]['obj'].open(
                    self.televisions[television]['device'])
            except SamsungTVException as err:
                self.log.error(err.value)
                print(err.value)
                self.force_leave()
                return

        # Create listener
        Listener(self.television_cb, self.myxpl, {
            'schema': 'control.basic',
            'xpltype': 'xpl-cmnd',
            'type': 'television'
        })
        self.log.debug("Listener for tv_samsg created")

        self.enable_hbeat()

    def television_cb(self, message):
        """ Call tv_samsg lib
            @param message : xPL message detected by listener
        """
        # device contains name of television which will be used to get device
        if 'device' in message.data:
            name = message.data['device']
        if 'current' in message.data:
            command = message.data['current']
        else:
            self._log.warning("Xpl message : missing 'current' attribute")
            return
        if 'data1' in message.data:
            data1 = int(message.data['data1'])
        else:
            data1 = None

        try:
            device = self.televisions[name]["device"]
        except KeyError:
            self.log.warning("Television named '%s' is not defined" % name)
            return

        self.log.info("Television command received for '%s' on '%s'" %
                      (name, device))
        status = self.televisions[name]['obj'].send(command, data1)

        # Send xpl-trig to say plugin receive command
        print("S=%s" % status)
        if status == True:
            mess = XplMessage()
            mess.set_type('xpl-trig')
            mess.set_schema('sensor.basic')
            mess.add_data({'device': device})
            mess.add_data({'type': 'television'})
            mess.add_data({'current': command})
            if data1 != None:
                mess.add_data({'data1': data1})
            print(mess)
            self.myxpl.send(mess)
Esempio n. 41
0
class WolPing(XplPlugin):
    """ Implements a listener for wol messages on xPL network
    """

    def __init__(self):
        """ Create listener for wake on lan
        """
        XplPlugin.__init__(self, name = 'wol_ping')

        # Configuration : interval between each ping
        self._config = Query(self.myxpl, self.log)
        interval = self._config.query('wol_ping', 'ping-interval')
        if interval == None:
            interval = 60

        # Configuration : list of computers
        self.computers = {}
        num = 1
        loop = True
        while loop == True:
            name = self._config.query('wol_ping', 'name-%s' % str(num))
            ip = self._config.query('wol_ping', 'ip-%s' % str(num))
            mac = self._config.query('wol_ping', 'mac-%s' % str(num))
            mac_port = self._config.query('wol_ping', 'wol-port-%s' % str(num))
            if mac_port == None:
                mac_port = 7
            if name != None:
                self.log.info("Configuration : name=%s, ip=%s, mac=%s, mac port=%s" % (name, ip, mac, mac_port))
                self.computers[name] = {"ip" : ip, "mac" : mac, 
                                        "mac_port" : mac_port}
            else:
                loop = False
            num += 1

        ### Create WOL object
        self._wolmanager = WOL(self.log)
        # Create listeners
        Listener(self.wol_cb, self.myxpl, {'schema': 'control.basic',
                'xpltype': 'xpl-cmnd', 'type': 'wakeonlan', 'current': 'high'})
        self.log.debug("Listener for wake on lan created")

        ### Create Ping object
        self._pingmanager = Ping(self.myxpl, 
                                 self.log, 
                                 self.ping_cb, 
                                 float(interval),
                                 self.computers)
        self.enable_hbeat()
        self._pingmanager.ping()

    def wol_cb(self, message):
        """ Call wake on lan lib
            @param message : xPL message detected by listener
        """
        if 'device' in message.data:
            device = message.data['device']

        try:
            mac = self.computers[device]["mac"]
            port = int(self.computers[device]["mac_port"])
        except KeyError:
            self.log.warning("Computer named '%s' is not defined" % device)
            return
        
        self.log.info("Wake on lan command received for '%s' on port '%s'" %
                       (mac, port))
        #status = self._wolmanager.wake_up(mac, port)
        status = self._wolmanager.wake_up(mac, port)

        # Send xpl-trig to say plugin receive command
        if status == True:
            mess = XplMessage()
            mess.set_type('xpl-trig')
            mess.set_schema('sensor.basic')
            mess.add_data({'device' :  device})
            mess.add_data({'type' :  'wakeonlan'})
            mess.add_data({'current' :  'high'})
            self.myxpl.send(mess)


    def ping_cb(self, type, computer, status):
        # Send xpl-trig to say plugin receive command
        msg = XplMessage()
        msg.set_type(type)
        msg.set_schema('sensor.basic')
        msg.add_data({'device' :  computer})
        msg.add_data({'type' :  'ping'})
        msg.add_data({'current' :  status})
        self.myxpl.send(msg)
Esempio n. 42
0
class APushNotificationListener(XplPlugin):
    """ Create listener for xPL messages about Android push notification
    """

    def __init__(self):
        """ Create listener for Android push notification
        """
        XplPlugin.__init__(self, name = 'apushnot')
        # Create logger
        self.log.debug("Listener for Android push notification created")

        # Configuration : list of recipient and source key
        self.alias_list = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            recipient = self._config.query('apushnot', 'name-%s' % str(num))
            source = self._config.query('apushnot', 'source-%s' % str(num))
            dfltitle = self._config.query('apushnot', 'default-title-%s' % str(num))
            if recipient != None:
                mess="Configuration : recipient=" + str(recipient) + " , source=" + str(source) + ", default title=" + str(dfltitle)
                self.log.info(mess)
                print(mess)
                self.alias_list[recipient] = {"recipient" : recipient, "source" : source, "dfltitle" : dfltitle}
                num += 1
            else:
                loop = False

        # no recipient configured
        if num == 1:
            msg = "No recipient configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        # Check title
        for alias in self.alias_list:
            if str(self.alias_list[alias]['dfltitle']) != "None":
                self.log.debug("default title for recipient " + str(self.alias_list[alias]['recipient']) + " is " + str(self.alias_list[alias]['dfltitle']))
            else:
                self.log.error("Can't find the default title for the recipient " + str(self.alias_list[alias]['recipient']) + " , please check the configuration page of this plugin")
                self.force_leave()
                return


        # Create APushNotification object
        self.apn_notification_manager = APushNotification(self.log)

        # Create listeners
        Listener(self.apn_notification_cb, self.myxpl, {'schema': 'sendmsg.push', 'xpltype': 'xpl-cmnd'})
        self.enable_hbeat()

    def apn_notification_cb(self, message):
        """ Call Android notification lib
            @param message : message from xpl
        """
        self.log.debug("Call apn_notification_cb")

        # mandatory keys
        if 'to' in message.data:
            to = message.data['to']
            for alias in self.alias_list:
                try:
                    if str(self.alias_list[alias]['recipient']) == str(to):
                        sourcekey = self.alias_list[alias]['source']
                except :
                    self.log.debug("Can't find the recipient, please check the configuration page of this plugin")
                    self.force_leave()
                    return
        else:
            self.log.warning("No recipient was found in the xpl message")
            return

        if 'body' in message.data:
            body = message.data['body']
        else:
            self.log.warning("No message was found in the xpl message")
            return

        # optionnal keys
        if 'title' in message.data:
            title = message.data['title']
        else:
            for alias in self.alias_list:
                if str(self.alias_list[alias]['recipient']) == str(to):
                    title = self.alias_list[alias]['dfltitle']
                    self.log.info("No title was found in the xpl message, so the default title " + title + "is used")


        self.log.debug("Call send_apn with following parameters : sourcekey=" + sourcekey + ", title=" + title + ", message=" + body)
        self.apn_notification_manager.send_apn(sourcekey, title, body)
Esempio n. 43
0
class Telldus(XplHlpPlugin):
    '''
    Manage chacon devices through the TellStick device
    '''
    def __init__(self):
        """
        Create the telldus class
        This class is used to connect devices (through telldus) to
        the xPL Network
        """
        XplHlpPlugin.__init__(self, name = 'telldus',
            reload_cb = self.telldus_reload_config_cb)
        self.log.debug("telldus.__init__ : Start ...")
        self._device = "/dev/tellstick"
        #Check if the device exists
        if not os.path.exists(self._device):
            self.log.warning(self._device +
                " is not present but Tellstick Duo don't use it.")
        else:
            self.log.debug("Device present as "+self._device)
        self._config = Query(self.myxpl, self.log)
        self.log.debug("telldus.__init__ : Try to load API")
        try:
            self._mytelldus = TelldusAPI(self, self.send_xpl, self.log,
                self._config,self.get_data_files_directory(), self.myxpl)
        except Exception:
            self.log.error("Something went wrong during telldus API init.")
            self.log.error("%s" % (traceback.format_exc()))
            self.force_leave()
            exit(1)
        self.add_stop_cb(self._mytelldus.unregister)
        self.log.debug("telldus.__init__ : Create listeners")
        Listener(self.telldus_cmnd_cb, self.myxpl,
                 {'schema': 'telldus.basic', 'xpltype': 'xpl-cmnd'})
        Listener(self.telldus_reload_config_cb, self.myxpl,
                 {'schema': 'domogik.system', 'xpltype': 'xpl-cmnd',
                  'command': 'reload', 'plugin': 'telldus'})
        self.enable_hbeat()
        try:
            boo = self._config.query('telldus', 'lightext')
            if boo == None:
                boo = "False"
            self.lightext = eval(boo)
        except:
            self.log.warning("Can't get delay configuration from XPL. Disable lighting extensions.")
            self.lightext = False
        if self.lightext == True:
            self.log.debug("telldus.__init__ : Try to load the lighting extension.")
            self.lighting = LightingExtension(self, self._name, \
                self._mytelldus.lighting_activate_device, \
                self._mytelldus.lighting_deactivate_device, \
                self._mytelldus.lighting_valid_device)
        self.helpers =   \
           { "list" :
              {
                "cb" : self._mytelldus.helper.helper_list,
                "desc" : "List devices in telldus daemon.",
                "usage" : "list [devicetype]",
                "param-list" : "devicetype",
                "min-args" : 0,
                "devicetype" : "the type of device to find",
              },
             "info" :
              {
                "cb" : self._mytelldus.helper.helper_info,
                "desc" : "Display device information.",
                "usage" : "info <device>",
                "param-list" : "device",
                "min-args" : 1,
                "device" : "device address",
              },
             "memory" :
              {
                "cb" : self._mytelldus.helper.helper_memory,
                "desc" : "Show memory usage of variables. Experimental.",
                "usage" : "memory",
                "param-list" : "",
                "min-args" : 0,
              },
            }
        if self.lightext == True:
            self.log.debug("telldus.__init__ : Try to enable the lighting extension.")
            self.lighting.enable_lighting()
        self.log.debug("telldus.__init__ : Try to load the helpers.")
        self.enable_helper()
        self.log.info("Telldus plugin correctly started")

    def telldus_cmnd_cb(self, message):
        """
        General callback for all command messages
        @param message : an XplMessage object
        """
        self.log.debug("telldus.telldus_cmnd_cb : Receive message.")
        commands = {
            'on': lambda hu, l, f: self._mytelldus.send_on(hu),
            'off': lambda hu, l, f: self._mytelldus.send_off(hu),
            'dim': lambda hu, l, f: self._mytelldus.send_dim(hu, l),
            'bright': lambda hu, l, f: self._mytelldus.send_bright(hu, l, f),
            'shine': lambda hu, l, f: self._mytelldus.send_shine(hu, l, f),
            'change': lambda hu, l, f: self._mytelldus.send_change(hu, l, f),
            'up': lambda hu, l, f: self._mytelldus.send_up(hu),
            'down': lambda hu, l, f: self._mytelldus.send_down(hu),
            'stop': lambda hu, l, f: self._mytelldus.send_stop(hu),
            'shut': lambda hu, l, f: self._mytelldus.send_shut(hu, l),
        }
        try :
            cmd = None
            if 'command' in message.data:
                cmd = message.data['command']
            device = None
            if 'device' in message.data:
                device = message.data['device']
            level = "0"
            if 'level' in message.data:
                level = message.data['level']
            faderate = "0"
            if 'faderate' in message.data:
                faderate = message.data['faderate']
            self.log.debug("%s received : device= %s, level=%s, faderate=%s" % (cmd, device, level, faderate))
            commands[cmd](device, level, faderate)
        except Exception:
            self.log.error("action _ %s _ unknown." % (cmd))
            error = "Exception : %s" % (traceback.format_exc())
            self.log.info("TelldusException : "+error)

    def telldus_reload_config_cb(self):
        """
        Callback for telldus reload config
        @param message : xpl message
        """
        self.log.debug("Telldus reload config received")
        self._mytelldus.reload_config()

    def send_xpl(self, message):
        """
        Callback for sending xpl
        @param add : address of the module
        @param order : the order sent to the unit
        """
        self.log.debug("Telldus send_xpl")
        self.myxpl.send(message)
Esempio n. 44
0
class YWeatherManager(XplPlugin):
    """ Get data from Yahoo weather and send them on xPL
    """

    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='yweather')

        # Get config
        self._config = Query(self.myxpl, self.log)
        unit = self._config.query('yweather', 'unit' )
        if unit == None:
            self.log.error("Unit not configured : exiting")
            print("Unit not configured : exiting")
            self.force_leave()
            return
        unit = unit.lower()
        
        self.enable_current = self._config.query('yweather', 'en-current' )
        self.enable_previsionnal = self._config.query('yweather', 'en-prev' )

        self.cities = {}
        num = 1
        loop = True
        while loop == True:
            city_code = self._config.query('yweather', 'city-%s' % str(num))
            device = self._config.query('yweather', 'device-%s' % str(num))
            if city_code != None:
                self.cities[city_code] = { "device" : device }
                num = num + 1
            else:
                loop = False

        # Open weather for cities
        for city in self.cities:
            self.cities[city]["obj"] = YWeather(self.log, self.send_xpl)
            try:
                self.log.info("Init weather for '%s'" % city)
                self.cities[city]["obj"].open(city, unit,
                                              self.cities[city]["device"])
            except YWeatherException as err:
                self.log.error(err.value)
                print(err.value)
                self.force_leave()
                return

        # Start listening for weather
        for city in self.cities:
            try:
                self.log.info("Start listening weather for '%s'" % city)
                self._listen_thr = XplTimer(TIME_BETWEEN_EACH_WEATHER_READ, \
                                            self.cities[city]["obj"].get, \
                                            self.myxpl)
                self._listen_thr.start()
                self.enable_hbeat()
            except YWeatherException as err:
                self.log.error(err.value)
                print(err.value)
                self.force_leave()
                return
        self.enable_hbeat()



    def send_xpl(self, device, weather):
        """ Send xPL message on network
            @param device : device (address set by user in config page)
            @param weather : weather data
        """
        # current part (sensor.basic)
        if self.enable_current == 'True':
            self._send_current(device, weather, 
                               "current", "temperature", "temp",
                               units = weather["units"]["temperature"])
            self._send_current(device, weather, 
                               "atmosphere", "pressure", "pressure",
                               units = weather["units"]["pressure"])
            self._send_current(device, weather, 
                               "atmosphere", "humidity", "humidity",
                               units = "%")
            self._send_current(device, weather, 
                               "atmosphere", "visibility", "visibility",
                               units = weather["units"]["distance"])
            self._send_current(device, weather, 
                               "atmosphere", "rising", "rising")
            self._send_current(device, weather, 
                               "wind", "chill", "chill")
            self._send_current(device, weather, 
                               "wind", "direction", "direction")
            self._send_current(device, weather, 
                               "wind", "speed", "speed",
                               units = weather["units"]["speed"])
            self._send_current(device, weather, 
                               "current", "code", "condition-code")
            self._send_current(device, weather, 
                               "current", "text", "condition-text")


        # previsionnal part
        if self.enable_previsionnal == 'True':
            common = {
                      "city" : weather["location"]["city"],
                      "region" : weather["location"]["region"],
                      "country" : weather["location"]["country"],
                      "unit-distance" : weather["units"]["distance"],
                      "unit-pressure" : weather["units"]["pressure"],
                      "unit-speed" : weather["units"]["speed"],
                      "unit-temperature" : weather["units"]["temperature"]
                     }

            my_today = datetime.date.today().isoformat() 
            today = {
                   "day" : my_today,
                   "condition-code" : weather["today"]["code"],
                   "condition-text" : weather["today"]["text"],
                   "temperature-low" : weather["today"]["temperature_low"],
                   "temperature-high" : weather["today"]["temperature_high"],
                     }

            my_tomorrow = (datetime.date.today() + \
                           datetime.timedelta(days = 1)).isoformat()
            tomorrow = {
                   "day" : my_tomorrow,
                   "condition-code" : weather["tomorrow"]["code"],
                   "condition-text" : weather["tomorrow"]["text"],
                   "temperature-low" : weather["tomorrow"]["temperature_low"],
                   "temperature-high" : weather["tomorrow"]["temperature_high"],
                     }

            today.update(common)
            tomorrow.update(common)
            self._send_previsionnal(device, today)
            self._send_previsionnal(device, tomorrow)


    def _send_current(self, device, weather, category, key, xpl_type, 
                      units = None):
        """ Check if data exists and sent it over xpl
            @param device : device (address set by user in config page)
            @param weather : weather struc
            @param category : category of data (atmosphere, today, tomorrow...)
            @param key : key in category
            @param xpl_type : type to use in xpl schema
            @param units : unit for value
        """
        try:
            self._send_sensor_basic(device = device,
                                            type = xpl_type,
                                            current = weather[category][key],
                                            units = units)
        except KeyError:
            # no data : pass
            print("No data for %s>%s" % (category, key))
            pass


    def _send_sensor_basic(self, device, type, current, units = None):
        """ Send sensor.basic xPL schema
            @param device : device
            @param type : type
            @param current : current
        """
        print("D=%s, T=%s, C=%s" % (device, type, current))
        if current == "":
            return
        msg = XplMessage()
        msg.set_type("xpl-stat")
        msg.set_schema("sensor.basic")
        msg.add_data({"device" : device})
        msg.add_data({"type" : type})
        msg.add_data({"current" : current})
        if units != None:
            msg.add_data({"units" : units})
        self.myxpl.send(msg)


    def _send_previsionnal(self, device, data):
        """ Send weather.basic xPL schema
            @param device : device
            @param data : dictionnary of data to send
        """
        print("D=%s, %s" % (device, data))
        msg = XplMessage()
        msg.set_type("xpl-stat")
        msg.set_schema("weather.basic")
        msg.add_data({"device" : device})
        for key in data:
            if data[key] != "":
                msg.add_data({key : data[key]})

        self.myxpl.send(msg)
Esempio n. 45
0
class DiskManager(XplPlugin):
    """ Get disk free size over xPL
    """
    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='diskfree')

        # Global config : probe interval
        self._config = Query(self.myxpl, self.log)
        interval = self._config.query('diskfree', 'interval')
        if interval != None:
            interval = float(interval)
        else:
            msg = "Interval not configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        # Configuration : list of path to check
        self.path_list = {}
        num = 1
        loop = True
        while loop == True:
            path = self._config.query('diskfree', 'path-%s' % str(num))
            if path != None:
                self.log.info("Configuration : path=%s" % path)
                num += 1
                # init object list for path to None
                self.path_list[path] = None
            else:
                loop = False

        # no path configured
        if num == 1:
            msg = "No path configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        ### Start listening each path
        for path in self.path_list:
            try:
                self.path_list[path] = Disk(self.log, self.send_xpl,
                                            self.get_stop())
                self.log.info("Start listening for '%s'" % path)
                path_listen = threading.Thread(None,
                                               self.path_list[path].listen,
                                               "listen_diskfree", (
                                                   path,
                                                   interval,
                                               ), {})
                path_listen.start()
            except:
                self.log.error(traceback.format_exc())
                print(traceback.format_exc())
                # we don't quit plugin if an error occured
                # a disk can have been unmounted for a while
                #self.force_leave()
                #return

        self.enable_hbeat()
        self.log.info("Plugin ready :)")

    def send_xpl(self, path, du_type, du_value):
        """ Send xPL message on network
        """
        print("path:%s, %s:%s" % (path, du_type, du_value))
        msg = XplMessage()
        msg.set_type("xpl-stat")
        msg.set_schema("sensor.basic")
        msg.add_data({"device": path})
        msg.add_data({"type": du_type})
        msg.add_data({"current": du_value})
        self.myxpl.send(msg)
Esempio n. 46
0
class YWeatherManager(XplPlugin):
    """ Get data from Yahoo weather and send them on xPL
    """
    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='yweather')

        # Get config
        self._config = Query(self.myxpl, self.log)
        unit = self._config.query('yweather', 'unit')
        if unit == None:
            self.log.error("Unit not configured : exiting")
            print("Unit not configured : exiting")
            self.force_leave()
            return
        unit = unit.lower()

        self.enable_current = self._config.query('yweather', 'en-current')
        self.enable_previsionnal = self._config.query('yweather', 'en-prev')

        self.cities = {}
        num = 1
        loop = True
        while loop == True:
            city_code = self._config.query('yweather', 'city-%s' % str(num))
            device = self._config.query('yweather', 'device-%s' % str(num))
            if city_code != None:
                self.cities[city_code] = {"device": device}
                num = num + 1
            else:
                loop = False

        # Open weather for cities
        for city in self.cities:
            self.cities[city]["obj"] = YWeather(self.log, self.send_xpl)
            try:
                self.log.info("Init weather for '%s'" % city)
                self.cities[city]["obj"].open(city, unit,
                                              self.cities[city]["device"])
            except YWeatherException as err:
                self.log.error(err.value)
                print(err.value)
                self.force_leave()
                return

        # Start listening for weather
        for city in self.cities:
            try:
                self.log.info("Start listening weather for '%s'" % city)
                self._listen_thr = XplTimer(TIME_BETWEEN_EACH_WEATHER_READ, \
                                            self.cities[city]["obj"].get, \
                                            self.myxpl)
                self._listen_thr.start()
                self.enable_hbeat()
            except YWeatherException as err:
                self.log.error(err.value)
                print(err.value)
                self.force_leave()
                return
        self.enable_hbeat()

    def send_xpl(self, device, weather):
        """ Send xPL message on network
            @param device : device (address set by user in config page)
            @param weather : weather data
        """
        # current part (sensor.basic)
        if self.enable_current == 'True':
            self._send_current(device,
                               weather,
                               "current",
                               "temperature",
                               "temp",
                               units=weather["units"]["temperature"])
            self._send_current(device,
                               weather,
                               "atmosphere",
                               "pressure",
                               "pressure",
                               units=weather["units"]["pressure"])
            self._send_current(device,
                               weather,
                               "atmosphere",
                               "humidity",
                               "humidity",
                               units="%")
            self._send_current(device,
                               weather,
                               "atmosphere",
                               "visibility",
                               "visibility",
                               units=weather["units"]["distance"])
            self._send_current(device, weather, "atmosphere", "rising",
                               "rising")
            self._send_current(device, weather, "wind", "chill", "chill")
            self._send_current(device, weather, "wind", "direction",
                               "direction")
            self._send_current(device,
                               weather,
                               "wind",
                               "speed",
                               "speed",
                               units=weather["units"]["speed"])
            self._send_current(device, weather, "current", "code",
                               "condition-code")
            self._send_current(device, weather, "current", "text",
                               "condition-text")

        # previsionnal part
        if self.enable_previsionnal == 'True':
            common = {
                "city": weather["location"]["city"],
                "region": weather["location"]["region"],
                "country": weather["location"]["country"],
                "unit-distance": weather["units"]["distance"],
                "unit-pressure": weather["units"]["pressure"],
                "unit-speed": weather["units"]["speed"],
                "unit-temperature": weather["units"]["temperature"]
            }

            my_today = datetime.date.today().isoformat()
            today = {
                "day": my_today,
                "condition-code": weather["today"]["code"],
                "condition-text": weather["today"]["text"],
                "temperature-low": weather["today"]["temperature_low"],
                "temperature-high": weather["today"]["temperature_high"],
            }

            my_tomorrow = (datetime.date.today() + \
                           datetime.timedelta(days = 1)).isoformat()
            tomorrow = {
                "day": my_tomorrow,
                "condition-code": weather["tomorrow"]["code"],
                "condition-text": weather["tomorrow"]["text"],
                "temperature-low": weather["tomorrow"]["temperature_low"],
                "temperature-high": weather["tomorrow"]["temperature_high"],
            }

            today.update(common)
            tomorrow.update(common)
            self._send_previsionnal(device, today)
            self._send_previsionnal(device, tomorrow)

    def _send_current(self,
                      device,
                      weather,
                      category,
                      key,
                      xpl_type,
                      units=None):
        """ Check if data exists and sent it over xpl
            @param device : device (address set by user in config page)
            @param weather : weather struc
            @param category : category of data (atmosphere, today, tomorrow...)
            @param key : key in category
            @param xpl_type : type to use in xpl schema
            @param units : unit for value
        """
        try:
            self._send_sensor_basic(device=device,
                                    type=xpl_type,
                                    current=weather[category][key],
                                    units=units)
        except KeyError:
            # no data : pass
            print("No data for %s>%s" % (category, key))
            pass

    def _send_sensor_basic(self, device, type, current, units=None):
        """ Send sensor.basic xPL schema
            @param device : device
            @param type : type
            @param current : current
        """
        print("D=%s, T=%s, C=%s" % (device, type, current))
        if current == "":
            return
        msg = XplMessage()
        msg.set_type("xpl-stat")
        msg.set_schema("sensor.basic")
        msg.add_data({"device": device})
        msg.add_data({"type": type})
        msg.add_data({"current": current})
        if units != None:
            msg.add_data({"units": units})
        self.myxpl.send(msg)

    def _send_previsionnal(self, device, data):
        """ Send weather.basic xPL schema
            @param device : device
            @param data : dictionnary of data to send
        """
        print("D=%s, %s" % (device, data))
        msg = XplMessage()
        msg.set_type("xpl-stat")
        msg.set_schema("weather.basic")
        msg.add_data({"device": device})
        for key in data:
            if data[key] != "":
                msg.add_data({key: data[key]})

        self.myxpl.send(msg)
Esempio n. 47
0
class Rest(XplPlugin):
    """ REST Server 
        - create a HTTP server 
        - process REST requests
    """
        

    def __init__(self, server_ip, server_port):
        """ Initiate DbHelper, Logs and config
            Then, start HTTP server and give it initialized data
            @param server_ip :  ip of HTTP server
            @param server_port :  port of HTTP server
        """

        XplPlugin.__init__(self, name = 'rest')
        # logging initialization
        self.log.info("Rest Server initialisation...")
        self.log.debug("locale : %s %s" % locale.getdefaultlocale())

        # logging Queue activities
        log_queue = logger.Logger('rest-queues')
        self.log_queue = log_queue.get_logger('rest-queues')
        self.log_queue.info("Rest's queues activities...")
    
        # logging data manipulation initialization
        log_dm = logger.Logger('rest-dm')
        self.log_dm = log_dm.get_logger('rest-dm')
        self.log_dm.info("Rest Server Data Manipulation...")

        # API version
        self._rest_api_version = REST_API_VERSION

        # Hosts list
        self._hosts_list = {self.get_sanitized_hostname() : 
                                {"id" : self.get_sanitized_hostname(),
                                 "status" : "on",
                                 "primary" : True,
                                 "last_seen" : time.time(),
                                 "ip" : "",
                                 "interval" : "1"}}

        try:
    
            ### Config
    
            # directory data 
            cfg = Loader('domogik')
            config = cfg.load()
            conf = dict(config[1])
            self.log_dir_path = conf['log_dir_path']

            # plugin installation path
            if conf.has_key('package_path'):
                self._package_path = conf['package_path']
                self._src_prefix = None
                self.log.info("Set package path to '%s' " % self._package_path)
                print("Set package path to '%s' " % self._package_path)
                self._design_dir = "%s/domogik_packages/design/" % self._package_path
                self.package_mode = True
            else:
                self.log.info("No package path defined in config file")
                self._package_path = None
                self._src_prefix = conf['src_prefix']
                self._design_dir = "%s/share/domogik/design/" % conf['src_prefix']
                self.package_mode = False
    
            # HTTP server ip and port
            try:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.server_ip = conf_rest['rest_server_ip']
                self.server_port = conf_rest['rest_server_port']
            except KeyError:
                # default parameters
                self.server_ip = server_ip
                self.server_port = server_port
            self.log.info("Configuration : ip:port = %s:%s" % (self.server_ip, self.server_port))
    
            # SSL configuration
            try:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.use_ssl = conf_rest['rest_use_ssl']
                if self.use_ssl == "True":
                    self.use_ssl = True
                else:
                    self.use_ssl = False
                self.ssl_certificate = conf_rest['rest_ssl_certificate']
            except KeyError:
                # default parameters
                self.use_ssl = USE_SSL
                self.ssl_certificate = SSL_CERTIFICATE
            if self.use_ssl == True:
                self.log.info("Configuration : SSL support activated (certificate : %s)" % self.ssl_certificate)
            else:
                self.log.info("Configuration : SSL support not activated")
    
            # File repository
            try:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.repo_dir = conf_rest['rest_repository']
            except KeyError:
                # default parameters
                self.repo_dir = DEFAULT_REPO_DIR

            # Gloal Queues config
            self.log.debug("Get queues configuration")
            self._config = Query(self.myxpl, self.log)

            self._queue_timeout = self._config.query('rest', 'q-timeout')
            if self._queue_timeout == None:
                self._queue_timeout = QUEUE_TIMEOUT
            self._queue_timeout = float(self._queue_timeout)

            self._queue_package_size = self._config.query('rest', 'q-pkg-size')
            if self._queue_package_size == None:
                self._queue_package_size = QUEUE_PACKAGE_SIZE
            self._queue_package_size = float(self._queue_package_size)

            self._queue_size = self._config.query('rest', 'q-size')
            if self._queue_size == None:
                self._queue_size = QUEUE_SIZE
            self._queue_size = float(self._queue_size)

            self._queue_life_expectancy = self._config.query('rest', 'q-life-exp')
            if self._queue_life_expectancy == None:
                self._queue_life_expectancy = QUEUE_LIFE_EXPECTANCY
            self._queue_life_expectancy = float(self._queue_life_expectancy)

            self._queue_sleep = self._config.query('rest', 'q-sleep')
            if self._queue_sleep == None:
                self._queue_sleep = QUEUE_SLEEP
            self._queue_sleep = float(self._queue_sleep)

            # /command Queues config
            self._queue_command_size = self._config.query('rest', 'q-cmd-size')
            if self._queue_command_size == None:
                self._queue_command_size = QUEUE_COMMAND_SIZE
            self._queue_command_size = float(self._queue_command_size)

            # /event Queues config
            self._event_timeout = self._config.query('rest', 'evt-timeout')
            if self._event_timeout == None:
                self._event_timeout = EVENT_TIMEOUT
            self._event_timeout = float(self._event_timeout)

            self._queue_event_size = self._config.query('rest', 'q-evt-size')
            if self._queue_event_size == None:
                self._queue_event_size = QUEUE_EVENT_SIZE
            self._queue_event_size = float(self._queue_event_size)

            self._queue_event_timeout = self._config.query('rest', 'q-evt-timeout')
            if self._queue_event_timeout == None:
                self._queue_event_timeout = QUEUE_EVENT_TIMEOUT
            self._queue_event_timeout = float(self._queue_event_timeout)

            self._queue_event_life_expectancy = self._config.query('rest', 'q-evt-life-exp')
            if self._queue_event_life_expectancy == None:
                self._queue_event_life_expectancy = QUEUE_EVENT_LIFE_EXPECTANCY
            self._queue_event_life_expectancy = float(self._queue_event_life_expectancy)
    
            # Queues for xPL
            # Queues for packages management
            self._queue_package = Queue(self._queue_package_size)

            # Queues for domogik system actions
            self._queue_system_list = Queue(self._queue_size)
            self._queue_system_detail = Queue(self._queue_size)
            self._queue_system_start = Queue(self._queue_size)
            self._queue_system_stop = Queue(self._queue_size)

            # Queues for /command
            self._queue_command = Queue(self._queue_command_size)
    
            # Queues for /events/domogik
            self._queue_event_dmg = Queue(self._queue_event_size)
    
            # Queues for /events/request
            # this queue will be fill by stat manager
            self._event_requests = RequestEvents(self.get_stop,
                                                  self.log,
                                                  self._event_timeout,
                                                  self._queue_event_size,
                                                  self._queue_event_timeout,
                                                  self._queue_event_life_expectancy)
            self.add_stop_cb(self._event_requests.set_stop_clean)

            # Queues for /events/domogik
            # this queue will be fill by stat manager
            self._event_dmg = DmgEvents(self.get_stop,
                                     self.log,
                                     self._event_timeout,
                                     self._queue_event_size,
                                     self._queue_event_timeout,
                                     self._queue_event_life_expectancy)
            # notice : adding data in queue is made in _add_to_queue_system_list
            self.add_stop_cb(self._event_dmg.set_stop_clean)
    
            # define listeners for queues
            self.log.debug("Create listeners")
            if self.package_mode == True:
                Listener(self._list_installed_packages, self.myxpl, \
                         {'schema': 'domogik.package',
                          'xpltype': 'xpl-trig',
                          'command' : 'installed-packages-list'})
            Listener(self._add_to_queue_package, self.myxpl, \
                     {'schema': 'domogik.package',
                      'xpltype': 'xpl-trig'})
            Listener(self._add_to_queue_system_list, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'list'})
            Listener(self._add_to_queue_system_list, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'enable'})
            Listener(self._add_to_queue_system_list, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'disable'})
            Listener(self._add_to_queue_system_detail, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'detail'})
            Listener(self._add_to_queue_system_start, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'start'})
            Listener(self._add_to_queue_system_stop, self.myxpl, \
                     {'schema': 'domogik.system',
                      'xpltype': 'xpl-trig',
                      'command' : 'stop'})
            Listener(self._add_to_queue_command, self.myxpl, \
                     {'xpltype': 'xpl-trig'})

            # Listener for hosts list
            Listener(self._list_hosts, self.myxpl, \
                     {'schema': 'hbeat.app',
                      'xpltype': 'xpl-stat'})
 
            # Background process to check if hosts has disappeared
            thr_hbeat = XplTimer(10, \
                                 self._refresh_status_for_list_hosts, \
                                 self.myxpl)
            thr_hbeat.start()
   
            self._discover_hosts()
            
            # Enable hbeat
            self.enable_hbeat()

            # Ask for installed packages on all hosts
            # Semaphore init for installed package list update
            self.sema_installed = Semaphore(value=1)
            self._installed_packages = {}
            if self.package_mode == True:
                self._get_installed_packages_from_manager()

            # Launch server, stats
            self.log.info("REST Initialisation OK")
            self.add_stop_cb(self.stop_http)
            self.server = None
            self.start_stats()

            self.start_http()
        except :
            self.log.error("%s" % self.get_exception())


    def _add_to_queue_package(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_package, message)

    def _add_to_queue_system_list(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_list, message)
        current_date = calendar.timegm(time.gmtime())
        self._event_dmg.add_in_queues({"timestamp" : current_date,
                                            "data" : "plugin-list-updated"})

    def _add_to_queue_system_detail(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_detail, message)

    def _add_to_queue_system_start(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_start, message)

    def _add_to_queue_system_stop(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_system_stop, message)

    def _add_to_queue_command(self, message):
        """ Add data in a queue
        """
        self._put_in_queue(self._queue_command, message)

    def _get_from_queue(self, my_queue, filter_type = None, filter_schema = None, filter_data = None, nb_rec = 0, timeout = None):
        """ Encapsulation for _get_from_queue_in
            If timeout not elapsed and _get_from_queue didn't find a valid data
            call again _get_from_queue until timeout
            This encapsulation is used to process case where queue is not empty but there is
            no valid data in it and we want to wait for timeout
        """
        if timeout == None:
            timeout = self._queue_timeout
        start_time = time.time()
        while time.time() - start_time < timeout:
            try:
                return self._get_from_queue_without_waiting(my_queue, filter_type, filter_schema, filter_data, nb_rec, timeout)
            except Empty:
                # no data in queue for us.... let's continue until time elapsed
                # in order not rest not working so much, let it make a pause
                time.sleep(self._queue_sleep)
        # time elapsed... we can raise the Empty exception
        raise Empty



    def _get_from_queue_without_waiting(self, my_queue, filter_type = None, filter_schema = None, filter_data = None, nb_rec = 0, timeout = None):
        """ Get an item from queue (recursive function)
            Checks are made on : 
            - life expectancy of message
            - filter given
            - size of queue
            If necessary, each item of queue is read.
            @param my_queue : queue to get data from
            @param filter_type : filter on a schema type
            @param filter_schema : filter on a specific schema
            @param filter_data : dictionnay of filters. Examples :
                - {"command" : "start", ...}
                - {"plugin" : "wol%", ...} : here "%" indicate that we search for something starting with "wol"
            @param nb_rec : internal parameter (do not use it for first call). Used to check recursivity VS queue size
            @param timeout : to use a different timeout from default one
        """
        if timeout == None:
            timeout = self._queue_timeout
        self.log_queue.debug("Get from queue : %s (recursivity deepth : %s)" % (str(my_queue), nb_rec))
        # check if recursivity doesn't exceed queue size
        if nb_rec > my_queue.qsize():
            self.log_queue.warning("Get from queue %s : number of call exceed queue size (%s) : return None" % (str(my_queue), my_queue.qsize()))
            # we raise an "Empty" exception because we consider that if we don't find
            # the good data, it is as if it was "empty"
            raise Empty

        msg_time, message = my_queue.get(True, timeout)

        # if message not too old, we process it
        if time.time() - msg_time < self._queue_life_expectancy:
            # no filter defined
            if filter_type == None and filter_schema == None and filter_data == None: 
                self.log_queue.debug("Get from queue %s : return %s" % (str(my_queue), str(message)))
                return message

            # we want to filter data
            else:
                keep_data = True
                if filter_type != None and filter_type.lower() != message.type.lower():
                    keep_data = False
                if filter_schema != None and filter_schema.lower() != message.schema.lower():
                    keep_data = False

                if filter_data != None and keep_data == True:
                    # data
                    self.log_queue.debug("Filter on message %s WITH %s" % (message.data, filter_data))
                    for key in filter_data:
                        # take care of final "%" in order to search data starting by filter_data[key]
                        if filter_data[key][-1] == "%":
                            if message.data.has_key(key):
                                msg_data = str(message.data[key])
                                my_filter_data = str(filter_data[key])
                                len_data = len(my_filter_data) - 1
                                if msg_data[0:len_data] != my_filter_data[0:-1]:
                                    keep_data = False
                            else:
                                keep_data = False
                        # normal search
                        else:
                            if message.data.has_key(key):
                                if message.data[key].lower() != filter_data[key].lower():
                                    keep_data = False
                            else:
                                keep_data = False
    
                # if message is ok for us, return it
                if keep_data == True:
                    self.log_queue.debug("Get from queue %s : return %s" % (str(my_queue), str(message)))
                    return message

                # else, message get back in queue and get another one
                else:
                    self.log_queue.debug("Get from queue %s : bad data, check another one..." % (str(my_queue)))
                    self._put_in_queue(my_queue, message)
                    return self._get_from_queue_without_waiting(my_queue, filter_type, filter_schema, filter_data, nb_rec + 1, timeout)

        # if message too old : get an other message
        else:
            self.log_queue.debug("Get from queue %s : data too old, check another one..." % (str(my_queue)))
            return self._get_from_queue_without_waiting(my_queue, filter_type, filter_schema, filter_data, nb_rec + 1, timeout)

    def _put_in_queue(self, my_queue, message):
        """ put a message in a named queue
            @param my_queue : queue 
            @param message : data to put in queue
        """
        self.log_queue.debug("Put in queue %s : %s" % (str(my_queue), str(message)))
        try:
            my_queue.put((time.time(), message), True, self._queue_timeout) 

        # Clean queue to make space
        except Full:
            msg = "Queue '%s' is full : cleaning it to make some space..." % my_queue
            self.log_queue.debug(msg)
            print(msg)
            # queue is full : start cleaning it
            nb_ck = 0
            while nb_ck < my_queue.qsize():
                (q_time, q_data) = my_queue.get()
                # data to keep
                if time.time() - self._queue_life_expectancy < q_time:
                    my_queue.put((q_time, q_data), True, self._queue_timeout)
                nb_ck += 1
            my_queue.put((time.time(), message), True, self._queue_timeout) 
            self.log_queue.debug("Cleaning finished")
              
    def _discover_hosts(self):
        """ Send a hbeat.request to discover managers
        """
        mess = XplMessage()
        mess.set_type('xpl-cmnd')
        mess.set_target("*")
        mess.set_schema('hbeat.request')
        mess.add_data({'command' : 'request'})
        self.myxpl.send(mess)

    def _list_hosts(self, message):
        """ Maintain list of Domogik hosts
            @param message : hbeat.app xpl message
        """
        tmp1 = message.source.split(".")
        tmp2 = tmp1[0].split("-")
        vendor = tmp2[0]
        device = tmp2[1]
        instance = tmp1[1]
        if vendor == "domogik" and device == "manager":
             # host not in the list
             if self._hosts_list.has_key(instance) == False:
                 self._hosts_list[instance] = {"primary" : False}
             self._hosts_list[instance]["status"] = "on"
             self._hosts_list[instance]["last_seen"] = time.time()
             self._hosts_list[instance]["interval"] = 60 * int(message.data["interval"])
             self._hosts_list[instance]["ip"] = message.data["remote-ip"]
             self._hosts_list[instance]["id"] = instance
                

    def _refresh_status_for_list_hosts(self):
        """ Check if hosts has disappeared
        """
        now = time.time()
        for instance in self._hosts_list:
            if (now - self._hosts_list[instance]["last_seen"] > self._hosts_list[instance]["interval"]):
                self._hosts_list[instance]["status"] = "off"


    def _get_installed_packages_from_manager(self):
        """ Send a xpl message to all managers to get installed packages list
        """

        ### Send xpl message to get list
        message = XplMessage()
        message.set_type("xpl-cmnd")
        message.set_schema("domogik.package")
        message.add_data({"command" : "installed-packages-list"})
        message.add_data({"host" : "*"})
        self.myxpl.send(message)


    def get_installed_packages(self):
        """ return list of installed packages
            There is a semaphore in order not to return the list when it is
            updated (may be incomplete)
        """
        # developper mode : all plugins are installed

        # TODO : remove log lines after tests
        self.log.debug("*** get_installed_packages")
        self.sema_installed.acquire()
        self.log.debug("*** sema acquired")
        ret = self._installed_packages
        self.sema_installed.release()
        self.log.debug("*** sema released")
        return ret

    def _list_installed_packages(self, message):
        """ Called when a list of installed packages is received
            @param host : host
            @param pkg_type : type of package
        """
        print("Get new installed packages list")
        self.log.debug("Get new installed packages list")
        self.sema_installed.acquire()
        self.log.debug("*** sema acquired")
        self.log.debug("*** msg = %s" % message)
        # process message
        host = message.data["host"]
        self._installed_packages[host] = {}

        pkg_mgr = PackageManager()
        idx = 0
        loop_again = True
        self.log.debug("*** before while")
        while loop_again:
            try:
                self.log.debug("*** in while : idx=%s" % idx)
                pkg_type = message.data["type"+str(idx)]
                if  message.data["enabled"+str(idx)].lower() == "yes":
                    enabled = True
                else:
                    enabled = False
                data = {"fullname" : message.data["fullname"+str(idx)],
                        "id" : message.data["id"+str(idx)],
                        "version" : message.data["version"+str(idx)],
                        "type" : message.data["type"+str(idx)],
                        #"source" : message.data["source"+str(idx)],
                        "enabled" : enabled}
                self.log.debug("*** call get_available_updates(%s, %s, %s)" % (data["type"], data["id"], data["version"]))
                updates = pkg_mgr.get_available_updates(data["type"], data["id"], data["version"])
                self.log.debug("*** after get_available_updates")
                data["updates"] = updates
                if self._installed_packages[host].has_key(pkg_type) == False:
                    self._installed_packages[host][pkg_type] = []
                self._installed_packages[host][pkg_type].append(data)
                self.log.debug("*** before idx += 1")
                idx += 1
            except KeyError:
                self.log.debug("*** except keyerror")
                loop_again = False
            except:
                self.log.debug("*** except global")
                self.log.error("Error while creating list of installed packages : %s" % traceback.format_exc())
                loop_again = False
        self.log.debug("*** before release")
        self.sema_installed.release()
        self.log.debug("*** sema released")
    



    def start_http(self):
        """ Start HTTP Server
        """
        # Start HTTP server
        self.log.info("Start HTTP Server on %s:%s..." % (self.server_ip, self.server_port))

        if self.use_ssl:
            self.server = HTTPSServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \
                                         handler_params = [self])
        else:
            self.server = HTTPServerWithParam((self.server_ip, int(self.server_port)), RestHandler, \
                                         handler_params = [self])

        self.server.serve_forever()



    def stop_http(self):
        """ Stop HTTP Server
        """
        self.server.stop_handling()



    def start_stats(self):
        """ Start Statistics manager
        """
        print("Start Stats")
        self.log.info("Starting statistics manager. Its logs will be in a dedicated log file")
        self.stat_mgr = StatsManager(handler_params = [self], xpl = self.myxpl)
        self.stat_mgr.load()
        self.log.info("Stat manager started")

    def reload_stats(self):
        """ Reload Statistics manager
        """
        time.sleep(1)
        print("Reload Stats")
        self.log.info("Reloading statistics manager. Its logs will be in a dedicated log file")
        self.stat_mgr.load()

    def get_exception(self):
        """ Get exception and display it on stdout
        """
        my_exception =  str(traceback.format_exc()).replace('"', "'")
        print("==== Error in REST ====")
        print(my_exception)
        print("=======================")
        return my_exception
Esempio n. 48
0
class Proxy(XplPlugin):
    """ REST Proxy
        - create a HTTP server
        - process REST proxy requests
    """
    def __init__(self, proxy_ip, proxy_port):
        """
        Initiate properties
        Then, start HTTP server and give it initialized data
        @param proxy_ip :  ip of the proxy server
        @param proxy_port :  port of proxy server
        """

        XplPlugin.__init__(self, name='proxy', reload_cb=self.reload_config)
        # logging initialization
        self.log.info("Proxy initialisation ...")
        self.log.debug("locale : %s %s" % locale.getdefaultlocale())
        self._config = Query(self.myxpl, self.log)
        self.server = None
        self.server_process = None
        self.proxy_ip = None
        self.proxy_port = None
        self.use_ssl = False
        self.ssl_certificate = None
        self.server_ip = None
        self.server_port = None
        self.auth_method = None
        self.username = None
        self.password = None
        self.add_stop_cb(self.stop_http)
        self.enable_hbeat()
        self.reload_config()
        #self.log.info("Proxy initialisation done")

    def reload_config(self):
        '''
        Load configuration an start proxy server
        '''
        if self.server != None:
            self.stop_http()
            self.server = None
            self.server_process = None
        try:
            cfg_rest = Loader('rest')
            config_rest = cfg_rest.load()
            conf_rest = dict(config_rest[1])
            self.server_ip = conf_rest['rest_server_ip']
            self.server_port = conf_rest['rest_server_port']
        except KeyError:
            self.log.error(
                "Can't retrieve REST configuration from domogik.cfg. Leave plugin."
            )
            self.force_leave()
        try:
            self.proxy_ip = self._config.query('proxy', 'proxy-ip')
            self.proxy_port = self._config.query('proxy', 'proxy-port')
        except:
            self.log.warning(
                "Can't get proxy address configuration from XPL. Use default value."
            )
        finally:
            if self.proxy_ip == None:
                self.proxy_ip = self.server_ip
            try:
                self.proxy_port = int(self.proxy_port)
            except:
                self.proxy_port = str(int(self.server_port) + 1)
        try:
            self.auth_method = self._config.query('proxy', 'auth-method')
        except:
            self.log.warning(
                "Can't get authentification method from XPL. Use basic by default."
            )
        finally:
            if self.auth_method == None:
                self.auth_method = "basic"
        try:
            self.username = self._config.query('proxy', 'username')
            self.password = self._config.query('proxy', 'password')
        except:
            self.log.warning(
                "Can't get username/password from XPL. Use defaults.")
        finally:
            if self.username == None or self.username == "None":
                self.username = "******"
            if self.password == None or self.password == "None":
                self.password = "******"
        try:
            boo = self._config.query('proxy', 'use-ssl')
            #print boo
            self.use_ssl = True if boo == "True" else False
            if self.use_ssl:
                cfg_rest = Loader('rest')
                config_rest = cfg_rest.load()
                conf_rest = dict(config_rest[1])
                self.ssl_certificate = conf_rest['rest_ssl_certificate']
        except KeyError:
            self.log.warning(
                "Can't get ssl configuration from XPL. Do not use it.")
            self.use_ssl = False
            self.ssl_certificate = None
        self.log.info("Proxy configuration  : ip:port = %s:%s" %
                      (self.proxy_ip, self.proxy_port))
        if self.use_ssl == True:
            self.log.info(
                "Proxy configuration : SSL support activated (certificate : %s)"
                % self.ssl_certificate)
        else:
            self.log.info("Proxy configuration : SSL support not activated")
        self.log.info("Proxy authentification  : %s" % (self.auth_method))
        self.log.info("Rest configuration : ip:port = %s:%s" %
                      (self.server_ip, self.server_port))
        try:
            self.start_http()
        except:
            self.log.error("Can't start proxy. Leave plugin.")
            self.log.error("%s" %
                           str(traceback.format_exc()).replace('"', "'"))
            self.force_leave()

    def start_http(self):
        """
        Start HTTP proxy
        """
        # Start HTTP proxy
        self.log.info("Start HTTP proxy on %s:%s..." %
                      (self.proxy_ip, self.proxy_port))
        if self.use_ssl:
            self.server = HTTPSServerWithParam((self.proxy_ip, int(self.proxy_port)), \
                                            (self.server_ip, int(self.server_port)), \
                                            self.get_stop(), self.log, self.auth_method, \
                                            self.username, self.password, \
                                            ProxyHandler, bind_and_activate=True, handler_params = [self])
        else:
            self.server = HTTPServerWithParam((self.proxy_ip, int(self.proxy_port)), \
                                            (self.server_ip, int(self.server_port)), \
                                            self.get_stop(), self.log, self.auth_method, \
                                            self.username, self.password, \
                                            ProxyHandler, bind_and_activate=True, handler_params = [self])
        self.server.serve_forever()
        #self.log.info("HTTP proxy started.")
        #self.server.server_bind()
        #self.server.server_activate()
        #self.server_process = threading.Thread(None,
        #                    self.server.serve_forever(),
        #                    "rest_proxy",
        #                    (),
        #                    {})
        #self.log.info("HTTP proxy started.")
        #self.server_process.start()

    def stop_http(self):
        """
        Stop HTTP proxy
        """
        if self.server != None:
            self.server.stop_handling()
Esempio n. 49
0
class ZiBaseMain(XplPlugin):
    '''Manage ZiBase
    '''
    def __init__(self):
        """ Create lister and launch bg listening
        """
        XplPlugin.__init__(self, name='zibase')

        self._config = Query(self.myxpl, self.log)

        self.address = self._config.query('zibase', 'ip')
        self.inter = self._config.query('zibase', 'interface')
        self.port = int(self._config.query('zibase', 'port'))
        self.valvar = self._config.query('zibase', 'envar')
        self.interv = int(self._config.query('zibase', 'interv'))

        self.log.info("Creating listener for ZiBase")
        Listener(self.zibase_command, self.myxpl, {
            'schema': 'zibase.basic',
            'xpltype': 'xpl-cmnd'
        })

        try:
            self.ip_host = get_ip_address(self.inter)
            self.log.debug("Adress IP Host=%s" % (self.ip_host))
        except:
            self.log.error("IP Host not found=%s" % (traceback.format_exc()))
            return

        try:
            self.api = APIZiBase(self.log, self.address)
        except:
            self.log.error("API ZiBase error=%s" % (traceback.format_exc()))
            return

        try:
            self.th = ServerZiBase(self.log, self.ip_host, self.port,
                                   self.myxpl)
            self.th.start()
        except:
            self.log.error("Server ZiBase error=%s" % (traceback.format_exc()))
            self.stop()

        try:
            self.api.Connect(self.ip_host, self.port)
        except:
            self.log.error("Connection ZiBase error=%s" %
                           (traceback.format_exc()))
            self.stop()

        if self.valvar == "True":
            try:
                self.log.info("Start reading internal variables")
                var_read = XplTimer(self.interv, self.zibase_read_var,
                                    self.myxpl)
                var_read.start()
            except:
                self.log.error("reading internal variables error")
                return

        self.add_stop_cb(self.stop)
        self.enable_hbeat()

        self.log.info("Plugin ready :)")

    def zibase_command(self, message):
        """ Call zibase lib function in function of given xpl message
            @param message : xpl message
        """
        commands = {
            'off': 0,
            'on': 1,
            'preset-dim': 2,
        }
        protocols = {
            'PRESET': 0,
            'VISONIC433': 1,
            'VISONIC868': 2,
            'CHACON': 3,
            'DOMIA': 4,
            'X10': 5,
            'ZWAVE': 6,
            'RFS10': 7,
            'XDD433AL': 8,
            'XDD868AL': 9,
            'XDD868INSH': 10,
            'XDD868PILOT': 11,
            'XDD868BOAC': 12,
        }

        cmd = None
        dev = None
        protocol = None
        preset_dim = 0

        if 'command' in message.data:
            cmd = message.data['command']
        if 'device' in message.data:
            chaine = message.data['device'].split(':')
            try:
                dev = chaine[0].upper()
                protocol = chaine[1].upper()
            except:
                self.log.error("Syntax device not valid")
        if 'preset-dim' in message.data:
            preset_dim = message.data['preset-dim']

        self.log.debug(message.data)
        if protocol == None:
            self.log.warning("Protocol not specified")
            return
        else:
            self.log.debug(
                "%s received : device = %s protocol = %s number protocol=%s preset=%s"
                % (cmd, dev, protocol, protocols[protocol], str(preset_dim)))
            try:
                self.api.sendCommand(dev, commands[cmd], protocols[protocol],
                                     int(preset_dim))
            except:
                self.log.error("Sendcommand error")
                return

            self.th.send_xpl_cmd(message.data['device'], cmd, preset_dim)

    def stop(self):
        self.log.debug("Stop plugin in progress...")
        self.var_read.stop()
        self.api.Disconnect(self.ip_host, self.port)
        self.th.stop()
        return

    def zibase_read_var(self):
        try:
            datas = self.api.getVariables()
            for data in datas:
                elmt = data.split(':')
                stats = ['sta:' + elmt[1]]
                self.th.send_xpl_sensor(stats, elmt[0], 'xpl-stat')
        except:
            self.log.error("Read var error=%s" % (traceback.format_exc()))
Esempio n. 50
0
class RfxcomUsbManager(XplPlugin):
    """ Manage the Rfxcom Usb device and connect it to xPL
    """

    def __init__(self):
        """ Init plugin
        """
        XplPlugin.__init__(self, name='rfxcom')
        # Get config
        #   - device
        self._config = Query(self.myxpl, self.log)
        device = self._config.query('rfxcom', 'device')
        if device == None:
            self.log.error('Device is not configured, exiting') 
            print('Device is not configured, exiting')
            self.force_leave()
            return

        # Init RFXCOM
        self.rfxcom  = RfxcomUsb(self.log, self.send_xpl, self.send_trig, self.get_stop())
        
        # Create a listener for all messages used by RFXCOM
        # TODO !!!!!
        # Create listeners
        Listener(self.process_x10_basic, self.myxpl, 
                 {'schema': 'x10.basic',
                  'xpltype': 'xpl-cmnd'})        
        Listener(self.process_x10_security, self.myxpl, 
                 {'schema': 'x10.securiy',
                  'xpltype': 'xpl-cmnd'})        
        Listener(self.process_ac_basic, self.myxpl, 
                 {'schema': 'ac.basic',
                  'xpltype': 'xpl-cmnd'})        
        Listener(self.process_remote_basic, self.myxpl, 
                 {'schema': 'remote.basic',
                  'xpltype': 'xpl-cmnd'})        
        Listener(self.process_control_basic, self.myxpl, 
                 {'schema': 'control.basic',
                  'xpltype': 'xpl-cmnd'})        
        
        # Open RFXCOM
        try:
            self.rfxcom.open(device)
        except RfxcomException as e:
            self.log.error(e.value)
            print(e.value)
            self.force_leave()
            return
            
        # Start reading RFXCOM
        rfxcom_process = threading.Thread(None,
                                   self.rfxcom.listen,
                                   "rfxcom-process-reader",
                                   (self.get_stop(),),
                                   {})
        self.register_thread(rfxcom_process)
        rfxcom_process.start()
        self.enable_hbeat()

    # lighting1
    def process_x10_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        address = message.data["device"].lower()
        command = message.data["command"].lower()
        if message.data.has_key("level"):
            level = message.data["level"].lower()
        else:
            level = 0
        if message.data.has_key("protocol"):
            protocol = message.data["protocol"].lower()
        else:
            protocol = "x10"

        # Prepare xpl-trig to send if success
        trig_msg = message
        trig_msg.set_type("xpl-trig")

        # call appropriate function
        if protocol in ("x10", "arc", "elro", "waveman", "chacon", "impuls"):
            self.rfxcom.command_10(address, command, protocol, trig_msg)
        elif protocol in ("koppla"):
            self.rfxcom.command_12(address, command, level, protocol, trig_msg)
        elif protocol in ("harrison"):
            self.rfxcom.command_18(address, command, protocol, trig_msg)

    def process_x10_security(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        address = message.data["device"].lower()
        command = message.data["command"].lower()
        if message.data.has_key("delay"):
            delay = message.data["delay"].lower()
        else:
            delay = None

        # Prepare xpl-trig to send if success
        trig_msg = message
        trig_msg.set_type("xpl-trig")

        self.rfxcom.command_20(address, command, delay, trig_msg)
        
    def process_ac_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        # TODO : finish
        address = message.data["address"].lower()
        unit = message.data["unit"]
        if unit.lower() == "group":
            unit = 0
            group = True
        else:
            unit = int(unit)
            group = False
        command = message.data["command"].lower()
        if command == "preset":
            level = int(message.data["level"])
        else:
            level = 0
        if message.data.has_key("eu"):
            eu = message.data["eu"]
        else:
            eu = False
        # Prepare xpl-trig to send if success
        trig_msg = message
        trig_msg.set_type("xpl-trig")
        self.rfxcom.command_11(address, unit, command, level, eu, group, trig_msg)
        
    def process_remote_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        # TODO
        pass
        
    def process_control_basic(self, message):
        """ Process command xpl message and call the librairy for processing command
            @param message : xpl message
        """
        msg_type = message.data["type"]
        msg_current = message.data["current"]
        msg_device = message.data["current"]
        self.log.debug("CONTROL.BASIC received : device = %s, type = %s, current = %s" % (msg_device, msg_type, msg_current))
        self.rfxcom.xplcmd_control_basic(device = msg_device,
                                         type = msg_type,
                                         current = msg_current)

    def send_xpl(self, schema, data = {}):
        """ Send xPL message on network
        """
        print("schema:%s, data:%s" % (schema, data))
        self.log.debug("schema:%s, data:%s" % (schema, data))
        msg = XplMessage()
        msg.set_type("xpl-trig")
        msg.set_schema(schema)
        for key in data:
            msg.add_data({key : data[key]})
        self.myxpl.send(msg)

    def send_trig(self, message):
        """ Send xpl-trig given message
            @param message : xpl-trig message
        """
        self.myxpl.send(message)
Esempio n. 51
0
class NBZNotificationListener(XplPlugin):
    """ Create listener for xPL messages about Nabaztag TTS notification
    """

    def __init__(self):
        """ Create listener for Nabaztag TTS notification
        """
        XplPlugin.__init__(self, name="nbz_tts")
        # Create logger
        self.log.debug("Listener for Nabaztag TTS notification created")

        # Configuration : list of nabaztag whith serial, token and voice
        self.alias_list = {}
        num = 1
        loop = True
        self._config = Query(self.myxpl, self.log)
        while loop == True:
            nabaztag = self._config.query("nbz_tts", "name-%s" % str(num))
            serial = self._config.query("nbz_tts", "serial-%s" % str(num))
            token = self._config.query("nbz_tts", "token-%s" % str(num))
            voice = self._config.query("nbz_tts", "voice-%s" % str(num))
            if nabaztag != None:
                mess = (
                    "Configuration : nabaztag="
                    + str(nabaztag)
                    + " , serial="
                    + str(serial)
                    + ", token="
                    + str(token)
                    + ", voice="
                    + str(voice)
                )
                self.log.info(mess)
                print(mess)
                self.alias_list[nabaztag] = {"nabaztag": nabaztag, "serial": serial, "token": token, "voice": voice}
                num += 1
            else:
                loop = False

        # no nabaztag configured
        if num == 1:
            msg = "No nabaztag configured. Exiting plugin"
            self.log.info(msg)
            print(msg)
            self.force_leave()
            return

        # Check serial
        for alias in self.alias_list:
            if str(self.alias_list[alias]["serial"]) != "None":
                self.log.debug(
                    "Serial for nabaztag "
                    + str(self.alias_list[alias]["nabaztag"])
                    + " is "
                    + str(self.alias_list[alias]["serial"])
                )
            else:
                self.log.error(
                    "Can't find the serial for the nabaztag "
                    + str(self.alias_list[alias]["nabaztag"])
                    + " , please check the configuration page of this plugin"
                )
                self.force_leave()
                return

        # Check token
        for alias in self.alias_list:
            if str(self.alias_list[alias]["token"]) != "None":
                self.log.debug(
                    "Token for nabaztag "
                    + str(self.alias_list[alias]["nabaztag"])
                    + " is "
                    + str(self.alias_list[alias]["token"])
                )
            else:
                self.log.error(
                    "Can't find the Token for the nabaztag "
                    + str(self.alias_list[alias]["nabaztag"])
                    + " , please check the configuration page of this plugin"
                )
                self.force_leave()
                return

        # Check voice
        for alias in self.alias_list:
            if str(self.alias_list[alias]["voice"]) != "None":
                self.log.debug(
                    "Voice for nabaztag "
                    + str(self.alias_list[alias]["nabaztag"])
                    + " is "
                    + str(self.alias_list[alias]["voice"])
                )
            else:
                self.log.error(
                    "Can't find the Voice for the nabaztag "
                    + str(self.alias_list[alias]["nabaztag"])
                    + " , please check the configuration page of this plugin"
                )
                self.force_leave()
                return

        # Create NBZNotification object
        self.nbz_notification_manager = NBZNotification(self.log)

        # Create listeners
        Listener(self.nbz_notification_cb, self.myxpl, {"schema": "sendmsg.push", "xpltype": "xpl-cmnd"})
        self.enable_hbeat()

    def nbz_notification_cb(self, message):
        """ Call Nabaztag TTS lib
            @param message : message to send
        """
        self.log.debug("Call nbz_notification_cb")

        # mandatory keys
        if "to" in message.data:
            to = message.data["to"]
            for alias in self.alias_list:
                try:
                    if str(self.alias_list[alias]["nabaztag"]) == str(to):
                        serialkey = self.alias_list[alias]["serial"]
                        tokenkey = self.alias_list[alias]["token"]
                        voicekey = self.alias_list[alias]["voice"]
                except:
                    self.log.debug("Can't find the recipient, please check the configuration page of this plugin")
                    self.force_leave()
                    return
        else:
            self.log.warning("No recipient was found in the xpl message")
            return

        if "body" in message.data:
            body = message.data["body"]
        else:
            self.log.warning("No message was found in the xpl message")
            return

        self.log.debug(
            "Call send_tts with following parameters : serial="
            + serialkey
            + ", token="
            + tokenkey
            + ", message="
            + body
            + ", voice="
            + voicekey
        )
        self.nbz_notification_manager.send_tts(serialkey, tokenkey, body, voicekey)