def cmd_fake(self, message): ### sub send an answer for fake device of scene plugin if message.data['number'] not in self.fake_stat: self.fake_stat[message.data['number']] = '' if message.data['command'] == "fake-true" or message.data[ 'command'] == "fake-false" and message.type == "xpl-cmnd": print("Réception xpl cmnd") msg = XplMessage() msg.set_schema('scene.basic') sender = "domogik-scene0.%s" % self.get_sanitized_hostname() msg.set_source(sender) if self.fake_stat[ message.data['number']] != message.data['command']: msg.set_type('xpl-trig') self.fake_stat[ message.data['number']] = message.data['command'] else: msg.set_type('xpl-stat') if message.data['command'] == "fake-true": msg.add_data({'stats': 'true'}) if message.data['command'] == "fake-false": msg.add_data({'stats': 'false'}) msg.add_data({'number': message.data['number']}) self.myxpl.send(msg)
def forge_message(self): ''' Create the message based on script arguments ''' message = XplMessage() message.set_type(self.options.type) if self.options.source != None: print(u"Source forced : %s" % self.options.source) message.set_source(self.options.source) if self.options.target != None: print(u"Target forced : %s" % self.options.target) message.set_target(self.options.target) message.set_schema(self.options.schema) datas = self.options.message.split(',') for data in datas: if "=" not in data: self.log.error(u"Bad formatted commands. Must be key=value") self.usage() exit(4) else: message.add_data({ data.split("=", 1)[0].strip(): data.split("=", 1)[1].strip() }) return message
def send_msg_plugin(self, run, stats): ### send a message with the plugin name as source msg=XplMessage() msg.set_source(self.senderplug) msg.set_schema('scene.basic') msg.set_type('xpl-trig') msg.add_data({'number': self.number}) msg.add_data({'run':run}) msg.add_data({'stats':stats}) self.myxpl.send(msg)
def send_msg_plugin(self, run, stats): ### send a message with the plugin name as source msg = XplMessage() msg.set_source(self.senderplug) msg.set_schema('scene.basic') msg.set_type('xpl-trig') msg.add_data({'number': self.number}) msg.add_data({'run': run}) msg.add_data({'stats': stats}) self.myxpl.send(msg)
def send_msg_scene(self, type, run, stats): ### send a message with the scene name as source msg = XplMessage() msg.set_source(self.senderscene) msg.set_schema('scene.basic') msg.set_type(type) msg.add_data({'number': self.number}) msg.add_data({'run': run}) msg.add_data({'stats': stats}) self.myxpl.send(msg) self.log_scene('info', "Send and xpl message: %s" % msg)
def send_msg_scene(self,type, run, stats): ### send a message with the scene name as source msg=XplMessage() msg.set_source(self.senderscene) msg.set_schema('scene.basic') msg.set_type(type) msg.add_data({'number': self.number}) msg.add_data({'run':run}) msg.add_data({'stats':stats}) self.myxpl.send(msg) self.log_scene('info', "Send and xpl message: %s" %msg)
def send_xpl(self,data): print("send xpl...") msg=XplMessage() senderscene = "domogik-scene.%s" %self.get_sanitized_hostname() msg.set_source(senderscene) msg.set_schema('scene.basic') msg.set_type('xpl-trig') msg.add_data({'command': 'Create-ack'}) msg.add_data({'scene': '0'}) msg.add_data({'data':data}) self.myxpl.send(msg) self.log.info("scene sucessfully create")
def send_xpl(self, data): print("send xpl...") msg = XplMessage() senderscene = "domogik-scene.%s" % self.get_sanitized_hostname() msg.set_source(senderscene) msg.set_schema('scene.basic') msg.set_type('xpl-trig') msg.add_data({'command': 'Create-ack'}) msg.add_data({'scene': '0'}) msg.add_data({'data': data}) self.myxpl.send(msg) self.log.info("scene sucessfully create")
def send_action_xpl(self, action): ### Send an xpl message define in scene action ### action['type_message'] =xpl-type ### action['schema'] = xpl schema ### action['value'] = xpl val msg=XplMessage() msg.set_source(self.senderscene) msg.set_schema(action['schema']) msg.set_type(action['type_message']) # if "Eval" in action['value'] or "eval" in action['value']: # msg.add_data(eval(action['value'].replace('Eval',''))) # else: # msg.add_data(action['value']) msg.add_data(action['value']) self.myxpl.send(msg)
def send_action_xpl(self, action): ### Send an xpl message define in scene action ### action['type_message'] =xpl-type ### action['schema'] = xpl schema ### action['value'] = xpl val msg = XplMessage() msg.set_source(self.senderscene) msg.set_schema(action['schema']) msg.set_type(action['type_message']) # if "Eval" in action['value'] or "eval" in action['value']: # msg.add_data(eval(action['value'].replace('Eval',''))) # else: # msg.add_data(action['value']) msg.add_data(action['value']) self.myxpl.send(msg)
def _SendHeartbeat(self, target="*", test="", schema="hbeat.app"): """ Send heartbeat message in broadcast on the network, on the bus port (3865) This make the application able to be discovered by the hub This method is not called by childs, so no need to protect it. """ self._lock_status.acquire() self.p.log.debug("send hbeat") mesg = XplMessage() mesg.set_type("xpl-stat") mesg.set_hop_count(1) mesg.set_source(self._source) mesg.set_target(target) mesg.set_schema(schema) mesg.add_single_data("interval", "5") mesg.add_single_data("port", self.port) mesg.add_single_data("remote-ip", self._ip) if schema != "hbeat.end": if self._status == 0: msg = ( "HUB discovery > looking for the hub. I hope there is one hub, Domogik won't work without the hub!" ) self.p.log.info(msg) print(msg) elif self._status == 1: msg = "HUB discovery > hub found, configuration in progress" self.p.log.info(msg) print(msg) elif self._status == 2: pass else: msg = ( "Oops! Wrong status for the hbeat message : %s. Please create a bug report for this!" % self._status ) self.p.log.warning(msg) print(msg) mesg.add_single_data("status", self._status) if self is not None: self.send(mesg) self._lock_status.release()
def forge_message(self): ''' Create the message based on script arguments ''' message = XplMessage() message.set_type(self.options.type) if self.options.source != None: print(u"Source forced : %s" % self.options.source) message.set_source(self.options.source) if self.options.target != None: print(u"Target forced : %s" % self.options.target) message.set_target(self.options.target) message.set_schema(self.options.schema) datas = self.options.message.split(',') for data in datas: if "=" not in data: self.log.error(u"Bad formatted commands. Must be key=value") self.usage() exit(4) else: message.add_data({data.split("=",1)[0].strip() : data.split("=",1)[1].strip()}) return message
def cmd_fake(self, message): ### sub send an answer for fake device of scene plugin if message.data['number'] not in self.fake_stat: self.fake_stat[message.data['number']]='' if message.data['command'] == "fake-true" or message.data['command'] == "fake-false" and message.type == "xpl-cmnd": print("Réception xpl cmnd") msg=XplMessage() msg.set_schema('scene.basic') sender= "domogik-scene0.%s" %self.get_sanitized_hostname() msg.set_source(sender) if self.fake_stat[message.data['number']] != message.data['command']: msg.set_type('xpl-trig') self.fake_stat[message.data['number']] = message.data['command'] else: msg.set_type('xpl-stat') if message.data['command'] == "fake-true": msg.add_data({'stats': 'true'}) if message.data['command'] == "fake-false": msg.add_data({'stats': 'false'}) msg.add_data({'number': message.data['number']}) self.myxpl.send(msg)
def _SendHeartbeat(self, target='*', test="", schema="hbeat.app"): """ Send heartbeat message in broadcast on the network, on the bus port (3865) This make the application able to be discovered by the hub This method is not called by childs, so no need to protect it. """ self._lock_status.acquire() self.p.log.debug("send hbeat") mesg = XplMessage() mesg.set_type("xpl-stat") mesg.set_hop_count(1) mesg.set_source(self._source) mesg.set_target(target) mesg.set_schema(schema) mesg.add_single_data("interval", "5") mesg.add_single_data("port", self.port) mesg.add_single_data("remote-ip", self._ip) if schema != 'hbeat.end': if self._status == 0: msg = "HUB discovery > looking for the hub. I hope there is one hub, Domogik won't work without the hub!" self.p.log.info(msg) print(msg) elif self._status == 1: msg = "HUB discovery > hub found, configuration in progress" self.p.log.info(msg) print(msg) elif self._status == 2: pass else: msg = "Oops! Wrong status for the hbeat message : %s. Please create a bug report for this!" % self._status self.p.log.warning(msg) print(msg) mesg.add_single_data("status", self._status) if self is not None: self.send(mesg) self._lock_status.release()
class XplMessageTest(unittest.TestCase): """ Test XplMessage class. """ def setUp(self): """ Setup context. The context is setup before each call to a test method. """ self.__xpl_message = XplMessage() def tearDown(self): """ clean context. The context is cleaned after each call of a test method. """ del self.__xpl_message def test_set_type(self): """ Test XplMessage.set_type() method. """ self.assertRaises(XplMessageError, self.__xpl_message.set_type, 'dummy') for type_ in ('xpl-cmnd', 'xpl-trig', 'xpl-stat'): self.__xpl_message.set_type(type_) self.assertEqual(self.__xpl_message.type, type_) def test_set_hop_count(self): """ Test XplMessage.set_hop_count() method. """ self.assertRaises(XplMessageError, self.__xpl_message.set_hop_count, 0) for i in xrange(1, 10): self.__xpl_message.set_hop_count(i) self.assertEqual(self.__xpl_message.hop_count, i) self.assertRaises(XplMessageError, self.__xpl_message.set_hop_count, 10) def test_inc_hop_count(self): """ Test XplMessage.inc_hop_count() method. """ for i in xrange(8): self.__xpl_message.inc_hop_count() self.assertRaises(XplMessageError, self.__xpl_message.inc_hop_count) def test_set_source(self): """ Test XplMessage.set_source() method. """ # Check length self.assertRaises(XplMessageError, self.__xpl_message.set_source, "xxxxxxxxx-x.x") self.assertRaises(XplMessageError, self.__xpl_message.set_source, "x-xxxxxxxxx.x") self.assertRaises(XplMessageError, self.__xpl_message.set_source, "x-x.xxxxxxxxxxxxxxxxx") # Check format self.assertRaises(XplMessageError, self.__xpl_message.set_source, "dummy") self.assertRaises(XplMessageError, self.__xpl_message.set_source, "xPL-hal.myhouse") self.__xpl_message.set_source("xpl-xplhal.myhouse") self.assertEqual(self.__xpl_message.source, "xpl-xplhal.myhouse") self.assertEqual(self.__xpl_message.source_vendor_id, "xpl") self.assertEqual(self.__xpl_message.source_device_id, "xplhal") self.assertEqual(self.__xpl_message.source_instance_id, "myhouse") def test_set_target(self): """ Test XplMessage.set_target() method. """ # Check length self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xxxxxxxxx-xxx.xxx") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xxx-xxxxxxxxx.xxx") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xxx-xxx.xxxxxxxxxxxxxxxxx") # Check format self.assertRaises(XplMessageError, self.__xpl_message.set_target, "dummy") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xPL-hal.myhouse") self.__xpl_message.set_target("acme-cm12.server") self.assertEqual(self.__xpl_message.target, "acme-cm12.server") self.assertEqual(self.__xpl_message.target_vendor_id, "acme") self.assertEqual(self.__xpl_message.target_device_id, "cm12") self.assertEqual(self.__xpl_message.target_instance_id, "server") self.__xpl_message.set_target('*') self.assertEqual(self.__xpl_message.target, '*') self.assertEqual(self.__xpl_message.target_vendor_id, None) self.assertEqual(self.__xpl_message.target_device_id, None) self.assertEqual(self.__xpl_message.target_instance_id, None) def test_set_schema(self): """ Test XplMessage.set_schema() method. """ # Check length self.assertRaises(XplMessageError, self.__xpl_message.set_schema, "xxxxxxxxx.xxx") self.assertRaises(XplMessageError, self.__xpl_message.set_schema, "xxx.xxxxxxxxx") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "x10-basic") # Check format self.assertRaises(XplMessageError, self.__xpl_message.set_schema, "dummy") self.__xpl_message.set_schema("x10.basic") self.assertEqual(self.__xpl_message.schema, "x10.basic") self.assertEqual(self.__xpl_message.schema_class, "x10") self.assertEqual(self.__xpl_message.schema_type, "basic") def test_add_single_data(self): """ Test XplMessage.test_add_single_data() method. """ # check lengths name = 'x' * 17 value = "xxx" self.assertRaises(XplMessageError, self.__xpl_message.add_single_data, name, value) name = "xxx" value = 'x' * 129 #self.assertRaises(XplMessageError, self.__xpl_message.add_single_data, name, value) # def test_set_data(self): """ Test XplMessage.set_data() method. """ self.__xpl_message.set_data({"command": "dim", "device": "a1", "level": "75"}) self.assertEqual(self.__xpl_message.data, OrderedDict({"command": "dim", "device": "a1", "level": "75"})) # Check if correctly remove previous data self.__xpl_message.set_data({"command2": "dim", "device2": "a1", "level2": "75"}) self.assertEqual(self.__xpl_message.data, OrderedDict({"command2": "dim", "device2": "a1", "level2": "75"})) def test_from_packet(self): """ Test the XplMessage.from_packet() method. """ wrong_packet = \ """xpl-cmnd { target=acme-cm12.server } { command=dim device=a1 level=75 } """ self.assertRaises(XplMessageError, self.__xpl_message.from_packet, wrong_packet) packet = \ """xpl-cmnd { hop=1 source=xpl-xplhal.myhouse target=acme-cm12.server } x10.basic { command=dim device=a1 level=75 } """ self.__xpl_message.from_packet(packet) self.assertEqual(self.__xpl_message.type, 'xpl-cmnd') self.assertEqual(self.__xpl_message.hop_count, 1) self.assertEqual(self.__xpl_message.source, "xpl-xplhal.myhouse") self.assertEqual(self.__xpl_message.source_vendor_id, "xpl") self.assertEqual(self.__xpl_message.source_device_id, "xplhal") self.assertEqual(self.__xpl_message.source_instance_id, "myhouse") self.assertEqual(self.__xpl_message.target, "acme-cm12.server") self.assertEqual(self.__xpl_message.target_vendor_id, "acme") self.assertEqual(self.__xpl_message.target_device_id, "cm12") self.assertEqual(self.__xpl_message.target_instance_id, "server") self.assertEqual(self.__xpl_message.schema, "x10.basic") self.assertEqual(self.__xpl_message.schema_class, "x10") self.assertEqual(self.__xpl_message.schema_type, "basic") self.assertEqual(self.__xpl_message.data, OrderedDict({"command": "dim", "device": "a1", "level": "75"})) def testto_packet(self): """ Test XplMessage.to_packet() method. """ packet = \ """xpl-cmnd { hop=1 source=xpl-xplhal.myhouse target=acme-cm12.server } x10.basic { command=dim device=a1 level=75 } """ self.__xpl_message.from_packet(packet) self.assertEquals(self.__xpl_message.to_packet(), packet) def test_is_valid(self): """ Test XplMessage.is_valid() method. """ packet = \ """xpl-cmnd { hop=1 source=xpl-xplhal.myhouse target=acme-cm12.server } x10.basic { command=dim device=a1 level=75 } """ self.assertEquals(self.__xpl_message.is_valid(), False) self.__xpl_message.from_packet(packet) self.assertEquals(self.__xpl_message.is_valid(), True)
def _send_xpl_command(self, data): """ Reply to config.get MQ req @param data : MQ req message Needed info in data: - cmdid => command id to send - cmdparams => key/value pair of all params needed for this command """ with self._db.session_scope(): self.log.info(u"Received new cmd request: {0}".format(data)) failed = False request = data.get_data() if 'cmdid' not in request: failed = "cmdid not in message data" if 'cmdparams' not in request: failed = "cmdparams not in message data" if not failed: # get the command cmd = self._db.get_command(request['cmdid']) if cmd is not None: if cmd.xpl_command is not None: xplcmd = cmd.xpl_command xplstat = self._db.get_xpl_stat(xplcmd.stat_id) if xplstat is not None: # get the device from the db dev = self._db.get_device(int(cmd.device_id)) msg = XplMessage() if not dev['client_id'] in self.client_xpl_map.keys(): self._load_client_to_xpl_target() if not dev['client_id'] in self.client_xpl_map.keys(): failed = "Can not fincd xpl source for {0} client_id".format(dev['client_id']) else: msg.set_target(self.client_xpl_map[dev['client_id']]) msg.set_source(self.myxpl.get_source()) msg.set_type("xpl-cmnd") msg.set_schema(xplcmd.schema) # static paramsw for par in xplcmd.params: msg.add_data({par.key : par.value}) # dynamic params for par in cmd.params: if par.key in request['cmdparams']: value = request['cmdparams'][par.key] # chieck if we need a conversion if par.conversion is not None and par.conversion != '': if dev['client_id'] in self.client_conversion_map: if par.conversion in self.client_conversion_map[dev['client_id']]: exec(self.client_conversion_map[dev['client_id']][par.conversion]) value = locals()[par.conversion](value) msg.add_data({par.key : value}) else: failed = "Parameter ({0}) for device command msg is not provided in the mq message".format(par.key) if not failed: # send out the msg self.log.debug(u"Sending xplmessage: {0}".format(msg)) self.myxpl.send(msg) xplstat = self._db.detach(xplstat) # generate an uuid for the matching answer published messages if xplstat != None: resp_uuid = uuid4() self._cmd_lock_d.acquire() self._cmd_dict[str(resp_uuid)] = xplstat self._cmd_lock_d.release() else: resp_uuid = None # send the response reply_msg = MQMessage() reply_msg.set_action('cmd.send.result') reply_msg.add_data('uuid', str(resp_uuid)) reply_msg.add_data('status', True) reply_msg.add_data('reason', None) self.log.debug(u"mq reply (success) : {0}".format(reply_msg.get())) self.reply(reply_msg.get()) if failed: self.log.error(failed) reply_msg = MQMessage() reply_msg.set_action('cmd.send.result') reply_msg.add_data('uuid', None) reply_msg.add_data('status', False) reply_msg.add_data('reason', failed) self.log.debug(u"mq reply (failed) : {0}".format(reply_msg.get())) self.reply(reply_msg.get())
def _send_xpl_command(self, cmd, request): """ Reply to config.get MQ req @param data : MQ req message Needed info in data: - cmdid => command id to send - cmdparams => key/value pair of all params needed for this command """ self.log.debug(u" => Generating XPL message to plugin") failed = False xplcmd = cmd['xpl_command'] #xplstat = self._db.get_xpl_stat(xplcmd['stat_id']) xplstat = self.all_xpl_stats[str(xplcmd['stat_id'])] if xplstat is not None: # get the device from the db dev = self.all_devices[str(cmd['device_id'])] msg = XplMessage() if not dev['client_id'] in self.client_xpl_map.keys(): self._load_client_to_xpl_target() if not dev['client_id'] in self.client_xpl_map.keys(): failed = "Can not fincd xpl source for {0} client_id".format( dev['client_id']) else: ### Fix bug #349 # I am not totally sure why before we used the xpl_source from the client list. # Indeed for domogik xpl plugins it helps to target the appropriate plugin but # for xpl messages for outside of domogik, this is a blocking point ! # As xpl plugins are starting to be deprecated as the 'common plugin format', it # should not be an issue to retarget xpl messages to '*' for now and later on if # there is a real need to target on a dedicated target, implement a bette way to # handle this # -- Fritz -- oct 2016 #msg.set_target(self.client_xpl_map[dev['client_id']]) msg.set_target("*") ### End of fix msg.set_source(self.myxpl.get_source()) msg.set_type("xpl-cmnd") msg.set_schema(xplcmd['schema']) # static paramsw for par in xplcmd['params']: msg.add_data({par['key']: par['value']}) # dynamic params for par in cmd['params']: if par['key'] in request['cmdparams']: value = request['cmdparams'][par['key']] # check if we need a conversion if par['conversion'] is not None and par[ 'conversion'] != '': if dev['client_id'] in self.client_conversion_map: if par['conversion'] in self.client_conversion_map[ dev['client_id']]: self.log.debug( \ u" => Calling conversion {0}".format(par['conversion'])) exec(self.client_conversion_map[ dev['client_id']][par['conversion']]) value = locals()[par['conversion']](value) self.log.debug( \ u" => Command parameter after conversion {0} = {1}".format(par['key'], value)) msg.add_data({par['key']: value}) else: failed = "Parameter ({0}) for device command msg is not provided in the mq message".format( par['key']) if not failed: # send out the msg self.log.debug(u" => Sending xplmessage: {0}".format(msg)) try: self.myxpl.send(msg) except XplMessageError as msg: failed = msg #xplstat = self._db.detach(xplstat) # generate an uuid for the matching answer published messages if xplstat != None: resp_uuid = uuid4() self._cmd_lock_d.acquire() self._cmd_dict[str(resp_uuid)] = xplstat self._cmd_lock_d.release() else: resp_uuid = None return True, resp_uuid, None if failed: self.log.error(failed) return False, None, failed
def _send_xpl_command(self, cmd, request): """ Reply to config.get MQ req @param data : MQ req message Needed info in data: - cmdid => command id to send - cmdparams => key/value pair of all params needed for this command """ self.log.debug(u" => Generating XPL message to plugin") failed = False xplcmd = cmd['xpl_command'] #xplstat = self._db.get_xpl_stat(xplcmd['stat_id']) xplstat = self.all_xpl_stats[str(xplcmd['stat_id'])] if xplstat is not None: # get the device from the db dev = self.all_devices[str(cmd['device_id'])] msg = XplMessage() if not dev['client_id'] in self.client_xpl_map.keys(): self._load_client_to_xpl_target() if not dev['client_id'] in self.client_xpl_map.keys(): failed = "Can not fincd xpl source for {0} client_id".format(dev['client_id']) else: ### Fix bug #349 # I am not totally sure why before we used the xpl_source from the client list. # Indeed for domogik xpl plugins it helps to target the appropriate plugin but # for xpl messages for outside of domogik, this is a blocking point ! # As xpl plugins are starting to be deprecated as the 'common plugin format', it # should not be an issue to retarget xpl messages to '*' for now and later on if # there is a real need to target on a dedicated target, implement a bette way to # handle this # -- Fritz -- oct 2016 #msg.set_target(self.client_xpl_map[dev['client_id']]) msg.set_target("*") ### End of fix msg.set_source(self.myxpl.get_source()) msg.set_type("xpl-cmnd") msg.set_schema(xplcmd['schema']) # static paramsw for par in xplcmd['params']: msg.add_data({par['key'] : par['value']}) # dynamic params for par in cmd['params']: if par['key'] in request['cmdparams']: value = request['cmdparams'][par['key']] # check if we need a conversion if par['conversion'] is not None and par['conversion'] != '': if dev['client_id'] in self.client_conversion_map: if par['conversion'] in self.client_conversion_map[dev['client_id']]: self.log.debug( \ u" => Calling conversion {0}".format(par['conversion'])) exec(self.client_conversion_map[dev['client_id']][par['conversion']]) value = locals()[par['conversion']](value) self.log.debug( \ u" => Command parameter after conversion {0} = {1}".format(par['key'], value)) msg.add_data({par['key'] : value}) else: failed = "Parameter ({0}) for device command msg is not provided in the mq message".format(par['key']) if not failed: # send out the msg self.log.debug(u" => Sending xplmessage: {0}".format(msg)) try: self.myxpl.send(msg) except XplMessageError as msg: failed = msg #xplstat = self._db.detach(xplstat) # generate an uuid for the matching answer published messages if xplstat != None: resp_uuid = uuid4() self._cmd_lock_d.acquire() self._cmd_dict[str(resp_uuid)] = xplstat self._cmd_lock_d.release() else: resp_uuid = None return True, resp_uuid, None if failed: self.log.error(failed) return False, None, failed
def _send_xpl_command(self, data): """ Reply to config.get MQ req @param data : MQ req message Needed info in data: - cmdid => command id to send - cmdparams => key/value pair of all params needed for this command """ with self._db.session_scope(): self.log.info(u"Received new cmd request: {0}".format(data)) failed = False request = data.get_data() if 'cmdid' not in request: failed = "cmdid not in message data" if 'cmdparams' not in request: failed = "cmdparams not in message data" if not failed: # get the command cmd = self._db.get_command(request['cmdid']) if cmd is not None: if cmd.xpl_command is not None: xplcmd = cmd.xpl_command xplstat = self._db.get_xpl_stat(xplcmd.stat_id) if xplstat is not None: # get the device from the db dev = self._db.get_device(int(cmd.device_id)) msg = XplMessage() if not dev['client_id'] in self.client_xpl_map.keys(): self._load_client_to_xpl_target() if not dev['client_id'] in self.client_xpl_map.keys(): failed = "Can not fincd xpl source for {0} client_id".format(dev['client_id']) else: msg.set_target(self.client_xpl_map[dev['client_id']]) msg.set_source(self.myxpl.get_source()) msg.set_type("xpl-cmnd") msg.set_schema( xplcmd.schema) # static params for p in xplcmd.params: msg.add_data({p.key : p.value}) # dynamic params for p in cmd.params: if p.key in request['cmdparams']: value = request['cmdparams'][p.key] # chieck if we need a conversion if p.conversion is not None and p.conversion != '': if dev['client_id'] in self.client_conversion_map: if p.conversion in self.client_conversion_map[dev['client_id']]: exec(self.client_conversion_map[dev['client_id']][p.conversion]) value = locals()[p.conversion](value) msg.add_data({p.key : value}) else: failed = "Parameter ({0}) for device command msg is not provided in the mq message".format(p.key) if not failed: # send out the msg self.log.debug(u"sending xplmessage: {0}".format(msg)) self.myxpl.send(msg) ### Wait for answer stat_received = 0 if xplstat != None: # get xpl message from queue self.log.debug(u"Command : wait for answer...") sub = MQSyncSub( self.zmq, 'xplgw-command', ['device-stats'] ) stat = sub.wait_for_event() if stat is not None: reply = json.loads(stat['content']) reply_msg = MQMessage() reply_msg.set_action('cmd.send.result') reply_msg.add_data('stat', reply) reply_msg.add_data('status', True) reply_msg.add_data('reason', None) self.log.debug(u"mq reply".format(reply_msg.get())) self.reply(reply_msg.get()) if failed: self.log.error(failed) reply_msg = MQMessage() reply_msg.set_action('cmd.send.result') reply_msg.add_data('status', False) reply_msg.add_data('reason', failed) self.log.debug(u"mq reply".format(reply_msg.get())) self.reply(reply_msg.get())
class XplMessageTest(unittest.TestCase): """ Test XplMessage class. """ def setUp(self): """ Setup context. The context is setup before each call to a test method. """ self.__xpl_message = XplMessage() def tearDown(self): """ clean context. The context is cleaned after each call of a test method. """ del self.__xpl_message def test_set_type(self): """ Test XplMessage.set_type() method. """ self.assertRaises(XplMessageError, self.__xpl_message.set_type, 'dummy') for type_ in ('xpl-cmnd', 'xpl-trig', 'xpl-stat'): self.__xpl_message.set_type(type_) self.assertEqual(self.__xpl_message.type, type_) def test_set_hop_count(self): """ Test XplMessage.set_hop_count() method. """ self.assertRaises(XplMessageError, self.__xpl_message.set_hop_count, 0) for i in xrange(1, 10): self.__xpl_message.set_hop_count(i) self.assertEqual(self.__xpl_message.hop_count, i) self.assertRaises(XplMessageError, self.__xpl_message.set_hop_count, 10) def test_inc_hop_count(self): """ Test XplMessage.inc_hop_count() method. """ for i in xrange(8): self.__xpl_message.inc_hop_count() self.assertRaises(XplMessageError, self.__xpl_message.inc_hop_count) def test_set_source(self): """ Test XplMessage.set_source() method. """ # Check length self.assertRaises(XplMessageError, self.__xpl_message.set_source, "xxxxxxxxx-x.x") self.assertRaises(XplMessageError, self.__xpl_message.set_source, "x-xxxxxxxxx.x") self.assertRaises(XplMessageError, self.__xpl_message.set_source, "x-x.xxxxxxxxxxxxxxxxx") # Check format self.assertRaises(XplMessageError, self.__xpl_message.set_source, "dummy") self.assertRaises(XplMessageError, self.__xpl_message.set_source, "xPL-hal.myhouse") self.__xpl_message.set_source("xpl-xplhal.myhouse") self.assertEqual(self.__xpl_message.source, "xpl-xplhal.myhouse") self.assertEqual(self.__xpl_message.source_vendor_id, "xpl") self.assertEqual(self.__xpl_message.source_device_id, "xplhal") self.assertEqual(self.__xpl_message.source_instance_id, "myhouse") def test_set_target(self): """ Test XplMessage.set_target() method. """ # Check length self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xxxxxxxxx-xxx.xxx") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xxx-xxxxxxxxx.xxx") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xxx-xxx.xxxxxxxxxxxxxxxxx") # Check format self.assertRaises(XplMessageError, self.__xpl_message.set_target, "dummy") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "xPL-hal.myhouse") self.__xpl_message.set_target("acme-cm12.server") self.assertEqual(self.__xpl_message.target, "acme-cm12.server") self.assertEqual(self.__xpl_message.target_vendor_id, "acme") self.assertEqual(self.__xpl_message.target_device_id, "cm12") self.assertEqual(self.__xpl_message.target_instance_id, "server") self.__xpl_message.set_target('*') self.assertEqual(self.__xpl_message.target, '*') self.assertEqual(self.__xpl_message.target_vendor_id, None) self.assertEqual(self.__xpl_message.target_device_id, None) self.assertEqual(self.__xpl_message.target_instance_id, None) def test_set_schema(self): """ Test XplMessage.set_schema() method. """ # Check length self.assertRaises(XplMessageError, self.__xpl_message.set_schema, "xxxxxxxxx.xxx") self.assertRaises(XplMessageError, self.__xpl_message.set_schema, "xxx.xxxxxxxxx") self.assertRaises(XplMessageError, self.__xpl_message.set_target, "x10-basic") # Check format self.assertRaises(XplMessageError, self.__xpl_message.set_schema, "dummy") self.__xpl_message.set_schema("x10.basic") self.assertEqual(self.__xpl_message.schema, "x10.basic") self.assertEqual(self.__xpl_message.schema_class, "x10") self.assertEqual(self.__xpl_message.schema_type, "basic") def test_add_single_data(self): """ Test XplMessage.test_add_single_data() method. """ # check lengths name = 'x' * 17 value = "xxx" self.assertRaises(XplMessageError, self.__xpl_message.add_single_data, name, value) name = "xxx" value = 'x' * 129 #self.assertRaises(XplMessageError, self.__xpl_message.add_single_data, name, value) # def test_set_data(self): """ Test XplMessage.set_data() method. """ self.__xpl_message.set_data({ "command": "dim", "device": "a1", "level": "75" }) self.assertEqual( self.__xpl_message.data, OrderedDict({ "command": "dim", "device": "a1", "level": "75" })) # Check if correctly remove previous data self.__xpl_message.set_data({ "command2": "dim", "device2": "a1", "level2": "75" }) self.assertEqual( self.__xpl_message.data, OrderedDict({ "command2": "dim", "device2": "a1", "level2": "75" })) def test_from_packet(self): """ Test the XplMessage.from_packet() method. """ wrong_packet = \ """xpl-cmnd { target=acme-cm12.server } { command=dim device=a1 level=75 } """ self.assertRaises(XplMessageError, self.__xpl_message.from_packet, wrong_packet) packet = \ """xpl-cmnd { hop=1 source=xpl-xplhal.myhouse target=acme-cm12.server } x10.basic { command=dim device=a1 level=75 } """ self.__xpl_message.from_packet(packet) self.assertEqual(self.__xpl_message.type, 'xpl-cmnd') self.assertEqual(self.__xpl_message.hop_count, 1) self.assertEqual(self.__xpl_message.source, "xpl-xplhal.myhouse") self.assertEqual(self.__xpl_message.source_vendor_id, "xpl") self.assertEqual(self.__xpl_message.source_device_id, "xplhal") self.assertEqual(self.__xpl_message.source_instance_id, "myhouse") self.assertEqual(self.__xpl_message.target, "acme-cm12.server") self.assertEqual(self.__xpl_message.target_vendor_id, "acme") self.assertEqual(self.__xpl_message.target_device_id, "cm12") self.assertEqual(self.__xpl_message.target_instance_id, "server") self.assertEqual(self.__xpl_message.schema, "x10.basic") self.assertEqual(self.__xpl_message.schema_class, "x10") self.assertEqual(self.__xpl_message.schema_type, "basic") self.assertEqual( self.__xpl_message.data, OrderedDict({ "command": "dim", "device": "a1", "level": "75" })) def testto_packet(self): """ Test XplMessage.to_packet() method. """ packet = \ """xpl-cmnd { hop=1 source=xpl-xplhal.myhouse target=acme-cm12.server } x10.basic { command=dim device=a1 level=75 } """ self.__xpl_message.from_packet(packet) self.assertEquals(self.__xpl_message.to_packet(), packet) def test_is_valid(self): """ Test XplMessage.is_valid() method. """ packet = \ """xpl-cmnd { hop=1 source=xpl-xplhal.myhouse target=acme-cm12.server } x10.basic { command=dim device=a1 level=75 } """ self.assertEquals(self.__xpl_message.is_valid(), False) self.__xpl_message.from_packet(packet) self.assertEquals(self.__xpl_message.is_valid(), True)