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 ping(self): """ Ping computers """ self._ping_thr = XplTimer(self._interval, \ self.ping_list, self.myxpl) self._ping_thr.start()
def start(self): """ Get values each <interval> seconds while process is up """ if self.pid == None: return stop = threading.Event() timer = XplTimer(self._interval, self._get_values, stop, self.myxpl) timer.start()
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()
class Ping: """ This class allow to ping a computer """ def __init__(self, myxpl, log, cb, interval, computers): """ Init object @param log : logger instance """ self.myxpl = myxpl self._log = log self._cb = cb self._interval = interval self._computers = computers def ping(self): """ Ping computers """ self._ping_thr = XplTimer(self._interval, \ self.ping_list, self.myxpl) self._ping_thr.start() def ping_list(self): """ Ping list of computers """ for computer in self._computers: try: old_status = self._computers[computer]["old_status"] except KeyError: # First ping, no old status for ping old_status = None self._log.debug("Pinging %s (%s)" % (computer, self._computers[computer]["ip"])) print("Pinging %s (%s)" % (computer, self._computers[computer]["ip"])) ret = subprocess.call("ping -c 1 %s" % self._computers[computer]["ip"], shell=True, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT) if ret == 0: self._log.debug("%s: is alive" % computer) print("%s: is alive" % computer) status = "high" else: self._log.debug("%s: did not respond" % computer) print("%s: did not respond" % computer) status = "low" if status != old_status: type = "xpl-trig" else: type = "xpl-stat" self._computers[computer]["old_status"] = status self._cb(type, computer, status)
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 :)")
class Ping: """ This class allow to ping a computer """ def __init__(self, myxpl, log, cb, interval, computers): """ Init object @param log : logger instance """ self.myxpl = myxpl self._log = log self._cb = cb self._interval = interval self._computers = computers def ping(self): """ Ping computers """ self._ping_thr = XplTimer(self._interval, self.ping_list, self.myxpl) self._ping_thr.start() def ping_list(self): """ Ping list of computers """ for computer in self._computers: try: old_status = self._computers[computer]["old_status"] except KeyError: # First ping, no old status for ping old_status = None self._log.debug("Pinging %s (%s)" % (computer, self._computers[computer]["ip"])) print("Pinging %s (%s)" % (computer, self._computers[computer]["ip"])) ret = subprocess.call( "ping -c 1 %s" % self._computers[computer]["ip"], shell=True, stdout=open("/dev/null", "w"), stderr=subprocess.STDOUT, ) if ret == 0: self._log.debug("%s: is alive" % computer) print("%s: is alive" % computer) status = "high" else: self._log.debug("%s: did not respond" % computer) print("%s: did not respond" % computer) status = "low" if status != old_status: type = "xpl-trig" else: type = "xpl-stat" self._computers[computer]["old_status"] = status self._cb(type, computer, status)
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 __init__(self): XplPlugin.__init__(self, name = 'xpl_time') self._listen_thr = XplTimer(TIME_BETWEEN_EACH_MESSAGE, \ self._send_datetime, self.myxpl) self._listen_thr.start() self.enable_hbeat()
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()
class XPLDateTime(XplPlugin): ''' Send date and time on the xPL network every minute ''' def __init__(self): XplPlugin.__init__(self, name = 'xpl_time') self._listen_thr = XplTimer(TIME_BETWEEN_EACH_MESSAGE, \ self._send_datetime, self.myxpl) self._listen_thr.start() self.enable_hbeat() def _format(self, number): ''' Format the number ''' if int(number) < 10: return "0%s" % number else: return number def _send_datetime(self): ''' Send date and time on xPL network ''' ldt = localtime() date = "%s%s%s" % (ldt[0], self._format(ldt[1]), self._format(ldt[2])) time = "%s%s%s" % (self._format(ldt[3]), self._format(ldt[4]), self._format(ldt[5])) datetime = "%s%s" % (date, time) mess = XplMessage() mess.set_type("xpl-trig") mess.set_schema("datetime.basic") mess.add_data({"datetime" : datetime}) mess.add_data({"date" : date}) mess.add_data({"time" : time}) # datetime + weekday mess.add_data({"format1" : "%s%s" % (datetime, ldt[6])}) print(mess) self.myxpl.send(mess)
def __init__(self): ''' Manages the plcbus domogik plugin ''' # Load config XplPlugin.__init__(self, name='plcbus') ### get the devices list # for this plugin, if no devices are created we won't be able to use devices. # but.... if we stop the plugin right now, we won't be able to detect existing device and send events about them # so we don't stop the plugin if no devices are created self.devices = self.get_device_list(quit_if_no_device=False) # register helpers self.register_helper('scan', 'test help', 'scan') # check if the plugin is configured. If not, this will stop the plugin and log an error if not self.check_configured(): return ### get all config keys plcbus_device = str(self.get_config('device')) self._usercode = self.get_config('usercode') self._probe_inter = int(self.get_config('probe-interval')) self._probe_list = self.get_config('probe-list') # Init Plcbus self.manager = PLCBUSAPI(self.log, plcbus_device, self._command_cb, self._message_cb) self.add_stop_cb(self.manager.stop) # Create the xpl listeners Listener(self._plcbus_cmnd_cb, self.myxpl, {'xpltype': 'xpl-cmnd', 'schema': 'plcbus.basic'}) 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.ready()
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 __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())
class PlcBusManager(XplPlugin): ''' Manage PLCBus technology, send and receive order/state ''' def __init__(self): ''' Manages the plcbus domogik plugin ''' # Load config XplPlugin.__init__(self, name='plcbus') ### get the devices list # for this plugin, if no devices are created we won't be able to use devices. # but.... if we stop the plugin right now, we won't be able to detect existing device and send events about them # so we don't stop the plugin if no devices are created self.devices = self.get_device_list(quit_if_no_device=False) # register helpers self.register_helper('scan', 'test help', 'scan') # check if the plugin is configured. If not, this will stop the plugin and log an error if not self.check_configured(): return ### get all config keys plcbus_device = str(self.get_config('device')) self._usercode = self.get_config('usercode') self._probe_inter = int(self.get_config('probe-interval')) self._probe_list = self.get_config('probe-list') # Init Plcbus self.manager = PLCBUSAPI(self.log, plcbus_device, self._command_cb, self._message_cb) self.add_stop_cb(self.manager.stop) # Create the xpl listeners Listener(self._plcbus_cmnd_cb, self.myxpl, {'xpltype': 'xpl-cmnd', 'schema': 'plcbus.basic'}) 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.ready() def _send_probe(self): print("send_probe(self)") """ Send probe message """ for h in self._probe_list: print("send get_all_id") self.manager.send("GET_ALL_ID_PULSE", h, self._usercode, 0, 0) time.sleep(1) print("send get_all_on_id") self.manager.send("GET_ALL_ON_ID_PULSE", h, self._usercode, 0, 0) time.sleep(1) def _plcbus_cmnd_cb(self, message): print("plcbus_cmnd_cb(self, message):") ''' General callback for all command messages ''' cmd = None dev = None user = '******' level = 0 rate = 0 print("xpl message receive %s" % message) if 'command' in message.data: cmd = message.data['command'] if 'device' in message.data: dev = message.data['device'].upper() if 'address' in message.data: dev = message.data['address'].upper() if 'usercode' in message.data: user = message.data['usercode'] else: user = self._usercode if 'level' in message.data: level = message.data['level'] if level == "1": cmd = "ON" else: cmd = "OFF" 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)) self.log.debug("%s received : device = %s, user code = %s, level = " \ "%s, rate = %s" % (cmd, dev, user, level, rate)) if cmd == 'GET_ALL_ON_ID_PULSE': self.manager.get_all_on_id(user, dev) else: # self.manager.send(cmd.upper(), dev, user, level, rate) self.manager.send(cmd, dev, user, level, rate) if cmd == 'PRESET_DIM' and level == 0: print("cmd : %s " % cmd) print("level : %s " % level) self.manager.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.manager.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": print("elif fd_command =GET ALL PULSE ") # data = int("%s%s" % (f["d_data1"], f["d_data2"])) # Workaround with autodetection problem force data to 511 # to consider discover of device with value from 0 to 9 # Could also be set to 4095 to force from 0 to F data = 511 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": print("elif fd_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 = 1 else: command = 0 self.log.info("New status for device : %s is now %s " % (code, command)) mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('plcbus.basic') mess.add_data({"address": code, "level": command}) self.myxpl.send(mess) print("message XPL : %s" % mess) item = item - 1 else: print("else") if f["d_command"] == "ON": command = 1 else: command = 0 mess = XplMessage() mess.set_type('xpl-trig') mess.set_schema('plcbus.basic') mess.add_data({"usercode": f["d_user_code"], "address": f["d_home_unit"], "level": command, "data1": f["d_data1"], "data2": f["d_data2"]}) self.myxpl.send(mess) print("message XPL : %s" % mess) def _message_cb(self, message): print("Message : %s " % message)
def __init__(self): """ Create lister and launch bg listening """ XplPlugin.__init__(self, name='zibase') # check if the plugin is configured. If not, this will stop the plugin and log an error if not self.check_configured(): return # check if the plugin is configured. If not, this will stop the plugin and log an error if not self.check_configured(): return self.address = self.get_config('ip') self.inter = self.get_config('interface') self.port = int(self.get_config('port')) self.valvar = self.get_config('envar') self.interv = int(self.get_config('interv')) # get the devices list # for this plugin, if no devices are created we won't be able to use devices. # but.... if we stop the plugin right now, we won't be able to detect existing device and send events about them # so we don't stop the plugin if no devices are created self.devices = self.get_device_list(quit_if_no_device=False) #self._config = Query(self.myxpl, self.log) 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(str(self.inter)) self.log.debug("Adress IP Host=%s" % (self.ip_host)) except: self.log.error("IP Host not found=%s" % (traceback.format_exc())) self.force_leave() return try: self.api = APIZiBase(self.log, self.address) except: self.log.error("API ZiBase error=%s" % (traceback.format_exc())) self.force_leave() 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.force_leave() try: self.api.Connect(self.ip_host, self.port) except: self.log.error("Connection ZiBase error=%s" % (traceback.format_exc())) self.force_leave() if self.valvar: 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") self.force_leave() return #self.add_stop_cb(self.stop) #self.enable_hbeat() self.ready() self.log.info("Plugin ready :)")
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)
def ping(self): """ Ping computers """ self._ping_thr = XplTimer(self._interval, self.ping_list, self.myxpl) self._ping_thr.start()
class HvacMvhr(): """ HVACMvhr """ def __init__(self, plugin): """ Init the library """ self.config = plugin.config self.log = plugin.log self.myxpl = plugin.myxpl self._init_lib() def __init__(self, config, log, myxpl): """ Init the library """ self.config = config self.log = log self.myxpl = myxpl self._init_lib() def _init_lib(self): self.log.debug("hvacMvhr.__init__ : Start") self.sensors = dict() self.mvhr_name = "mvhr1" self.sensors_timeout = 10 self.delay = 5 self.mvhr_indoor = "S1" self.mvhr_outdoor = "S2" self.mvhr_insufflation = "S3" self.mvhr_reject = "" self.mvhr_power = "" self.ect = False self.ect_tube = "" self.ect_outdoor = "" self.timer = None #self._cronquery = CronQuery(self.myxpl, self.log) def reload_config(self): """ Reload the plugin config. """ self.log.debug("reload_config : Try to get configuration from XPL") try: del(self.sensors) self.sensors = dict() self.mvhr_name = self.config.query('mvhr', 'name') boo = self.config.query('mvhr', 'timeout') if boo == None: boo = "0" self.sensors_timeout = int(boo) boo = self.config.query('mvhr', 'delay') if boo == None: boo = "0" self.delay = int(boo) self.mvhr_indoor = self.config.query('mvhr', 'mvhr-indoor') if (self.mvhr_indoor != None and len(self.mvhr_indoor) != 0): self.sensors[self.mvhr_indoor] = {} self.mvhr_outdoor = self.config.query('mvhr', 'mvhr-outdoor') if (self.mvhr_outdoor != None and len(self.mvhr_outdoor) != 0): self.sensors[self.mvhr_outdoor] = {} self.mvhr_insufflation = \ self.config.query('mvhr', 'mvhr-insuffl') if (self.mvhr_insufflation != None \ and len(self.mvhr_insufflation) != 0): self.sensors[self.mvhr_insufflation] = {} self.mvhr_reject = self.config.query('mvhr', 'mvhr-reject') if (self.mvhr_reject != None and len(self.mvhr_reject) != 0): self.sensors[self.mvhr_reject] = {} self.mvhr_power = self.config.query('mvhr', 'mvhr-power') if (self.mvhr_power != None and len(self.mvhr_power) !=0 ): self.sensors[self.mvhr_power] = {} boo = self.config.query('mvhr', 'ect') if boo == None: boo = "False" self.ect = eval(boo) if (self.ect == True): self.ect_tube = self.config.query('mvhr', 'ect-tube') if (self.ect_tube != None and len(self.ect_tube) != 0): self.sensors[self.ect_tube] = {} self.ect_outdoor = self.config.query('mvhr', 'ect-outdoor') if (self.ect_outdoor != None and len(self.ect_outdoor) != 0): self.sensors[self.ect_outdoor] = {} if self.timer != None: self.timer.stop() self.timer = XplTimer(self.delay * 60, self.mvhr_xpl_cb, self.myxpl) self.timer.start() #if self._cronquery.status_job(self.mvhr_name, extkey = "current") \ # != "halted": # self._cronquery.halt_job(self.mvhr_name) # self.log.debug("Halt old cron device %s" % self.mvhr_name) #nstmess = XplMessage() #nstmess.set_type("xpl-trig") #nstmess.set_schema("mvhr.basic") #nstmess.add_data({"mvhr" : self.mvhr_name}) #nstmess.add_data({"type" : "cron"}) #if self._cronquery.start_timer_job(self.mvhr_name, nstmess, \ # self.delay * 60): # self.log.debug("Cron device %s activated" % self.mvhr_name) #else: # self.log.error("Can't activate cron device %s" % \ # self.mvhr_name) self.log.debug("hvacMvhr.__init__ : sensors : %s " % self.sensors) except: error = "Can't get configuration from XPL : %s" % \ (traceback.format_exc()) self.log.exception("mvhr.reload_config : " + error) return False self.log.debug("hvacMvhr.reloadconfig : Done") return True # def leave(self): # """ # Stop the library # """ # self._cronquery.halt_job(self.mvhr_name) def sensor_current(self, sensor): """ Return the current value of a sensor """ if (sensor in self.sensors and "current" in self.sensors[sensor]): return self.sensors[sensor]["current"] else: return "not-found" def exchanger_efficiency(self): """ Return efficiency of the mvhr """ if (self.mvhr_outdoor in self.sensors and self.mvhr_indoor in self.sensors and self.mvhr_insufflation in self.sensors and "current" in self.sensors[self.mvhr_indoor] and "current" in self.sensors[self.mvhr_outdoor] and "current" in self.sensors[self.mvhr_insufflation]): res = ((self.sensors[self.mvhr_insufflation]["current"] - \ self.sensors[self.mvhr_outdoor]["current"]) / \ (self.sensors[self.mvhr_indoor]["current"] - \ self.sensors[self.mvhr_outdoor]["current"])) * 100 return "%.2f" % res else: return "not-found" def helper_status(self, params={}): """ Return status of a device """ self.log.debug("helper_status : Start ...") data = [] data.append("Exchanger efficiency : %s" % \ self.exchanger_efficiency()) data.append("Outdoor temperature : %s" % \ self.sensor_current(self.mvhr_outdoor)) data.append("Indoor temperature : %s" % \ self.sensor_current(self.mvhr_indoor)) data.append("Insufflation temperature : %s" % \ self.sensor_current(self.mvhr_insufflation)) self.log.debug("helper_status : Done") return data def helper_reload_config(self, params={}): """ Reload config of the plugin """ self.log.debug("helper_reload_config : Start ...") data = [] res = self.reload_config() data.append("Reload config of the plugin : %s" % res) return data def req_gate_info(self, myxpl, message): """ Requests the sending of an mvhr.gateinfo message containing details of the xPL connector software. @param myxpl : The XPL sender @param message : The XPL message mvhr.request { request=gateinfo } mvhr.gateinfo { protocol=[X10|UPB|CBUS|ZWAVE|INSTEON] description= version= author= info-url= zone-count=# } """ mess = XplMessage() mess.set_type("xpl-stat") mess.set_schema("mvhr.gateinfo") mess.add_data({"protocol" : "MVHR"}) mess.add_data({"description" : "Manage an mvhr with xpl"}) mess.add_data({"version" : "0.1"}) mess.add_data({"author" : "Domogik Team"}) mess.add_data({"info-url" : "http://wiki.domogik.org/plugin_hvac_mvhr"}) mess.add_data({"request-list" : "mvhrinfo,mvhr"}) mess.add_data({"command-list" : "none"}) mess.add_data({"device-list" : self.mvhr_name}) myxpl.send(mess) def req_mvhr_info(self, myxpl, message): """ This schema reports the configuration of a mvhr, the modes that can be set and the states that it can report. It is sent as an xPL status message in response to an mvhr.request with request=mvhrinfo. @param myxpl : The XPL sender @param message : The XPL message mvhr.request { request=mvhrinfo mvhr=id } mvhr.mvhrinfo { mvhr=id mvhr-mode-list= ect-mode-list= fan-mode-list= mvhr-state-list= ect-state-list= fan-state-list= } """ mvhr = None if 'mvhr' in message.data: mvhr = message.data['mvhr'] mess = XplMessage() mess.set_type("xpl-stat") mess.set_schema("mvhr.mvhrinfo") if mvhr == None: mess.add_data({"error" : "Missing parameter : mvhr"}) self.log.error("request = %s : Missing parameter _ mvhr _." \ % ("mvhrinfo")) elif mvhr != self.mvhr_name: mess.add_data({"error" : "mvhr not found : %s" % mvhr}) self.log.error("request = %s : MVHR _ %s _ not found." % \ ("mvhrinfo", mvhr)) else: mess.add_data({"mvhr" : mvhr}) mess.add_data({"ect-mode-list" : "on,off"}) mess.add_data({"mvhr-mode-list" : "heat,bypass,cool"}) mess.add_data({"fan-mode-list" : "on,off,auto"}) mess.add_data({"ect-state-list" : "on,off"}) mess.add_data({"mvhr-state-list" : "heat,bypass,cool"}) mess.add_data({"fan-state-list" : "on,off"}) myxpl.send(mess) def req_mvhr(self, myxpl, message): """ Requests the sending of an mvhr.mvhr message describing the current state of the specified mvhr. @param myxpl : The XPL sender @param message : The XPL message mvhr.request { request=mvhr mvhr=id } mvhr.mvhr { mvhr=id } """ mvhr = None if 'mvhr' in message.data: mvhr = message.data['mvhr'] mess = XplMessage() mess.set_type("xpl-stat") mess.set_schema("mvhr.mvhr") if mvhr == None: self.log.error("Request = %s : Missing parameter _ mvhr _." % \ ("mvhr")) mess.add_data({"error" : "Missing parameter : mvhr"}) elif mvhr != self.mvhr_name: mess.add_data({"error" : "Mvhr not found : %s" % mvhr}) self.log.error("Request = %s : Mvhr _ %s _ not found." % \ ("mvhr", mvhr)) else: mess.add_data({"mvhr" : mvhr}) self.mvhr_message(mess) if self.ect : self.ect_message(mess) myxpl.send(mess) def mvhr_message(self, mess): """ Add the mvhr part to the message """ mess.add_data({"mvhr-mode" : "bypass"}) mess.add_data({"fan-mode" : "auto"}) mess.add_data({"mvhr-eff" : 0}) mess.add_data({"exchng-eff" : self.exchanger_efficiency()}) mess.add_data({"mvhr-outdoor" : \ self.sensor_current(self.mvhr_outdoor)}) mess.add_data({"mvhr-indoor" : \ self.sensor_current(self.mvhr_indoor)}) mess.add_data({"mvhr-insuffl" : \ self.sensor_current(self.mvhr_insufflation)}) def ect_message(self, mess): """ Add the ect part to the message """ res = 0 mess.add_data({"ect-mode" : "off"}) mess.add_data({"ect-eff" : 0}) if (self.ect_outdoor in self.sensors and self.ect_tube in self.sensors and "current" in self.sensors[self.ect_tube] and "current" in self.sensors[self.ect_outdoor]): res = self.sensors[self.ect_tube]["current"] - \ self.sensors[self.ect_outdoor]["current"] mess.add_data({"ect-delta" : res}) if (self.ect_outdoor in self.sensors and "current" in self.sensors[self.ect_outdoor]): mess.add_data({"ect-outdoor" : \ self.sensors[self.ect_outdoor]["current"]}) if (self.ect_tube in self.sensors and "current" in self.sensors[self.ect_tube]): mess.add_data({"ect-tube" : \ self.sensors[self.ect_tube]["current"]}) def sensor_trig_listener(self, myxpl, message): """ Listen to the trig messages of the sensors """ device = None if 'device' in message.data: device = message.data['device'] self.log.debug("hvacMvhr.sensor_trig_listener : value from \ device %s received" % (device)) if (device in self.sensors): current = 0 if 'current' in message.data: current = message.data['current'] self.log.debug("hvacMvhr.sensor_trig_listener : add \ value %s to sensors" % (current)) self.sensors[device]["current"] = float(current) self.sensors[device]["last"] = datetime.datetime.today() # def mvhr_trig_listener(self, myxpl, message): # """ # List to the mvhr messages # """ # mvhr = None # if 'mvhr' in message.data: # mvhr = message.data['mvhr'] # mtype = None # if 'type' in message.data: # mtype = message.data['type'] # self.log.debug("hvacMvhr.mvhr_trig_listener : message for \ #mvhr %s (%s) received" % (mvhr, mtype)) # if (mvhr == self.mvhr_name and mtype == "cron"): # mess = XplMessage() # mess.set_type("xpl-trig") # mess.set_schema("mvhr.basic") # mess.add_data({"mvhr" : mvhr}) # self.mvhr_message(mess) # if self.ect : # self.ect_message(mess) # myxpl.send(mess) def mvhr_xpl_cb(self): """ Callback function of the xpltimer """ mess = XplMessage() mess.set_type("xpl-trig") mess.set_schema("mvhr.basic") mess.add_data({"mvhr" : self.mvhr_name}) self.mvhr_message(mess) if self.ect : self.ect_message(mess) self.myxpl.send(mess) def request_listener(self, myxpl, message): """ Listen to mvhr.request messages @param message : The XPL message @param myxpl : The XPL sender mvhr.request { request=gateinfo|zonelist|zoneinfo|zone|setpoint|timer|runtime|fantime zone=id [setpoint=] [state=] } """ self.log.debug("hvacMvhr.request_listener : Start ...") requests = { 'gateinfo': lambda x,m: self.req_gate_info(x,m), 'mvhrinfo': lambda x,m: self.req_mvhr_info(x,m), 'mvhr': lambda x,m: self.req_mvhr(x,m), } request = None if 'request' in message.data: request = message.data['request'] self.log.debug("hvacMvhr.request_listener : request %s \ received" % (request)) try: requests[request](myxpl, message) except: self.log.error("Request _ %s _ unknown." % (request)) error = "Exception : %s" % (traceback.format_exc()) self.log.debug("hvacMvhr.request_listener : " + error)
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)
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())
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)
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)
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 reload_config(self): """ Reload the plugin config. """ self.log.debug("reload_config : Try to get configuration from XPL") try: del(self.sensors) self.sensors = dict() self.mvhr_name = self.config.query('mvhr', 'name') boo = self.config.query('mvhr', 'timeout') if boo == None: boo = "0" self.sensors_timeout = int(boo) boo = self.config.query('mvhr', 'delay') if boo == None: boo = "0" self.delay = int(boo) self.mvhr_indoor = self.config.query('mvhr', 'mvhr-indoor') if (self.mvhr_indoor != None and len(self.mvhr_indoor) != 0): self.sensors[self.mvhr_indoor] = {} self.mvhr_outdoor = self.config.query('mvhr', 'mvhr-outdoor') if (self.mvhr_outdoor != None and len(self.mvhr_outdoor) != 0): self.sensors[self.mvhr_outdoor] = {} self.mvhr_insufflation = \ self.config.query('mvhr', 'mvhr-insuffl') if (self.mvhr_insufflation != None \ and len(self.mvhr_insufflation) != 0): self.sensors[self.mvhr_insufflation] = {} self.mvhr_reject = self.config.query('mvhr', 'mvhr-reject') if (self.mvhr_reject != None and len(self.mvhr_reject) != 0): self.sensors[self.mvhr_reject] = {} self.mvhr_power = self.config.query('mvhr', 'mvhr-power') if (self.mvhr_power != None and len(self.mvhr_power) !=0 ): self.sensors[self.mvhr_power] = {} boo = self.config.query('mvhr', 'ect') if boo == None: boo = "False" self.ect = eval(boo) if (self.ect == True): self.ect_tube = self.config.query('mvhr', 'ect-tube') if (self.ect_tube != None and len(self.ect_tube) != 0): self.sensors[self.ect_tube] = {} self.ect_outdoor = self.config.query('mvhr', 'ect-outdoor') if (self.ect_outdoor != None and len(self.ect_outdoor) != 0): self.sensors[self.ect_outdoor] = {} if self.timer != None: self.timer.stop() self.timer = XplTimer(self.delay * 60, self.mvhr_xpl_cb, self.myxpl) self.timer.start() #if self._cronquery.status_job(self.mvhr_name, extkey = "current") \ # != "halted": # self._cronquery.halt_job(self.mvhr_name) # self.log.debug("Halt old cron device %s" % self.mvhr_name) #nstmess = XplMessage() #nstmess.set_type("xpl-trig") #nstmess.set_schema("mvhr.basic") #nstmess.add_data({"mvhr" : self.mvhr_name}) #nstmess.add_data({"type" : "cron"}) #if self._cronquery.start_timer_job(self.mvhr_name, nstmess, \ # self.delay * 60): # self.log.debug("Cron device %s activated" % self.mvhr_name) #else: # self.log.error("Can't activate cron device %s" % \ # self.mvhr_name) self.log.debug("hvacMvhr.__init__ : sensors : %s " % self.sensors) except: error = "Can't get configuration from XPL : %s" % \ (traceback.format_exc()) self.log.exception("mvhr.reload_config : " + error) return False self.log.debug("hvacMvhr.reloadconfig : Done") return True
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)