Esempio n. 1
0
    def __init__(self, configDir, osnInstance):
        AbstractAgent.__init__(self, configDir, osnInstance)

        log="Info" # should be read from config later

        configChanged = False
        if "zwave_device" not in self.configData:
            self.configData["zwave_device"] = "/dev/ttyACM0"
            configChanged = True
        if configChanged:
            self.serializeConfig()

        # handle zwave default device configurations
        self.zwaveDefaultConfigs = {}
        self.zwaveDefaultConfigFile = os.path.join(self.configDir, "zwavedefaultconfigs.config.json")
        self.readZwaveDefaultConfigs()

        self.device = self.configData["zwave_device"]
        self.logger.debug("Initiating ZWaveAgent with device %s." % self.device)
        self.zwaveOptions = ""
        try:
            self.zwaveOptions = ZWaveOption(self.device.encode('ascii'), \
            config_path=expanduser("~")+"/ozw-install/python-open-zwave/openzwave/config", \
            user_path=self.configDir, cmd_line="")
            self.zwaveOptions.set_log_file("../log/openzwave.log") # Todo: don't hardcode openzwave-path
            self.zwaveOptions.set_append_log_file(False)
            self.zwaveOptions.set_console_output(False)
            self.zwaveOptions.set_save_log_level(log)
            self.zwaveOptions.set_logging(False)
            self.zwaveOptions.lock()
        except BaseException as e:
            self.logger.info("Error setting up ZWave network. Correct device? Device properly connected? Device is: %s Exception message: %s" % (self.device, e))
        self.inDiscoveryMode = False #scanning for available devices and sensors is slightly more complicated here...
Esempio n. 2
0
 def test_000_network_start_stop(self):
     self.driver_ready = False
     self.driver_removed = False
     self.options = ZWaveOption(device=self.device, user_path=self.userpath)
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(False)
     self.options.set_save_log_level("Debug")
     self.options.set_logging(True)
     self.options.lock()
     dispatcher.connect(self.driver_ready_message, ZWaveNetwork.SIGNAL_DRIVER_READY)
     dispatcher.connect(self.driver_removed_message, ZWaveNetwork.SIGNAL_DRIVER_REMOVED)
     self.network = ZWaveNetwork(self.options)
     for i in range(0, SLEEP):
         if self.network.state>=self.network.STATE_AWAKED:
             break
         else:
             time.sleep(1.0)
     self.assertTrue(self.driver_ready)
     self.network.stop()
     for i in range(0, SLEEP):
         if self.network.state==self.network.STATE_STOPPED:
             break
         else:
             time.sleep(1.0)
     self.assertEqual(self.network.state, self.network.STATE_STOPPED)
     #self.assertTrue(self.driver_removed)
     self.network = None
Esempio n. 3
0
    def start(self,
              controllerDevice,
              config_path="./config",
              user_path=".",
              cmd_line=""):
        self.options = ZWaveOption(controllerDevice, config_path, user_path,
                                   cmd_line)
        self.options.set_log_file("OZW_Log.log")
        self.options.set_append_log_file(False)
        self.options.set_console_output(False)
        self.options.set_save_log_level("None")
        self.options.set_logging(True)
        self.options.lock()

        dispatcher.connect(self.zwave_network_ready,
                           ZWaveNetwork.SIGNAL_NETWORK_READY)
        dispatcher.connect(self.zwave_network_started,
                           ZWaveNetwork.SIGNAL_NETWORK_STARTED)
        dispatcher.connect(self.zwave_network_failed,
                           ZWaveNetwork.SIGNAL_NETWORK_FAILED)
        dispatcher.connect(self.zwave_node_update, ZWaveNetwork.SIGNAL_NODE)
        dispatcher.connect(self.zwave_value_update, ZWaveNetwork.SIGNAL_VALUE)

        self.network = ZWaveNetwork(self.options, autostart=False)
        self.network.start()
Esempio n. 4
0
 def set_options(self):
     opts = self.raw_opts
     self.opts = ZWaveOption(device=opts.get("device"),
                             config_path=opts.get("config_path"),
                             user_path=opts.get("user_path"),
                             cmd_line=opts.get("cmd_line"))
     for key, val in opts.items():
         if key not in ["device", "config_path", "user_path", "cmd_line"]:
             getattr(self.opts, "set_" + key)(val)
     self.opts.lock()
     self.opts_locked = True
Esempio n. 5
0
 def __init__(self,
              device="/dev/ttyAMA0",
              config_path="/usr/local/etc/openzwave"):
     threading.Thread.__init__(self)
     self.__device = device
     self.__config_path = config_path
     self.__options = ZWaveOption(device, config_path=self.__config_path)
     self.__options.set_console_output(False)
     self.__options.lock()
     self.__network = None
     self.__network_ready = False
     self.__event_listen = None
Esempio n. 6
0
 def _start_network(self):
     #Define some manager options
     self.options = ZWaveOption(self.device, \
       config_path="openzwave/config", \
       user_path=".", cmd_line="")
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(False)
     self.options.set_save_log_level("Internal")
     self.options.set_logging(True)
     self.options.lock()
     self.network = ZWaveNetwork(self.options, self.log)
     self.status_bar.update(status='Start Network')
Esempio n. 7
0
 def _start_network(self):
     #Define some manager options
     self.options = ZWaveOption(self.device, \
       config_path=self.config_path, \
       user_path=self.user_path, cmd_line="")
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(False)
     self.options.set_save_log_level(self.loglevel_ow)
     self.options.set_logging(True)
     self.options.lock()
     self.network = ZWaveNetwork(self.options, self.log, kvals=False)
     self.status_bar.update(status='Start Network')
    def __init__(self, stdscr):
        self._curAlert = False
        self._alertStack = list()
        self._driverInitialized = False
        self._options = None
        self._network = None
        self._listMode = True
        self._screen = stdscr
        self._version = '0.1 Beta 1'
        self._listtop = 0
        self._listindex = 0
        self._listcount = 0
        self._selectedNode = None
        self._stop = threading.Event()
        self._keys = {
            'A': 'Add',
            'B': 'About',
            'D': 'Delete',
            'R': 'Refresh',
            'S': 'Setup',
            '+': 'Increase',
            '-': 'Decrease',
            '1': 'On',
            '0': 'Off',
            'Q': 'Quit'
        }

        #self._network = ZWaveWrapper.getInstance(device=self._config['device'], config=self._config['config'], log=None)
        self._options = ZWaveOption( \
            device="/dev/zwave-aeon-s2", \
            config_path="openzwave/config", \
            user_path=".", \
            cmd_line="")
        self._options.set_log_file("OZW_Log.log")
        self._options.set_append_log_file(False)
        self._options.set_save_log_level('Debug')
        self._options.set_console_output(False)
        self._options.set_logging(True)
        self._options.lock()

        # TODO: add log level to config
        # TODO: add log enable/disable to config
        # TODO: logging - can ozw log be redirected to file?  If so, we can add ability to view/tail log
        FORMAT = '%(asctime)s\t%(levelname)s\t%(name)s\t%(message)s'
        logging.basicConfig(filename='zwaveCommander.log',
                            level=logging.DEBUG,
                            format=FORMAT)
        self._log = logging.getLogger('ZWaveCommander')
        self._logbar = '\n%s\n' % ('-' * 60)
Esempio n. 9
0
 def setUpClass(self):
     super(TestApi, self).setUpClass()
     self.options = ZWaveOption(device=self.device, user_path=self.userpath)
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(False)
     self.options.set_save_log_level("Debug")
     self.options.set_logging(True)
     self.options.lock()
     self.network = ZWaveNetwork(self.options)
     self.ctrl_command_result = None
     dispatcher.connect(self.ctrl_message,
                        ZWaveController.SIGNAL_CONTROLLER)
     self.node_result = None
     dispatcher.connect(self.node_update, ZWaveNetwork.SIGNAL_NODE)
Esempio n. 10
0
 def setUpClass(self):
     super(TestApi, self).setUpClass()
     self.options = ZWaveOption(device=self.device, user_path=self.userpath)
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(self.ozwout)
     self.options.set_save_log_level(self.ozwlog)
     self.options.set_logging(True)
     self.options.lock()
     self.network = ZWaveNetwork(self.options)
     self.node_result = None
     self.ctrl_command_result = None
     self.ctrl_command_signal = None
     #dispatcher.connect(self.ctrl_message, ZWaveNetwork.SIGNAL_CONTROLLER_COMMAND)
     time.sleep(1.0)
Esempio n. 11
0
def init_manager():
	globals.options = ZWaveOption(globals.device, config_path=globals.config_folder, user_path=globals.data_folder, cmd_line="")
	globals.options.set_log_file("../../../log/openzwaved")
	globals.options.set_append_log_file(False)
	globals.options.set_console_output(False)
	if globals.log_level == 'notice':
		globals.options.set_save_log_level('Warning')
	else:
		globals.options.set_save_log_level(globals.log_level[0].upper() + globals.log_level[1:])
	globals.options.set_logging(True)
	globals.options.set_associate(True)
	globals.options.set_save_configuration(True)
	globals.options.set_poll_interval(globals.default_poll_interval)
	globals.options.set_interval_between_polls(False)
	globals.options.set_notify_transactions(True)
	globals.options.set_suppress_value_refresh(False)
	globals.options.set_driver_max_attempts(5)
	globals.options.addOptionBool("AssumeAwake", globals.assumeAwake)
	globals.options.addOptionString("NetworkKey", "0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10", True)
	globals.options.set_security_strategy('SUPPORTED')
	globals.options.addOptionBool('EnforceSecureReception', False)
	globals.options.addOptionBool('RefreshAllUserCodes', False)
	globals.options.addOptionInt('ThreadTerminateTimeout', 5000)
	globals.options.addOptionBool('EnableSIS', True)
	globals.options.lock()
	globals.files_manager = FilesManager(globals.data_folder, globals.not_supported_nodes, logging)
	globals.files_manager.check_config_files()
Esempio n. 12
0
    def __init__(self):
        self.sensor_events = []
        self.device = "/dev/ttyACM0"
        config_path = "plugins/python-openzwave/openzwave/config"
        user_path = "plugins/python-openzwave/config"
        # If using older Z-sticks, use the below device:
        # self.device = "/dev/ttyUSB0"
        # Change config paths where appropriate
        self.options = ZWaveOption(self.device, config_path=config_path,
                                   user_path=user_path, cmd_line="")
        # Turn off ozw console output
        self.options.set_console_output(False)
        self.options.set_save_log_level("Info")
        self.options.set_logging(False)
        self.options.lock()

        self.manager = libopenzwave.PyManager()
        self.manager.create()
        self.manager.addWatcher(self.event_callback)
        self.manager.addDriver(self.device)

        print("Starting Z-Wave Network...")
        self.network = ZWaveNetwork(self.options, log=None)
        # Wait for network to start
        while not self.network.state >= self.network.STATE_AWAKED:
            time.sleep(1)
        print("Z-Wave Network Started")
Esempio n. 13
0
 def connect(self) -> None:
     options = ZWaveOption(
         self.__zwave_config.port,
         config_path=self.__zwave_config.openzwave_config_path,
         user_path=".",
         cmd_line="")
     options.set_console_output(False)
     options.set_save_log_level("None")
     options.set_logging(False)
     options.lock()
     self.__network = ZWaveNetwork(options, autostart=False)
     dispatcher.connect(self.__network_failed,
                        ZWaveNetwork.SIGNAL_NETWORK_FAILED)
     dispatcher.connect(self.__network_ready,
                        ZWaveNetwork.SIGNAL_NETWORK_READY)
     dispatcher.connect(self.__value_update, ZWaveNetwork.SIGNAL_VALUE)
     self.__network.start()
Esempio n. 14
0
    def __init__(self, name, location, nodefilename="/opt/seciot/nodenames.json"):
        IOTDeviceController.__init__(self, name)

        # Restore node stuff
        nodefile = open(nodefilename, "r")
        nodejson = nodefile.read()
        self.node_dict = json.loads(nodejson)

        # Init options
        device = "/dev/ttyACM0"
        sniff = 300.0
        options = ZWaveOption(device, config_path="/opt/openzwave/config", user_path=".", cmd_line="")
        options.set_logging(False)
        options.set_console_output(False)
        options.lock()
        # Create a network object
        self.network = ZWaveNetwork(options, autostart=False)
        self.network.set_poll_interval(10, True)
        # We connect to the louie dispatcher
        dispatcher.connect(self.louie_network_started, ZWaveNetwork.SIGNAL_NETWORK_STARTED)
        dispatcher.connect(self.louie_network_failed, ZWaveNetwork.SIGNAL_NETWORK_FAILED)
        self.network.start()
        # We wait for the network.
        print "***** Waiting for network to become ready : "
        for i in range(0, 300):
            if self.network.state >= self.network.STATE_READY:
                print "***** Network is ready"
                break
            else:
                sys.stdout.write(".")
                sys.stdout.flush()
            time.sleep(1.0)
            # We update the name of the controller
        self.network.controller.node.name = name
        self.network.controller.node.location = location
Esempio n. 15
0
    def __init__(self, *args, **kwargs):
        self._serialDevicePath = kwargs.get('serialDevicePath', None)
        self._options = ZWaveOption(self._serialDevicePath, \
          config_path="/usr/local/etc/openzwave/", \
          user_path=".", cmd_line="")
        self._options.set_log_file("OZW_Log.log")
        self._options.set_append_log_file(False)
        self._options.set_console_output(False)
        #self._options.set_save_log_level(log)
        self._options.set_save_log_level('Info')
        self._options.set_logging(True)
	self._options.set_notify_transactions(True)
        self._options.lock()

        self._network = ZWaveNetwork(self._options, log=None,autostart=False)
	dispatcher.connect(self.louie_network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY)
	self._network.start()
        super(Open_zwave, self).__init__(self, *args, **kwargs)
Esempio n. 16
0
 def test_000_api_network(self):
     self.touchFile('ttyUSBO_fake')
     self.options = ZWaveOption(device='ttyUSBO_fake', user_path=self.userpath)
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(False)
     self.options.set_save_log_level("Debug")
     self.options.set_logging(True)
     self.options.lock()
     self.network = ZWaveNetwork(self.options, autostart=False)
     self.rmFile('ttyUSBO_fake')
Esempio n. 17
0
    def initZwave(self):
        self.options = ZWaveOption(self.device, config_path=self.config_path, user_path=".", cmd_line="")
        self.options.set_log_file("MyZWave_log.log")
        self.options.set_append_log_file(False)
        self.options.set_console_output(False)
        #self.options.set_console_output(True)
        self.options.set_save_log_level(self.log)
        self.options.set_logging(False)
        self.options.lock()

        self.network = ZWaveNetwork(self.options, log=None)

        time_started=0
        print("*** Waiting for network to awake: ")
        for i in range(0,300):
            if self.network.state >= self.network.STATE_AWAKED:
                print(" done")
                break
            else:
                sys.stdout.write(".")
                sys.stdout.flush()
                time_started += 1
                time.sleep(1.0)

        if self.network.state < self.network.STATE_AWAKED:
            print(".")
            print("Network is not awaked")
        for i in range(0,300):
            if self.network.state >= self.network.STATE_READY:
                print(" done in{} seconds".format(time_started))
                break
            else:
                sys.stdout.write(".")
                sys.stdout.flush()
                time_started += 1
                time.sleep(1.0)

        if not self.network.is_ready:
            print(".")
            print("Network is not ready")
Esempio n. 18
0
  def startup_zwave(self, args={}):
    ffEvent(self._id,{'zwave':'starting_up'})
    zwaveSetup = ZWaveOption(self._port, self._configFile)
    zwaveSetup.set_console_output(False)
    zwaveSetup.lock()
    network = ZWaveNetwork(zwaveSetup, autostart=False)
    network.start()

    stdout.write("Waking up Zwave (This can take up to 5 minutes)")
    for i in xrange(3):
      if network.state >= network.STATE_AWAKED:
        logging.info('Zwave Network Awake')
        break
      else:
        stdout.write(".")
        stdout.flush()
        sleep(1)

    for x in xrange(3):
      if network.state >= network.STATE_READY:
        ffEvent(self._id,{'zwave':'network_ready'})
      else:
        stdout.write(".")
        stdout.flush()
        sleep(.5)

    return network
Esempio n. 19
0
 def _start_network(self):
     #Define some manager options
     self.options = ZWaveOption(self.device, \
       config_path=self.config_path, \
       user_path=self.user_path, cmd_line="")
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(False)
     self.options.set_save_log_level(self.loglevel_ow)
     self.options.set_logging(True)
     self.options.lock()
     self.network = ZWaveNetwork(self.options, self.log, kvals = False)
     self.status_bar.update(status='Start Network')
Esempio n. 20
0
 def __init__(self, *args, **kwargs):
     self._serialDevicePath = kwargs.get('serialDevicePath', None)
     self._options = ZWaveOption(self._serialDevicePath, \
       config_path="/usr/share/python-openzwave/config", \
       user_path=".", cmd_line="")
     self._options.set_log_file("OZW_Log.log")
     self._options.set_append_log_file(False)
     self._options.set_console_output(True)
     #self._options.set_save_log_level(log)
     self._options.set_save_log_level('Info')
     self._options.set_logging(False)
     self._options.lock()
     self._network = ZWaveNetwork(self._options, log=None)
     super(Open_zwave, self).__init__(self, *args, **kwargs)
Esempio n. 21
0
 def setUpClass(self):
     super(TestApi, self).setUpClass()
     self.options = ZWaveOption(device=self.device, user_path=self.userpath)
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(False)
     self.options.set_save_log_level("Debug")
     self.options.set_logging(True)
     self.options.lock()
     self.network = ZWaveNetwork(self.options)
     self.ctrl_command_result = None
     dispatcher.connect(self.ctrl_message, ZWaveController.SIGNAL_CONTROLLER)
     self.node_result = None
     dispatcher.connect(self.node_update, ZWaveNetwork.SIGNAL_NODE)
Esempio n. 22
0
 def setUpClass(self):
     super(TestApi, self).setUpClass()
     self.options = ZWaveOption(device=self.device, user_path=self.userpath)
     self.options.set_log_file("OZW_Log.log")
     self.options.set_append_log_file(False)
     self.options.set_console_output(self.ozwout)
     self.options.set_save_log_level(self.ozwlog)
     self.options.set_logging(True)
     self.options.lock()
     self.node_result = None
     dispatcher.connect(self.node_update, ZWaveNetwork.SIGNAL_NODE)
     self.network = ZWaveNetwork(self.options)
     self.ctrl_command_result = None
     self.ctrl_command_signal = None
     #dispatcher.connect(self.ctrl_message, ZWaveNetwork.SIGNAL_CONTROLLER_COMMAND)
     time.sleep(1.0)
Esempio n. 23
0
    def __init__(self, stdscr):
        self._curAlert = False
        self._alertStack = list()
        self._driverInitialized = False
        self._options = None
        self._network = None
        self._listMode = True
        self._screen = stdscr
        self._version = '0.1 Beta 1'
        self._listtop = 0
        self._listindex = 0
        self._listcount = 0
        self._selectedNode = None
        self._stop = threading.Event()
        self._keys = {
            'A' : 'Add',
            'B' : 'About',
            'D' : 'Delete',
            'R' : 'Refresh',
            'S' : 'Setup',
            '+' : 'Increase',
            '-' : 'Decrease',
            '1' : 'On',
            '0' : 'Off',
            'Q' : 'Quit'
        }

        #self._network = ZWaveWrapper.getInstance(device=self._config['device'], config=self._config['config'], log=None)
        self._options = ZWaveOption( \
            device="/dev/zwave-aeon-s2", \
            config_path="openzwave/config", \
            user_path=".", \
            cmd_line="")
        self._options.set_log_file("OZW_Log.log")
        self._options.set_append_log_file(False)
        self._options.set_save_log_level('Debug')
        self._options.set_console_output(False)
        self._options.set_logging(True)
        self._options.lock()

        # TODO: add log level to config
        # TODO: add log enable/disable to config
        # TODO: logging - can ozw log be redirected to file?  If so, we can add ability to view/tail log
        FORMAT='%(asctime)s\t%(levelname)s\t%(name)s\t%(message)s'
        logging.basicConfig(filename='zwaveCommander.log', level=logging.DEBUG, format=FORMAT)
        self._log = logging.getLogger('ZWaveCommander')
        self._logbar ='\n%s\n' % ('-'*60)
Esempio n. 24
0
    def __init__(self, device, isac_node):
        self.isac_node = isac_node

        self.signals = {}

        self._ozw_notif_queue = Queue()
        self._running = True
        green.spawn(self._notif_reader)

        self.options = ZWaveOption(
            device,
            config_path='/usr/share/openzwave/config',
            user_path='./user-dir',
            cmd_line=''
        )
        self.options.set_log_file("./user-dir/OZW_Log.log")
        self.options.set_append_log_file(False)
        self.options.set_console_output(False)
        self.options.set_save_log_level('Info')
        self.options.set_logging(False)
        self.options.lock()

        self.network = ZWaveNetwork(self.options, log=None)

        notif_to_func = [
            (ZWaveNetwork.SIGNAL_NETWORK_STARTED,    self.notif_network_started),
            (ZWaveNetwork.SIGNAL_NETWORK_RESETTED,   self.notif_network_resetted),
            (ZWaveNetwork.SIGNAL_NETWORK_READY,      self.notif_network_ready),
            (ZWaveNetwork.SIGNAL_NODE_ADDED,         self.notif_node_added),
            (ZWaveNetwork.SIGNAL_NODE_NAMING,        self.notif_node_named),
            (ZWaveNetwork.SIGNAL_NODE_REMOVED,       self.notif_node_removed),
            (ZWaveNetwork.SIGNAL_VALUE_ADDED,        self.notif_value_added),
            (ZWaveNetwork.SIGNAL_VALUE_CHANGED,      self.notif_value_update),
            (ZWaveNetwork.SIGNAL_VALUE_REMOVED,      self.notif_value_removed),
            (ZWaveNetwork.SIGNAL_CONTROLLER_COMMAND, self.notif_ctrl_message),
            (ZWaveNetwork.SIGNAL_CONTROLLER_WAITING, self.notif_ctrl_message),
        ]
        for notif, func in notif_to_func:
            dispatcher.connect(self._notif_wrapper(func), notif, weak=False)

        # dispatcher.connect(self._notif_wrapper_all, All)

        self.isac_node.add_rpc(self.network_heal)
        self.isac_node.add_rpc(self.controller_add_node, name='add_node')
        self.isac_node.add_rpc(self.controller_remove_node, name='remove_node')
        self.isac_node.add_rpc(self.controller_cancel_command, name='cancel_command')
Esempio n. 25
0
def create_zwave_options(
        device,
        config_path="/usr/local/etc/openzwave",  # TODO: Auto-discover
        user_path=".",
        cmd_line=""):
    try:
        options = ZWaveOption(device,
                              config_path=config_path,
                              user_path=user_path,
                              cmd_line=cmd_line)

        options.set_console_output(False)
        options.set_logging(False)
        options.lock()
        return options
    except ZWaveOption:
        # TODO: Seems device can only be used by one process at the time. If so,
        # try to give a meaningful error message
        raise
Esempio n. 26
0
def create_zwave_options(
    device,
    config_path = "/usr/local/etc/openzwave", # TODO: Auto-discover
    user_path = ".",
    cmd_line = ""):
  try:
    options = ZWaveOption(
        device,
        config_path=config_path,
        user_path=user_path,
        cmd_line=cmd_line)

    options.set_console_output(False)
    options.set_logging(False)
    options.lock()
    return options
  except ZWaveOption:
    # TODO: Seems device can only be used by one process at the time. If so,
    # try to give a meaningful error message
    raise
Esempio n. 27
0
    def start_network(self):
        if self.network and self.network.state >= self.network.STATE_AWAKED:
            self.logger.info('Z-Wave network already started')
            return

        from openzwave.network import ZWaveNetwork, dispatcher
        from openzwave.option import ZWaveOption

        network_ready.clear()
        logging.getLogger('openzwave').addHandler(self.logger)
        opts = ZWaveOption(self.device,
                           config_path=self.config_path,
                           user_path=self.user_path)
        opts.set_console_output(False)
        opts.lock()

        self.network = ZWaveNetwork(opts, log=None)
        dispatcher.connect(_zwcallback)
        ready = network_ready.wait(self.ready_timeout)

        if not ready:
            self.logger.warning(
                'Driver not ready after {} seconds: continuing anyway'.format(
                    self.ready_timeout))
Esempio n. 28
0
class MainWindow(Screen):
    def __init__(self, device=None, footer=False, name=None):
        Screen.__init__(self)
        self.device = device
        self.footer_display = footer
        self._define_log()
        self._define_screen()
        self._connect_louie()
        self._start_network()

    def _define_log(self):
        hdlr = logging.FileHandler('/tmp/urwidcmd.log')
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
        hdlr.setFormatter(formatter)
        self.log = logging.getLogger('openzwave')
        self.log.addHandler(hdlr)
        self.log.setLevel(logging.DEBUG)
        self.log.info("="*15 + " start " + "="*15)

    def _define_screen(self):
        self._palette = [("title", "yellow", "dark cyan"),
        ("keys", "dark blue", "light gray"),
        ("message", "light cyan", "dark green"),
        ("linenr", "light blue", "dark cyan"),
        ("input", "light gray", "black"),
        ("input2", "dark red", "light gray"),
        ("focus", "black", "light gray", "bold"),
        ("dialog", "black", "light gray", "bold"),
        ("file", "light green", "dark blue"),
        ("errortxt", "dark red", "dark blue"),
        ("selectedfile", "yellow", "dark blue"),
        ("selectedfocus", "yellow", "light gray", "bold"),
        ("dir", "light gray", "dark blue"),
        ("fileedit", "light green", "dark red"),
        ('edit', 'yellow', 'dark blue'),
        ('body','default', 'default'),
        ('foot','dark cyan', 'dark blue', 'bold'),
        ('shadow','white','black'),
        ('border','black','dark blue'),
        ('error','black','dark red'),
        ('FxKey','light cyan', 'dark blue', 'underline')]
        self.network = None
        self.controller = None
        self.root_box = RootBox(self, None, "body")
        self.stat_box = StatBox(self, self.root_box, "body")
        self.controller_box = ControllerBox(self, self.root_box, "body")
        self.scenes_box = ScenesBox(self, self.root_box, "body")
        self.scene_box = SceneBox(self, self.scenes_box, "body")
        self.nodes_box = NodesBox(self, self.root_box, "body")
        self.switches_box = SwitchesBox(self, self.nodes_box, "body")
        self.dimmers_box = DimmersBox(self, self.nodes_box, "body")
        self.sensors_box = SensorsBox(self, self.nodes_box, "body")
        self.node_box = NodeBox(self, self.nodes_box, "body")
        self.values_box = ValuesBox(self, self.node_box, "body")
        self.groups_box = GroupsBox(self, self.node_box, "body")

        self.status_bar = StatusBar(self)
        self.header_bar = HeaderBar(self)

        self.framefocus = 'footer'

        self._active_box = self.root_box
        self.frame = urwid.Frame(urwid.AttrWrap(self.active_box, 'body'), \
            header=self.header_bar,\
            footer=self.status_bar, \
            focus_part=self.framefocus)
        self.active_box = self.root_box

        self.loop = urwid.MainLoop(self.frame, \
            self._palette, \
            unhandled_input=self._unhandled_input)

    @property
    def active_box(self):
        """
        Gets the number of association groups reported by this node.

        :rtype: int

        """
        return self._active_box

    @active_box.setter
    def active_box(self,value):
        """
        Gets the number of association groups reported by this node.

        :rtype: int

        """
        self._active_box = value
        self.frame.set_body(self._active_box)
        self.header_bar.update(self._active_box.walker.fullpath())

    def exit(self):
        """
        Quit the programm
        Clean network properly and exit

        """
        self.network.write_config()
        self.network.stop()
        raise urwid.ExitMainLoop()

    def execute(self, command):
        """
        Parse an execute a commande
        """
        command = command.strip()
        if command.startswith('ls') :
            if ' ' in command :
                cmd,options = command.split(' ')
            else:
                options = ""
            options = options.strip()
            self.active_box.walker.ls(options)
            self.status_bar.set_command("")
            return True
        elif command.startswith('exit') :
            self.exit()
        elif command.startswith('cd') :
            if ' ' in command :
                cmd,path = command.split(' ',1)
            else:
                path = "/"
            path = path.strip()
            if self.active_box.walker.exist(path):
                self.active_box = self.active_box.walker.cd(path)
                self.active_box.walker.ls("")
                self.status_bar.set_command("")
                self.log.info(" self.active_box %s" %  self.active_box.walker.path)
                return True
            elif path == "/" :
                self.active_box = self.root_box
                self.active_box.walker.ls("")
                self.status_bar.set_command("")
                self.log.info(" self.active_box %s" %  self.active_box.walker.path)
                return True
            else:
                self.status_bar.update(status='Unknown directory "%s"' % path)
                return False
        elif command.startswith('send') :
            if ' ' in command :
                cmd,value = command.split(' ',1)
            else:
                self.status_bar.update(status='Usage : send <command>')
                return False
            value = value.strip()
            if len(value) == 0 :
                self.status_bar.update(status='Usage : send <command>')
                return False
            if self.active_box.walker.send(value):
                self.active_box.walker.ls("")
                self.status_bar.set_command("")
                return True
            else :
                return False
        elif command.startswith('create') :
            if ' ' in command :
                cmd,value = command.split(' ',1)
            else:
                self.status_bar.update(status='Usage : create <value>')
                return False
            value = value.strip()
            if len(value) == 0 :
                self.status_bar.update(status='Usage : create <value>')
                return False
            if self.active_box.walker.create(value):
                self.active_box.walker.ls("")
                self.status_bar.set_command("")
                return True
            else :
                return False
        elif command.startswith('delete') :
            if ' ' in command :
                cmd,value = command.split(' ',1)
            else:
                self.status_bar.update(status='Usage : delete <value>')
                return False
            value = value.strip()
            if len(value) == 0 :
                self.status_bar.update(status='Usage : delete <value>')
                return False
            if self.active_box.walker.delete(value):
                self.active_box.walker.ls("")
                self.status_bar.set_command("")
                return True
            else :
                return False
        elif command.startswith('activate') :
            if ' ' in command :
                cmd,value = command.split(' ',1)
            else:
                self.status_bar.update(status='Usage : activate <value>')
                return False
            value = value.strip()
            if len(value) == 0 :
                self.status_bar.update(status='Usage : activate <value>')
                return False
            if self.active_box.walker.activate(value):
                self.active_box.walker.ls("")
                self.status_bar.set_command("")
                return True
            else :
                return False
        elif command.startswith('set') :
            if ' ' in command :
                cmd,end = command.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : set <field> to <value>')
                    return False
                end = end.strip()
                field,end = end.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : set <field> to <value>')
                    return False
                end = end.strip()
                to,value = end.split(' ',1)
                if len(value) == 0 or to != "to"  :
                    self.status_bar.update(status='Usage : set <field> to <value>')
                    return False
                value = value.strip()
                if self.active_box.walker.set(field, value):
                    self.active_box.walker.ls("")
                    self.status_bar.set_command("")
                    return True
                else :
                    return False
            else :
                self.status_bar.update(status='Usage : set <field> to <value>')
                return False
        elif command.startswith('poll') :
            if ' ' in command :
                cmd,end = command.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : poll <value> to <intensity>')
                    return False
                end = end.strip()
                field,end = end.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : poll <value> to <intensity>')
                    return False
                end = end.strip()
                to,value = end.split(' ',1)
                if len(value) == 0 or to != "to"  :
                    self.status_bar.update(status='Usage : poll <value> to <intensity>')
                    return False
                value = value.strip()
                if self.active_box.walker.poll(field, value):
                    self.active_box.walker.ls("")
                    self.status_bar.set_command("")
                    return True
                else :
                    return False
            else :
                self.status_bar.update(status='Usage : poll <value> to <intensity>')
                return False
        elif command.startswith('add') :
            if ' ' in command :
                cmd,end = command.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : add <value> to <list>')
                    return False
                end = end.strip()
                field,end = end.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : add <value> to <list>')
                    return False
                end = end.strip()
                to,value = end.split(' ',1)
                if len(value) == 0 or to != "to"  :
                    self.status_bar.update(status='Usage : add <value> to <list>')
                    return False
                value = value.strip()
                if self.active_box.walker.add(value, field):
                    self.active_box.walker.ls("")
                    self.status_bar.set_command("")
                    return True
                else :
                    return False
            else :
                self.status_bar.update(status='Usage : add <value> to <list>')
                return False
        elif command.startswith('remove') :
            if ' ' in command :
                cmd,end = command.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : remove <value> from <list>')
                    return False
                end = end.strip()
                field,end = end.split(' ',1)
                if len(end) == 0 or ' ' not in end :
                    self.status_bar.update(status='Usage : remove <value> from <list>')
                    return False
                end = end.strip()
                to,value = end.split(' ',1)
                if len(value) == 0 or to != "from"  :
                    self.status_bar.update(status='Usage : remove <value> from <list>')
                    return False
                value = value.strip()
                if self.active_box.walker.remove(value, field):
                    self.active_box.walker.ls("")
                    self.status_bar.set_command("")
                    return True
                else :
                    return False
            else :
                self.status_bar.update(status='Usage : remove <value> from <list>')
                return False
        elif command.startswith('reset') :
            if ' ' in command :
                cmd,state = command.split(' ',1)
                state = state.strip()
                if len(state) == 0 :
                    self.status_bar.update(status='Usage : reset soft|hard')
                    return False
                if self.active_box.walker.reset(state):
                    self.active_box.walker.ls("")
                    self.status_bar.set_command("")
                    return True
                else :
                    self.status_bar.update(status='Unknowm state "%s"' % state)
                    return False
        else:
            self.status_bar.update(status='Unknown command "%s"' % command)
            return False

    def _unhandled_input(self, key):
        if key == 'esc':
            self.exit()
        elif key == 'tab' or key == 'shift tab':
            if self.framefocus == 'footer':
                self.framefocus = 'body'
            else:
                self.framefocus = 'footer'
            self.frame.set_focus(self.framefocus)
            return True
        elif key == 'enter':
            self.log.info('handled: %s' % repr(key))
            cmd = self.status_bar.get_command()
            self.execute(cmd)
            return True
        elif key == 'f5':
            self.refresh_nodes()
            return True
        else:
            self.log.info('unhandled: %s' % repr(key))

    def _start_network(self):
        #Define some manager options
        self.options = ZWaveOption(self.device, \
          config_path="openzwave/config", \
          user_path=".", cmd_line="")
        self.options.set_log_file("OZW_Log.log")
        self.options.set_append_log_file(False)
        self.options.set_console_output(False)
        self.options.set_save_log_level("Internal")
        self.options.set_logging(True)
        self.options.lock()
        self.network = ZWaveNetwork(self.options, self.log)
        self.status_bar.update(status='Start Network')

    def _connect_louie(self):
        dispatcher.connect(self._louie_network_started, ZWaveNetwork.SIGNAL_NETWORK_STARTED)
        dispatcher.connect(self._louie_network_resetted, ZWaveNetwork.SIGNAL_NETWORK_RESETTED)
        dispatcher.connect(self._louie_network_awaked, ZWaveNetwork.SIGNAL_NETWORK_AWAKED)
        dispatcher.connect(self._louie_network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY)
        dispatcher.connect(self._louie_network_stopped, ZWaveNetwork.SIGNAL_NETWORK_STOPPED)

    def _louie_network_started(self, network):
        self.log.info('OpenZWave network is started : homeid %0.8x - %d nodes were found.' % \
            (network.home_id, network.nodes_count))
        self.network = network
        self.status_bar.update(status='OpenZWave network is started ... Waiting ...')
        self.loop.draw_screen()

    def _louie_network_resetted(self, network):
        self.log.info('OpenZWave network is resetted.')
        self.network = None
        #self._disconnect_louie_node_and_value()
        self.status_bar.update(status='OpenZWave network was resetted ... Waiting ...')
        self.loop.draw_screen()

    def _louie_network_stopped(self, network):
        self.log.info('OpenZWave network is stopped.')
        self.network = None
        self.status_bar.update(status='OpenZWave network was stopped ... please quit')
        self.loop.draw_screen()

    def _louie_network_awaked(self, network):
        self.log.info('OpenZWave network is awaked.')
        self.network = network
        self.status_bar.update(status='OpenZWave network is awaked ... Waiting ...')
        self.loop.draw_screen()

    def _louie_network_ready(self, network):
        self.log.info('ZWave network is ready : %d nodes were found.' % network.nodes_count)
        self.log.info('Controller name : %s' % network.controller.node.product_name)
        self.network = network
        self.status_bar.update(status='ZWave network is ready')
        self.loop.draw_screen()
        self._connect_louie_node_and_value()

    def _disconnect_louie_node_and_value(self):
        #pass
        dispatcher.disconnect(self._louie_group, ZWaveNetwork.SIGNAL_GROUP)
        dispatcher.disconnect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE)
        dispatcher.disconnect(self._louie_value_update, ZWaveNetwork.SIGNAL_VALUE)
        dispatcher.disconnect(self._louie_ctrl_message, ZWaveController.SIGNAL_CONTROLLER)

    def _connect_louie_node_and_value(self):
        #pass
        dispatcher.connect(self._louie_group, ZWaveNetwork.SIGNAL_GROUP)
        dispatcher.connect(self._louie_node_update, ZWaveNetwork.SIGNAL_NODE)
        dispatcher.connect(self._louie_value_update, ZWaveNetwork.SIGNAL_VALUE)
        dispatcher.connect(self._louie_ctrl_message, ZWaveController.SIGNAL_CONTROLLER)

    def _louie_node_update(self, network, node):
        self.loop.draw_screen()

    def _louie_value_update(self, network, node, value):
        self.loop.draw_screen()

    def _louie_group(self, network, node):
        self.loop.draw_screen()

    def _louie_ctrl_message(self, state, message, network, controller):
        #self.status_bar.update(status='Message from controller: %s : %s' % (state,message))
        self.status_bar.update(status='Message from controller: %s' % (message))
        self.loop.draw_screen()
Esempio n. 29
0
class ZWaveAgent(AbstractAgent):
    """A Zwave Agent for directly collecting data from a ZWave network. Requires openzwave to be
    installed (see tools folder) and ZWave Stick to be plugged in"""

    def __init__(self, configDir, osnInstance):
        AbstractAgent.__init__(self, configDir, osnInstance)

        log="Info" # should be read from config later

        configChanged = False
        if "zwave_device" not in self.configData:
            self.configData["zwave_device"] = "/dev/ttyACM0"
            configChanged = True
        if configChanged:
            self.serializeConfig()

        # handle zwave default device configurations
        self.zwaveDefaultConfigs = {}
        self.zwaveDefaultConfigFile = os.path.join(self.configDir, "zwavedefaultconfigs.config.json")
        self.readZwaveDefaultConfigs()

        self.device = self.configData["zwave_device"]
        self.logger.debug("Initiating ZWaveAgent with device %s." % self.device)
        self.zwaveOptions = ""
        try:
            self.zwaveOptions = ZWaveOption(self.device.encode('ascii'), \
            config_path=expanduser("~")+"/ozw-install/python-open-zwave/openzwave/config", \
            user_path=self.configDir, cmd_line="")
            self.zwaveOptions.set_log_file("../log/openzwave.log") # Todo: don't hardcode openzwave-path
            self.zwaveOptions.set_append_log_file(False)
            self.zwaveOptions.set_console_output(False)
            self.zwaveOptions.set_save_log_level(log)
            self.zwaveOptions.set_logging(False)
            self.zwaveOptions.lock()
        except BaseException as e:
            self.logger.info("Error setting up ZWave network. Correct device? Device properly connected? Device is: %s Exception message: %s" % (self.device, e))
        self.inDiscoveryMode = False #scanning for available devices and sensors is slightly more complicated here...

    def networkStarted(self, network):
        self.logger.info("Network %0.8x started" % network.home_id)

    def networkFailed(self, network):
        self.logger.warning("Sorry, Network couldn't be started...")
        if self.inDiscoveryMode:
            self.logger("Discovery failed - terminating.")
            self.stop()

    def networkReady(self, network):
        self.logger.info("Network %0.8x is ready - %d nodes were found." % (self.network.home_id, self.network.nodes_count))
        self.logger.info("Network controller %s is connected to %s" % (self.network.controller.node.product_name, self.device))
        self.logger.info("\nNodes List:")
        self.logger.info("===========")
        configChanged = False
        for node in network.nodes:
            self.logger.info("Node %s: %s (battery: %s)" % (node, network.nodes[node].product_name, network.nodes[node].get_battery_level()))
            self.logger.info("Available Command Classes: %s" % network.nodes[node].command_classes)
            modelString = network.nodes[node].manufacturer_name + " " + network.nodes[node].product_name
            if node != self.network.controller.node_id: # not for controller node
                # Should usually only be necessary once in a lifetime for a given network, but repeating it on every startup doesn't ha$
                self.configureNode(network, node)
            for sensor in network.nodes[node].get_sensors():
                if ((not self.sensorConfigured(sensor)) and (self.inDiscoveryMode)):
                    # we are in discovery mode and sensor is not configured yet, add default
                    self.addDefaultSensor(sensor, network.nodes[node].get_sensors()[sensor].label, network.nodes[node].get_sensors()[sensor].units, {"sensorModel":modelString})
                    configChanged = True
                self.logger.debug("Sensor %s has %s of %s (Unit: %s)" % (sensor, network.nodes[node].get_sensors()[sensor].label, \
                                                              network.nodes[node].get_sensor_value(sensor), network.nodes[node].get_sensors()[sensor].units))
        if self.inDiscoveryMode:
            # as discovery is more complicated for Zwave, we have to do it this way.
            # in discovery Mode, the config including new default configurations is serialized, then the agent Is stopped.
            if configChanged:
                # serialize for having all new sensors in config
                self.serializeConfig()
            self.isRunning = False # this ensures that runner stops this agent after discovery is completed
        else:
            dispatcher.connect(self.nodeUpdate, ZWaveNetwork.SIGNAL_NODE)
            dispatcher.connect(self.valueUpdate, ZWaveNetwork.SIGNAL_VALUE)

    def nodeUpdate(self, network, node):
        # maybe do something valuable here later...
        self.logger.debug('Received node update from node : %s.' % node)
        pass

    def valueUpdate(self, network, node, value):
        # not sure whether this might produce redundancies in case of one value_id appearing for multiple nodes...
        # nonetheless, staying with this for the moment
        self.sendValue(value.value_id, value.data)

    def configureNode(self,network, node):
        # Model-specific configuration of node. This definitely needs a complete rewrite later...
        self.logger.info("Setting specific configuration for product %s (Product ID: %s)..." % (network.nodes[node].product_name, network.nodes[node].product_id))
        productId = network.nodes[node].product_id
        defaultConfig = self.getDefaultDeviceConfiguration(productId)
        if defaultConfig: # could also be empty in case this product has no default config yet
            self.logger.debug("Got default config.")
            for param in network.nodes[node].values.values(): # traverse through available parameters
                self.logger.debug("Checking if default config exists for %s" % param.value_id)
                if defaultConfig.has_key("%s" % param.value_id): # is this parameter specified in default config? we take the long value id as key to avoid misinterpretations
                    self.logger.debug("Default config found. Now checking if default config contains a value")
                    if defaultConfig["%s" % param.value_id].has_key("value"):
                        self.logger.debug("Found value. Setting parameter <%s> to %s as specified in default config" % (param.label, defaultConfig["%s" % param.value_id]["value"]))
                        param.data = defaultConfig["%s" % param.value_id]["value"]
        else:
            self.logger.info("No default configuration found for device with product id %s - creating dumb template from what is reported..." % productId)
            newConfig = {}
            for param in network.nodes[node].values.values(): # traverse through available parameters
                newConfig["product name"] = network.nodes[node].manufacturer_name + " " + network.nodes[node].product_name
                newConfig[param.value_id] = {}
                note = param.label
                if param.units:
                    note = note + " (" + param.units + ")"
                newConfig[param.value_id]["note"] = note
                newConfig[param.value_id]["parameter index"] = param.index
                newConfig[param.value_id]["value"] = param.data
            self.zwaveDefaultConfigs["products"][productId] = newConfig
            self.serializeZwaveDefaultConfigs()

    def getDefaultDeviceConfiguration(self, productId):
        self.logger.debug("getting zwave default configs for product id %s" % productId)
        if self.zwaveDefaultConfigs["products"].has_key(productId):
            return self.zwaveDefaultConfigs["products"][productId]
        else:
            return {}

    def readZwaveDefaultConfigs(self):
        self.logger.debug("reading zwave default device configs from %s" % self.zwaveDefaultConfigFile)
        configChanged = False
        if os.path.isfile(self.zwaveDefaultConfigFile): # If configFile does not exist yet, default configs will be created and serialized later
            with open(self.zwaveDefaultConfigFile) as configFileHandle:
                self.zwaveDefaultConfigs = json.load(configFileHandle)
        if "products" not in self.zwaveDefaultConfigs:
            self.zwaveDefaultConfigs["products"]={}
            configChanged = True
        if (configChanged):
            self.serializeZwaveDefaultConfigs()

    def serializeZwaveDefaultConfigs(self):
        with open(self.zwaveDefaultConfigFile, "w") as configFileHandle:
            self.logger.info("Serializing zwave default device configs to %s." % self.zwaveDefaultConfigFile)
            json.dump(self.zwaveDefaultConfigs, configFileHandle, sort_keys = False, indent = 4, ensure_ascii=False)
            # data_file.close

    def run(self):
        self.isRunning = True
        #Create a network object
        self.network = ZWaveNetwork(self.zwaveOptions, autostart=False)
        #and connect our above handlers to respective events
        dispatcher.connect(self.networkStarted, ZWaveNetwork.SIGNAL_NETWORK_STARTED)
        dispatcher.connect(self.networkFailed, ZWaveNetwork.SIGNAL_NETWORK_FAILED)
        dispatcher.connect(self.networkReady, ZWaveNetwork.SIGNAL_NETWORK_READY)
        self.network.start()

    def discoverSensors(self):
        self.inDiscoveryMode = True
        # In this case, stuff is slightly more complicated as we have to manage the zwave network, too.
        # We thus here use the thread's run()-method and terinate once the discovery is complete.
        self.run()

    def stop(self):
        self.network.stop()
        self.isRunning = False
Esempio n. 30
0
async def async_setup_entry(hass, config_entry):
    """Set up Z-Wave from a config entry.

    Will automatically load components to support devices found on the network.
    """
    from pydispatch import dispatcher

    # pylint: disable=import-error
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    # Merge config entry and yaml config
    config = config_entry.data
    if DATA_ZWAVE_CONFIG in hass.data:
        config = {**config, **hass.data[DATA_ZWAVE_CONFIG]}

    # Update hass.data with merged config so we can access it elsewhere
    hass.data[DATA_ZWAVE_CONFIG] = config

    # Load configuration
    use_debug = config.get(CONF_DEBUG, DEFAULT_DEBUG)
    autoheal = config.get(CONF_AUTOHEAL, DEFAULT_CONF_AUTOHEAL)
    device_config = EntityValues(
        config.get(CONF_DEVICE_CONFIG),
        config.get(CONF_DEVICE_CONFIG_DOMAIN),
        config.get(CONF_DEVICE_CONFIG_GLOB),
    )

    usb_path = config[CONF_USB_STICK_PATH]

    _LOGGER.info("Z-Wave USB path is %s", usb_path)

    # Setup options
    options = ZWaveOption(
        usb_path,
        user_path=hass.config.config_dir,
        config_path=config.get(CONF_CONFIG_PATH),
    )

    options.set_console_output(use_debug)

    if config.get(CONF_NETWORK_KEY):
        options.addOption("NetworkKey", config[CONF_NETWORK_KEY])

    await hass.async_add_executor_job(options.lock)
    network = hass.data[DATA_NETWORK] = ZWaveNetwork(options, autostart=False)
    hass.data[DATA_DEVICES] = {}
    hass.data[DATA_ENTITY_VALUES] = []

    registry = await async_get_registry(hass)

    wsapi.async_load_websocket_api(hass)

    if use_debug:  # pragma: no cover

        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (
                    ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED,
                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED_SOME_DEAD,
            ):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Handle new added value to a node on the network."""
        # Check if this value should be tracked by an existing entity
        for values in hass.data[DATA_ENTITY_VALUES]:
            values.check_value(value)

        for schema in DISCOVERY_SCHEMAS:
            if not check_node_schema(node, schema):
                continue
            if not check_value_schema(
                    value, schema[const.DISC_VALUES][const.DISC_PRIMARY]):
                continue

            values = ZWaveDeviceEntityValues(hass, schema, value, config,
                                             device_config, registry)

            # We create a new list and update the reference here so that
            # the list can be safely iterated over in the main thread
            new_values = hass.data[DATA_ENTITY_VALUES] + [values]
            hass.data[DATA_ENTITY_VALUES] = new_values

    platform = EntityPlatform(
        hass=hass,
        logger=_LOGGER,
        domain=DOMAIN,
        platform_name=DOMAIN,
        platform=None,
        scan_interval=DEFAULT_SCAN_INTERVAL,
        entity_namespace=None,
        async_entities_added_callback=lambda: None,
    )
    platform.config_entry = config_entry

    def node_added(node):
        """Handle a new node on the network."""
        entity = ZWaveNodeEntity(node, network)

        async def _add_node_to_component():
            if hass.data[DATA_DEVICES].get(entity.unique_id):
                return

            name = node_name(node)
            generated_id = generate_entity_id(DOMAIN + ".{}", name, [])
            node_config = device_config.get(generated_id)
            if node_config.get(CONF_IGNORED):
                _LOGGER.info("Ignoring node entity %s due to device settings",
                             generated_id)
                return

            hass.data[DATA_DEVICES][entity.unique_id] = entity
            await platform.async_add_entities([entity])

        if entity.unique_id:
            hass.async_add_job(_add_node_to_component())
            return

        @callback
        def _on_ready(sec):
            _LOGGER.info("Z-Wave node %d ready after %d seconds",
                         entity.node_id, sec)
            hass.async_add_job(_add_node_to_component)

        @callback
        def _on_timeout(sec):
            _LOGGER.warning(
                "Z-Wave node %d not ready after %d seconds, "
                "continuing anyway",
                entity.node_id,
                sec,
            )
            hass.async_add_job(_add_node_to_component)

        hass.add_job(check_has_unique_id, entity, _on_ready, _on_timeout)

    def node_removed(node):
        node_id = node.node_id
        node_key = f"node-{node_id}"
        _LOGGER.info("Node Removed: %s", hass.data[DATA_DEVICES][node_key])
        for key in list(hass.data[DATA_DEVICES]):
            if not key.startswith(f"{node_id}-"):
                continue

            entity = hass.data[DATA_DEVICES][key]
            _LOGGER.info("Removing Entity - value: %s - entity_id: %s", key,
                         entity.entity_id)
            hass.add_job(entity.node_removed())
            del hass.data[DATA_DEVICES][key]

        entity = hass.data[DATA_DEVICES][node_key]
        hass.add_job(entity.node_removed())
        del hass.data[DATA_DEVICES][node_key]

    def network_ready():
        """Handle the query of all awake nodes."""
        _LOGGER.info("Z-Wave network is ready for use. All awake nodes "
                     "have been queried. Sleeping nodes will be "
                     "queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Handle the querying of all nodes on network."""
        _LOGGER.info("Z-Wave network is complete. All nodes on the network "
                     "have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    def network_complete_some_dead():
        """Handle the querying of all nodes on network."""
        _LOGGER.info("Z-Wave network is complete. All nodes on the network "
                     "have been queried, but some nodes are marked dead")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE_SOME_DEAD)

    dispatcher.connect(value_added,
                       ZWaveNetwork.SIGNAL_VALUE_ADDED,
                       weak=False)
    dispatcher.connect(node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
    dispatcher.connect(node_removed,
                       ZWaveNetwork.SIGNAL_NODE_REMOVED,
                       weak=False)
    dispatcher.connect(network_ready,
                       ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                       weak=False)
    dispatcher.connect(network_complete,
                       ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED,
                       weak=False)
    dispatcher.connect(
        network_complete_some_dead,
        ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED_SOME_DEAD,
        weak=False,
    )

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Z-Wave add_node have been initialized")
        network.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Z-Wave add_node_secure have been initialized")
        network.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Z-Wave remove_node have been initialized")
        network.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running Z-Wave command")
        network.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("Z-Wave heal running")
        network.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Z-Wave soft_reset have been initialized")
        network.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Z-Wave test_network have been initialized")
        network.test()

    def stop_network(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping Z-Wave network")
        network.stop()
        if hass.state == CoreState.running:
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    async def rename_node(service):
        """Rename a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info("Renamed Z-Wave node %d to %s", node_id, name)
        update_ids = service.data.get(const.ATTR_UPDATE_IDS)
        # We want to rename the device, the node entity,
        # and all the contained entities
        node_key = f"node-{node_id}"
        entity = hass.data[DATA_DEVICES][node_key]
        await entity.node_renamed(update_ids)
        for key in list(hass.data[DATA_DEVICES]):
            if not key.startswith(f"{node_id}-"):
                continue
            entity = hass.data[DATA_DEVICES][key]
            await entity.value_renamed(update_ids)

    async def rename_value(service):
        """Rename a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        name = service.data.get(const.ATTR_NAME)
        value.label = name
        _LOGGER.info("Renamed Z-Wave value (Node %d Value %d) to %s", node_id,
                     value_id, name)
        update_ids = service.data.get(const.ATTR_UPDATE_IDS)
        value_key = f"{node_id}-{value_id}"
        entity = hass.data[DATA_DEVICES][value_key]
        await entity.value_renamed(update_ids)

    def set_poll_intensity(service):
        """Set the polling intensity of a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        intensity = service.data.get(const.ATTR_POLL_INTENSITY)
        if intensity == 0:
            if value.disable_poll():
                _LOGGER.info("Polling disabled (Node %d Value %d)", node_id,
                             value_id)
                return
            _LOGGER.info("Polling disabled failed (Node %d Value %d)", node_id,
                         value_id)
        else:
            if value.enable_poll(intensity):
                _LOGGER.info(
                    "Set polling intensity (Node %d Value %d) to %s",
                    node_id,
                    value_id,
                    intensity,
                )
                return
            _LOGGER.info("Set polling intensity failed (Node %d Value %d)",
                         node_id, value_id)

    def remove_failed_node(service):
        """Remove failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to remove zwave node %d", node_id)
        network.controller.remove_failed_node(node_id)

    def replace_failed_node(service):
        """Replace failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to replace zwave node %d", node_id)
        network.controller.replace_failed_node(node_id)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE)
        for value in node.get_values(
                class_id=const.COMMAND_CLASS_CONFIGURATION).values():
            if value.index != param:
                continue
            if value.type == const.TYPE_BOOL:
                value.data = int(selection == "True")
                _LOGGER.info(
                    "Setting config parameter %s on Node %s "
                    "with bool selection %s",
                    param,
                    node_id,
                    str(selection),
                )
                return
            if value.type == const.TYPE_LIST:
                value.data = str(selection)
                _LOGGER.info(
                    "Setting config parameter %s on Node %s "
                    "with list selection %s",
                    param,
                    node_id,
                    str(selection),
                )
                return
            if value.type == const.TYPE_BUTTON:
                network.manager.pressButton(value.value_id)
                network.manager.releaseButton(value.value_id)
                _LOGGER.info(
                    "Setting config parameter %s on Node %s "
                    "with button selection %s",
                    param,
                    node_id,
                    selection,
                )
                return
            value.data = int(selection)
            _LOGGER.info(
                "Setting config parameter %s on Node %s "
                "with selection %s",
                param,
                node_id,
                selection,
            )
            return
        node.set_config_param(param, selection, size)
        _LOGGER.info(
            "Setting unknown config parameter %s on Node %s "
            "with selection %s",
            param,
            node_id,
            selection,
        )

    def refresh_node_value(service):
        """Refresh the specified value from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        node.values[value_id].refresh()
        _LOGGER.info("Node %s value %s refreshed", node_id, value_id)

    def set_node_value(service):
        """Set the specified value on a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        node = network.nodes[node_id]
        node.values[value_id].data = value
        _LOGGER.info("Node %s value %s set to %s", node_id, value_id, value)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info(
            "Config parameter %s on Node %s: %s",
            param,
            node_id,
            get_config_value(node, param),
        )

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, network, node_id)
        if association_type == "add":
            node.add_association(target_node_id, instance)
            _LOGGER.info(
                "Adding association for node:%s in group:%s "
                "target node:%s, instance=%s",
                node_id,
                group,
                target_node_id,
                instance,
            )
        if association_type == "remove":
            node.remove_association(target_node_id, instance)
            _LOGGER.info(
                "Removing association for node:%s in group:%s "
                "target node:%s, instance=%s",
                node_id,
                group,
                target_node_id,
                instance,
            )

    async def async_refresh_entity(service):
        """Refresh values that specific entity depends on."""
        entity_id = service.data.get(ATTR_ENTITY_ID)
        async_dispatcher_send(hass,
                              SIGNAL_REFRESH_ENTITY_FORMAT.format(entity_id))

    def refresh_node(service):
        """Refresh all node info."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        node.refresh_info()

    def reset_node_meters(service):
        """Reset meter counters of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        instance = service.data.get(const.ATTR_INSTANCE)
        node = network.nodes[node_id]
        for value in node.get_values(
                class_id=const.COMMAND_CLASS_METER).values():
            if value.index != const.INDEX_METER_RESET:
                continue
            if value.instance != instance:
                continue
            network.manager.pressButton(value.value_id)
            network.manager.releaseButton(value.value_id)
            _LOGGER.info("Resetting meters on node %s instance %s....",
                         node_id, instance)
            return
        _LOGGER.info(
            "Node %s on instance %s does not have resettable "
            "meters.",
            node_id,
            instance,
        )

    def heal_node(service):
        """Heal a node on the network."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        update_return_routes = service.data.get(const.ATTR_RETURN_ROUTES)
        node = network.nodes[node_id]
        _LOGGER.info("Z-Wave node heal running for node %s", node_id)
        node.heal(update_return_routes)

    def test_node(service):
        """Send test messages to a node on the network."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        messages = service.data.get(const.ATTR_MESSAGES)
        node = network.nodes[node_id]
        _LOGGER.info("Sending %s test-messages to node %s.", messages, node_id)
        node.test(messages)

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting Z-Wave network...")
        network.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        async def _check_awaked():
            """Wait for Z-wave awaked state (or timeout) and finalize start."""
            _LOGGER.debug("network state: %d %s", network.state,
                          network.state_str)

            start_time = dt_util.utcnow()
            while True:
                waited = int((dt_util.utcnow() - start_time).total_seconds())

                if network.state >= network.STATE_AWAKED:
                    # Need to be in STATE_AWAKED before talking to nodes.
                    _LOGGER.info("Z-Wave ready after %d seconds", waited)
                    break
                elif waited >= const.NETWORK_READY_WAIT_SECS:
                    # Wait up to NETWORK_READY_WAIT_SECS seconds for the Z-Wave
                    # network to be ready.
                    _LOGGER.warning(
                        "Z-Wave not ready after %d seconds, continuing anyway",
                        waited)
                    _LOGGER.info("final network state: %d %s", network.state,
                                 network.state_str)
                    break
                else:
                    await asyncio.sleep(1)

            hass.async_add_job(_finalize_start)

        hass.add_job(_check_awaked)

    def _finalize_start():
        """Perform final initializations after Z-Wave network is awaked."""
        polling_interval = convert(config.get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            network.set_poll_interval(polling_interval, False)

        poll_interval = network.get_poll_interval()
        _LOGGER.info("Z-Wave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node)
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure)
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node)
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command)
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network)
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset)
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network)
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
                               stop_network)
        hass.services.register(DOMAIN,
                               const.SERVICE_RENAME_NODE,
                               rename_node,
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_RENAME_VALUE,
                               rename_value,
                               schema=RENAME_VALUE_SCHEMA)
        hass.services.register(
            DOMAIN,
            const.SERVICE_SET_CONFIG_PARAMETER,
            set_config_parameter,
            schema=SET_CONFIG_PARAMETER_SCHEMA,
        )
        hass.services.register(
            DOMAIN,
            const.SERVICE_SET_NODE_VALUE,
            set_node_value,
            schema=SET_NODE_VALUE_SCHEMA,
        )
        hass.services.register(
            DOMAIN,
            const.SERVICE_REFRESH_NODE_VALUE,
            refresh_node_value,
            schema=REFRESH_NODE_VALUE_SCHEMA,
        )
        hass.services.register(
            DOMAIN,
            const.SERVICE_PRINT_CONFIG_PARAMETER,
            print_config_parameter,
            schema=PRINT_CONFIG_PARAMETER_SCHEMA,
        )
        hass.services.register(
            DOMAIN,
            const.SERVICE_REMOVE_FAILED_NODE,
            remove_failed_node,
            schema=NODE_SERVICE_SCHEMA,
        )
        hass.services.register(
            DOMAIN,
            const.SERVICE_REPLACE_FAILED_NODE,
            replace_failed_node,
            schema=NODE_SERVICE_SCHEMA,
        )

        hass.services.register(
            DOMAIN,
            const.SERVICE_CHANGE_ASSOCIATION,
            change_association,
            schema=CHANGE_ASSOCIATION_SCHEMA,
        )
        hass.services.register(DOMAIN,
                               const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_PRINT_NODE,
                               print_node,
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(
            DOMAIN,
            const.SERVICE_REFRESH_ENTITY,
            async_refresh_entity,
            schema=REFRESH_ENTITY_SCHEMA,
        )
        hass.services.register(DOMAIN,
                               const.SERVICE_REFRESH_NODE,
                               refresh_node,
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(
            DOMAIN,
            const.SERVICE_RESET_NODE_METERS,
            reset_node_meters,
            schema=RESET_NODE_METERS_SCHEMA,
        )
        hass.services.register(
            DOMAIN,
            const.SERVICE_SET_POLL_INTENSITY,
            set_poll_intensity,
            schema=SET_POLL_INTENSITY_SCHEMA,
        )
        hass.services.register(DOMAIN,
                               const.SERVICE_HEAL_NODE,
                               heal_node,
                               schema=HEAL_NODE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_TEST_NODE,
                               test_node,
                               schema=TEST_NODE_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("Z-Wave network autoheal is enabled")
        async_track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    hass.services.async_register(DOMAIN, const.SERVICE_START_NETWORK,
                                 start_zwave)

    for entry_component in SUPPORTED_PLATFORMS:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(
                config_entry, entry_component))

    return True
Esempio n. 31
0
def setup(hass, config):
    """
    Setup Z-wave.
    Will automatically load components to support devices found on the network.
    """
    # pylint: disable=global-statement, import-error
    global NETWORK

    from pydispatch import dispatcher
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork

    use_debug = str(config[DOMAIN].get(CONF_DEBUG)) == '1'

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH, DEFAULT_CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir)

    options.set_console_output(use_debug)
    options.lock()

    NETWORK = ZWaveNetwork(options, autostart=False)

    if use_debug:
        def log_all(signal, value=None):
            """ Log all the signals. """
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED):
                pprint(_obj_to_dict(value))
            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """ Called when a value is added to a node on the network. """
        for component, discovery_service, command_ids in DISCOVERY_COMPONENTS:
            if value.command_class in command_ids:
                # Ensure component is loaded
                bootstrap.setup_component(hass, component, config)

                # Fire discovery event
                hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
                    ATTR_SERVICE: discovery_service,
                    ATTR_DISCOVERED: {
                        ATTR_NODE_ID: node.node_id,
                        ATTR_VALUE_ID: value.value_id,
                    }
                })

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)

    def stop_zwave(event):
        """ Stop Z-wave. """
        NETWORK.stop()

    def start_zwave(event):
        """ Called when Home Assistant starts up. """
        NETWORK.start()

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    return True
    def __init__(self, **kwargs):
        """Attrs initialized here have names as in :dict:`_initials`

        Doctests
        ++++++++

        >>> t.start()
        (True, 'OK')

        # >>> t.hard_reset(force=True)
        # (True, 'OK')
        # >>> print("*** Action needed for node to be _added_ ***") # doctest:+ELLIPSIS
        # *** ...
        # >>> t.add_node() # doctest:+ELLIPSIS
        # {...}
        """
        if self._initialized:
            raise RuntimeErr("[Bug] backend already initialized!?")

        self._initialized = True

        # set defaults
        for attr in self._initials.keys():
            setattr(self, attr, self._initials[attr])

        # ...remainder.
        for k in kwargs.keys():
            if not hasattr(self, k):
                raise AttributeError(
                    "{}: no such attribute in definition of class {}.".format(
                        k, self.__class__.__name__))
            else:
                setattr(self, k, kwargs[k])

        # we put all artifacts here
        user_path = os.path.expanduser(os.path.expandvars(self.ozw_user_path))
        try:
            os.makedirs(self.ozw_user_path, exist_ok=True)
        except Exception as e:
            raise RuntimeError("Can't create user_path: {}".format(e))

        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(self.log_level)

        fh = logging.FileHandler("{}/{}.log".format(self.ozw_user_path,
                                                    __name__),
                                 mode='w')
        fh.setLevel(self.log_level)
        fh.setFormatter(
            logging.Formatter(self.log_format_dbg if self.log_level <= logging.
                              DEBUG else self.log_format))
        self.logger.addHandler(fh)

        self.logger.debug('initializing OZW backend...')

        options = ZWaveOption(self.device,
                              config_path=self.ozw_config_path,
                              user_path=self.ozw_user_path)

        options.set_log_file('OZW.log')
        options.set_append_log_file(False)
        options.set_console_output(False)
        options.set_save_log_level(
            'Debug' if self.log_level <= logging.DEBUG else 'Warning')
        options.set_logging(True)
        options.lock()

        self.network = ZWaveNetwork(options, autostart=False)

        # A dispatcher associates a callback method to a signal. Signals
        # are generated by the library python-openzwave. Once a signal is
        # received, its associated callback is executed (see "_node_added"
        # example below in "_network_started" method)
        dispatcher.connect(self._network_started,
                           ZWaveNetwork.SIGNAL_NETWORK_STARTED)
        dispatcher.connect(self._network_ready,
                           ZWaveNetwork.SIGNAL_NETWORK_READY)
        # Yep! It's really 'RESETTED', wanna file a bug for bad english usage? ;-)
        dispatcher.connect(self._network_reset,
                           ZWaveNetwork.SIGNAL_NETWORK_RESETTED)

        # dynamically set on add/remove events. See notification handlers below.
        self.node_added = None
        self.node_removed = None
        self.timestamps = {
        }  # times of the last values' update for each sensor

        # The different stages that a node object gets through before being
        # ready. [BUG] Why do we need to explicitly list them? Anyway to get
        # them from the lib?
        self.queryStages = {
            "None": 1,  # Query process hasn't started for this node
            "ProtocolInfo": 2,  # Retrieve protocol information
            "Probe": 3,  # Ping node to see if alive
            "WakeUp": 4,  # Start wake up process if a sleeping node
            "ManufacturerSpecific1":
            5,  # Retrieve manufacturer name and product ids if ProtocolInfo lets us
            "NodeInfo":
            6,  # Retrieve info about supported, controlled command classes
            "NodePlusInfo":
            7,  # Retrieve Z-Wave+ info and update device classes (Added by Edin et Daniel)
            "SecurityReport":
            8,  # Retrieve a list of Command Classes that require Security
            "ManufacturerSpecific2":
            9,  # Retrieve manufacturer name and product ids
            "Versions": 10,  # Retrieve version information
            "Instances":
            11,  # Retrieve information about multiple command class instances
            "Static": 12,  # Retrieve static information (doesn't change)
            "Probe1": 13,  # Ping a node upon starting with configuration
            "Associations": 14,  # Retrieve information about associations
            "Neighbors": 15,  # Retrieve node neighbor list
            "Session":
            16,  # Retrieve session information (changes infrequently)
            "Dynamic": 17,  # Retrieve dynamic information (changes frequently)
            "Configuration":
            18,  # Retrieve configurable parameter information (only done on request)
            "Complete": 19  # Query process is completed for this node
        }
Esempio n. 33
0
def setup(hass, config):
    """
    Setup Z-wave.
    Will automatically load components to support devices found on the network.
    """
    # pylint: disable=global-statement, import-error
    global NETWORK

    from pydispatch import dispatcher
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork

    # Load configuration
    use_debug = str(config[DOMAIN].get(CONF_DEBUG)) == '1'
    customize = config[DOMAIN].get(CONF_CUSTOMIZE, {})

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH, DEFAULT_CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get('config_path',
                                       DEFAULT_ZWAVE_CONFIG_PATH),
    )

    options.set_console_output(use_debug)
    options.lock()

    NETWORK = ZWaveNetwork(options, autostart=False)

    if use_debug:

        def log_all(signal, value=None):
            """ Log all the signals. """
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """ Called when a value is added to a node on the network. """

        for (component, discovery_service, command_ids, value_type,
             value_genre) in DISCOVERY_COMPONENTS:

            if value.command_class not in command_ids:
                continue
            if value_type is not None and value_type != value.type:
                continue
            if value_genre is not None and value_genre != value.genre:
                continue

            # Ensure component is loaded
            bootstrap.setup_component(hass, component, config)

            # Configure node
            name = "{}.{}".format(component, _object_id(value))

            node_config = customize.get(name, {})
            polling_intensity = convert(
                node_config.get(CONF_POLLING_INTENSITY), int)
            if polling_intensity is not None:
                value.enable_poll(polling_intensity)

            # Fire discovery event
            hass.bus.fire(
                EVENT_PLATFORM_DISCOVERED, {
                    ATTR_SERVICE: discovery_service,
                    ATTR_DISCOVERED: {
                        ATTR_NODE_ID: node.node_id,
                        ATTR_VALUE_ID: value.value_id,
                    }
                })

    def scene_activated(node, scene_id):
        """ Called when a scene is activated on any node in the network. """
        name = _node_name(node)
        object_id = "{}_{}".format(slugify(name), node.node_id)

        hass.bus.fire(EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: object_id,
            ATTR_SCENE_ID: scene_id
        })

    dispatcher.connect(value_added,
                       ZWaveNetwork.SIGNAL_VALUE_ADDED,
                       weak=False)
    dispatcher.connect(scene_activated,
                       ZWaveNetwork.SIGNAL_SCENE_EVENT,
                       weak=False)

    def add_node(event):
        """ Switch into inclusion mode """
        NETWORK.controller.begin_command_add_device()

    def remove_node(event):
        """ Switch into exclusion mode"""
        NETWORK.controller.begin_command_remove_device()

    def stop_zwave(event):
        """ Stop Z-wave. """
        NETWORK.stop()

    def start_zwave(event):
        """ Called when Home Assistant starts up. """
        NETWORK.start()

        polling_interval = convert(config[DOMAIN].get(CONF_POLLING_INTERVAL),
                                   int)
        if polling_interval is not None:
            NETWORK.set_poll_interval(polling_interval, False)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)

        # register add / remove node services for zwave sticks without
        # hardware inclusion button
        hass.services.register(DOMAIN, SERVICE_ADD_NODE, add_node)
        hass.services.register(DOMAIN, SERVICE_REMOVE_NODE, remove_node)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    return True
Esempio n. 34
0
class MyZwave:
    device="/dev/ttyACM0"
    config_path="/home/pi/Documents/Development/Python/python-openzwave-0.3.2/openzwave/config"
    log="Debug"
    network = None
    options = None

    def __init__(self):
        self.device="/dev/ttyACM0"
        self.config_path="/home/pi/Documents/Development/Python/python-openzwave-0.3.2/openzwave/config"
        self.log="Debug"
        self.network = None
        self.options = None

    def initZwave(self):
        self.options = ZWaveOption(self.device, config_path=self.config_path, user_path=".", cmd_line="")
        self.options.set_log_file("MyZWave_log.log")
        self.options.set_append_log_file(False)
        self.options.set_console_output(False)
        #self.options.set_console_output(True)
        self.options.set_save_log_level(self.log)
        self.options.set_logging(False)
        self.options.lock()

        self.network = ZWaveNetwork(self.options, log=None)

        time_started=0
        print("*** Waiting for network to awake: ")
        for i in range(0,300):
            if self.network.state >= self.network.STATE_AWAKED:
                print(" done")
                break
            else:
                sys.stdout.write(".")
                sys.stdout.flush()
                time_started += 1
                time.sleep(1.0)

        if self.network.state < self.network.STATE_AWAKED:
            print(".")
            print("Network is not awaked")
        for i in range(0,300):
            if self.network.state >= self.network.STATE_READY:
                print(" done in{} seconds".format(time_started))
                break
            else:
                sys.stdout.write(".")
                sys.stdout.flush()
                time_started += 1
                time.sleep(1.0)

        if not self.network.is_ready:
            print(".")
            print("Network is not ready")

    def toggleSwitch(self,nodeNum):
        node=self.network.nodes[nodeNum]
        print("Node: {}".format(node))
        val=node.get_switches().keys()[0]
        print("Values: {}".format(val))
        state = node.get_switch_state(val)
        print("State: {}".format(state))
        node.set_switch(val,not state)
        time.sleep(0.2)
        state = node.get_switch_state(val)
        return "on" if state else "off"

    def getSwitchStatus(self, nodeNum):
        node = self.network.nodes[nodeNum]
        val = node.get_switches().keys()[0]
        state = node.get_switch_state(val)
        return "on" if state else "off"

    def getInt(self, strNo):
        if strNo == None:
            return 0
        else:
            try:
                temp = int(strNo)
            except ValueError:
                temp = 0
            return temp
Esempio n. 35
0
    def __init__(self, object_group, config):
        Plugin.__init__(self, config=config, object_group=object_group, plugin_name=PLUGIN_NAME)

        # Get parameters from the config file

        if not self.is_enabled():
            return

        # Initialize zwave library
        # Options
        try:
            opts = ZWaveOption(device="/dev/ttyUSB0",
                               config_path="/home/mlamonta/git/python-openzwave/openzwave/config/",
                               user_path="logs")
            opts.set_log_file("./logs/zwave.log")
            opts.set_save_log_level("Alert")
            opts.set_append_log_file(False)
            opts.set_console_output(False)
            opts.set_logging(True)
            opts.lock()
        except ZWaveException as e:
            self.logger.error(str(e))
            return

        # Network
        self.net = ZWaveNetwork(opts)

        self.logger.info("------------------------------------------------------------")
        self.logger.info("Waiting for network awake : ")
        self.logger.info("------------------------------------------------------------")
        for i in range(0, 300):
            if self.net.state >= self.net.STATE_AWAKED:
                self.logger.info("done")
                break
            else:
                time.sleep(1.0)

        if self.net.state < self.net.STATE_AWAKED:
            self.logger.warning("Network is not awake")
            return

        self.logger.info("------------------------------------------------------------")

        for node in self.net.nodes:
            self.logger.info("%s - %s / %s" % (self.net.nodes[node].node_id,
                                               self.net.nodes[node].manufacturer_name,
                                               self.net.nodes[node].product_name) )

        self._initialized = True
Esempio n. 36
0
def setup(hass, config):
    """Setup Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    # pylint: disable=global-statement, import-error
    global NETWORK

    descriptions = conf_util.load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    try:
        import libopenzwave
    except ImportError:
        _LOGGER.error("You are missing required dependency Python Open "
                      "Z-Wave. Please follow instructions at: "
                      "https://home-assistant.io/components/zwave/")
        return False
    from pydispatch import dispatcher
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork

    default_zwave_config_path = os.path.join(os.path.dirname(
        libopenzwave.__file__), 'config')

    # Load configuration
    use_debug = config[DOMAIN].get(CONF_DEBUG)
    customize = config[DOMAIN].get(CONF_CUSTOMIZE)
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL)

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get(
            CONF_CONFIG_PATH, default_zwave_config_path))

    options.set_console_output(use_debug)
    options.lock()

    NETWORK = ZWaveNetwork(options, autostart=False)

    if use_debug:
        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Called when a value is added to a node on the network."""
        for (component,
             generic_device_class,
             specific_device_class,
             command_class,
             value_type,
             value_genre) in DISCOVERY_COMPONENTS:

            _LOGGER.debug("Component=%s Node_id=%s query start",
                          component, node.node_id)
            if node.generic not in generic_device_class and \
               None not in generic_device_class:
                _LOGGER.debug("node.generic %s not None and in "
                              "generic_device_class %s",
                              node.generic, generic_device_class)
                continue
            if node.specific not in specific_device_class and \
               None not in specific_device_class:
                _LOGGER.debug("node.specific %s is not None and in "
                              "specific_device_class %s", node.specific,
                              specific_device_class)
                continue
            if value.command_class not in command_class and \
               None not in command_class:
                _LOGGER.debug("value.command_class %s is not None "
                              "and in command_class %s",
                              value.command_class, command_class)
                continue
            if value_type != value.type and value_type is not None:
                _LOGGER.debug("value.type %s != value_type %s",
                              value.type, value_type)
                continue
            if value_genre != value.genre and value_genre is not None:
                _LOGGER.debug("value.genre %s != value_genre %s",
                              value.genre, value_genre)
                continue

            # Configure node
            _LOGGER.debug("Adding Node_id=%s Generic_command_class=%s, "
                          "Specific_command_class=%s, "
                          "Command_class=%s, Value type=%s, "
                          "Genre=%s", node.node_id,
                          node.generic, node.specific,
                          value.command_class, value.type,
                          value.genre)
            name = "{}.{}".format(component, _object_id(value))

            node_config = customize.get(name, {})
            polling_intensity = convert(
                node_config.get(CONF_POLLING_INTENSITY), int)
            if polling_intensity:
                value.enable_poll(polling_intensity)
            else:
                value.disable_poll()

            discovery.load_platform(hass, component, DOMAIN, {
                const.ATTR_NODE_ID: node.node_id,
                const.ATTR_VALUE_ID: value.value_id,
            }, config)

    def scene_activated(node, scene_id):
        """Called when a scene is activated on any node in the network."""
        hass.bus.fire(const.EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: _node_object_id(node),
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_SCENE_ID: scene_id
        })

    def node_event_activated(node, value):
        """Called when a nodeevent is activated on any node in the network."""
        hass.bus.fire(const.EVENT_NODE_EVENT, {
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_BASIC_LEVEL: value
        })

    def network_ready():
        """Called when all awake nodes have been queried."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes"
                     " have been queried. Sleeping nodes will be"
                     " queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Called when all nodes on network have been queried."""
        _LOGGER.info("Zwave network is complete. All nodes on the network"
                     " have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
    dispatcher.connect(
        node_event_activated, ZWaveNetwork.SIGNAL_NODE_EVENT, weak=False)
    dispatcher.connect(
        network_ready, ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED, weak=False)
    dispatcher.connect(
        network_complete, ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED, weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Zwave add_node have been initialized.")
        NETWORK.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Zwave add_node_secure have been initialized.")
        NETWORK.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Zwave remove_node have been initialized.")
        NETWORK.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running ZWave command.")
        NETWORK.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("ZWave heal running.")
        NETWORK.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Zwave soft_reset have been initialized.")
        NETWORK.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Zwave test_network have been initialized.")
        NETWORK.test()

    def stop_zwave(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping ZWave network.")
        NETWORK.stop()
        hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        state = hass.states.get(service.data.get(ATTR_ENTITY_ID))
        node_id = state.attributes.get(const.ATTR_NODE_ID)
        node = NETWORK.nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info(
            "Renamed ZWave node %d to %s", node_id, name)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        state = hass.states.get(service.data.get(ATTR_ENTITY_ID))
        node_id = state.attributes.get(const.ATTR_NODE_ID)
        node = NETWORK.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE, 2)
        node.set_config_param(param, value, size)
        _LOGGER.info("Setting config parameter %s on Node %s "
                     "with value %s and size=%s", param, node_id, value, size)

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting ZWave network.")
        NETWORK.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(const.NETWORK_READY_WAIT_SECS):
            _LOGGER.debug(
                "network state: %d %s", NETWORK.state, NETWORK.state_str)
            if NETWORK.state >= NETWORK.STATE_AWAKED:
                _LOGGER.info("zwave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                const.NETWORK_READY_WAIT_SECS)
            _LOGGER.info(
                "final network state: %d %s", NETWORK.state, NETWORK.state_str)

        polling_interval = convert(
            config[DOMAIN].get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            NETWORK.set_poll_interval(polling_interval, False)

        poll_interval = NETWORK.get_poll_interval()
        _LOGGER.info("zwave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
                               descriptions[const.SERVICE_ADD_NODE])
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure,
                               descriptions[const.SERVICE_ADD_NODE_SECURE])
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
                               descriptions[const.SERVICE_REMOVE_NODE])
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command,
                               descriptions[const.SERVICE_CANCEL_COMMAND])
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network,
                               descriptions[const.SERVICE_HEAL_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
                               descriptions[const.SERVICE_SOFT_RESET])
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network,
                               descriptions[const.SERVICE_TEST_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK, stop_zwave,
                               descriptions[const.SERVICE_STOP_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
                               start_zwave,
                               descriptions[const.SERVICE_START_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node,
                               descriptions[const.SERVICE_RENAME_NODE],
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
                               set_config_parameter,
                               descriptions[
                                   const.SERVICE_SET_CONFIG_PARAMETER],
                               schema=SET_CONFIG_PARAMETER_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("ZWave network autoheal is enabled.")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    return True
Esempio n. 37
0
class Open_zwave(HAInterface):
    VERSION = '0.0.1'
    awake = False
    ready = False
    nodesdisplayed = False

    def __init__(self, *args, **kwargs):
        self._serialDevicePath = kwargs.get('serialDevicePath', None)
        self._options = ZWaveOption(self._serialDevicePath, \
          config_path="/usr/share/python-openzwave/config", \
          user_path=".", cmd_line="")
        self._options.set_log_file("OZW_Log.log")
        self._options.set_append_log_file(False)
        self._options.set_console_output(True)
        #self._options.set_save_log_level(log)
        self._options.set_save_log_level('Info')
        self._options.set_logging(False)
        self._options.lock()
        self._network = ZWaveNetwork(self._options, log=None)
        super(Open_zwave, self).__init__(self, *args, **kwargs)

    def _printNetwork(self, node):
        print
        print "------------------------------------------------------"
        print "%s - Name : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].name)
        print "%s - Manufacturer name / id : %s / %s" % (
            self._network.nodes[node].node_id,
            self._network.nodes[node].manufacturer_name,
            self._network.nodes[node].manufacturer_id)
        print "%s - Product name / id / type : %s / %s / %s" % (
            self._network.nodes[node].node_id,
            self._network.nodes[node].product_name,
            self._network.nodes[node].product_id,
            self._network.nodes[node].product_type)
        print "%s - Version : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].version)
        print "%s - Command classes : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].command_classes_as_string)
        print "%s - Capabilities : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].capabilities)
        print "%s - Neighbors : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].neighbors)
        print "%s - Can sleep : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].can_wake_up())

    def _init(self, *args, **kwargs):
        super(Open_zwave, self)._init(self, *args, **kwargs)

    def _readInterface(self, lastPacketHash):
        if (self._network.state >= self._network.STATE_AWAKED
            and not self.awake):
            self.awake = True
            self._logger.info("Network Awaked")
        if (self._network.state >= self._network.STATE_READY
            and not self.ready):
            self.ready = True
            self._logger.info("Network Ready")
        if not self.awake:
            time.sleep(1.0)
            self._logger.debug("Not awaked")
            return
        if self.awake and not self.ready:
            time.sleep(1.0)
            self._logger.debug("Not ready")
            return
        if not self.nodesdisplayed and self.ready:
            for node in self._network.nodes:
                self._printNetwork(node)
            self.nodesdisplayed = True

    def version(self):
        self._logger.info("Open_zwave Pytomation Driver version " +
                          self.VERSION)
        self._logger.info("Use openzwave library : %s" %
                          self._network.controller.ozw_library_version)
        self._logger.info("Use python library : %s" %
                          self._network.controller.python_library_version)
        self._logger.info("Use ZWave library : %s" %
                          self._network.controller.library_description)
Esempio n. 38
0
def start_zwnetwork(app):
    options = ZWaveOption(device=app.config['ZWAVE_DEVICE'], config_path=app.config['ZWAVE_DIR'], user_path=app.config['USER_DIR'])
    options.set_log_file("OZW_Log.log")
    options.set_append_log_file(False)
    options.set_console_output(False)
    options.set_save_log_level(app.config['ZWAVE_DEBUG'])
    options.set_logging(app.config['ZWAVE_LOGGING'])
    options.lock()
    zwnetwork = ZWaveNetwork(options)
    return zwnetwork
Esempio n. 39
0
class TestApi(TestPyZWave):
    """
    Parent test class for api
    """

    @classmethod
    def setUpClass(self):
        super(TestApi, self).setUpClass()
        self.options = ZWaveOption(device=self.device, user_path=self.userpath)
        self.options.set_log_file("OZW_Log.log")
        self.options.set_append_log_file(False)
        self.options.set_console_output(False)
        self.options.set_save_log_level("Debug")
        self.options.set_logging(True)
        self.options.lock()
        self.ctrl_command_result = None
        dispatcher.connect(self.ctrl_message, ZWaveController.SIGNAL_CONTROLLER)
        self.node_result = None
        dispatcher.connect(self.node_update, ZWaveNetwork.SIGNAL_NODE)
        self.network = ZWaveNetwork(self.options)
        time.sleep(1.0)

    @classmethod
    def tearDownClass(self):
        self.network.stop()
        time.sleep(2.0)
        super(TestApi, self).tearDownClass()
        self.network=None

    def setUp(self):
        self.wait_for_network_state(self.network.STATE_AWAKED, 1)

    def wait_for_queue(self):
        for i in range(0,60):
            if self.network.controller.send_queue_count <= 0:
                break
            else:
                time.sleep(0.5)

    def wait_for_network_state(self, state, multiply=1):
        for i in range(0,SLEEP*multiply):
            if self.network.state>=state:
                break
            else:
                #sys.stdout.write(".")
                #sys.stdout.flush()
                time.sleep(1.0)

    def ctrl_message(self, state, message, network, controller):
        self.ctrl_command_result = state

    def node_update(self, network, node):
        self.node_result = node
Esempio n. 40
0
def setup(hass, config):
    """
    Setup Z-wave.
    Will automatically load components to support devices found on the network.
    """
    # pylint: disable=global-statement, import-error
    global NETWORK

    from pydispatch import dispatcher
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork

    # Load configuration
    use_debug = str(config[DOMAIN].get(CONF_DEBUG)) == '1'
    customize = config[DOMAIN].get(CONF_CUSTOMIZE, {})

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH, DEFAULT_CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get('config_path',
                                       DEFAULT_ZWAVE_CONFIG_PATH),)

    options.set_console_output(use_debug)
    options.lock()

    NETWORK = ZWaveNetwork(options, autostart=False)

    if use_debug:
        def log_all(signal, value=None):
            """ Log all the signals. """
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """ Called when a value is added to a node on the network. """

        for (component,
             discovery_service,
             command_ids,
             value_type,
             value_genre) in DISCOVERY_COMPONENTS:

            if value.command_class not in command_ids:
                continue
            if value_type is not None and value_type != value.type:
                continue
            if value_genre is not None and value_genre != value.genre:
                continue

            # Ensure component is loaded
            bootstrap.setup_component(hass, component, config)

            # Configure node
            name = "{}.{}".format(component, _object_id(value))

            node_config = customize.get(name, {})
            polling_intensity = convert(
                node_config.get(CONF_POLLING_INTENSITY), int)
            if polling_intensity is not None:
                value.enable_poll(polling_intensity)

            # Fire discovery event
            hass.bus.fire(EVENT_PLATFORM_DISCOVERED, {
                ATTR_SERVICE: discovery_service,
                ATTR_DISCOVERED: {
                    ATTR_NODE_ID: node.node_id,
                    ATTR_VALUE_ID: value.value_id,
                }
            })

    def scene_activated(node, scene_id):
        """ Called when a scene is activated on any node in the network. """
        name = _node_name(node)
        object_id = "{}_{}".format(slugify(name), node.node_id)

        hass.bus.fire(EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: object_id,
            ATTR_SCENE_ID: scene_id
        })

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)

    def add_node(event):
        """ Switch into inclusion mode """
        NETWORK.controller.begin_command_add_device()

    def remove_node(event):
        """ Switch into exclusion mode"""
        NETWORK.controller.begin_command_remove_device()

    def stop_zwave(event):
        """ Stop Z-wave. """
        NETWORK.stop()

    def start_zwave(event):
        """ Called when Home Assistant starts up. """
        NETWORK.start()

        polling_interval = convert(
            config[DOMAIN].get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            NETWORK.set_poll_interval(polling_interval, False)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)

        # register add / remove node services for zwave sticks without
        # hardware inclusion button
        hass.services.register(DOMAIN, SERVICE_ADD_NODE, add_node)
        hass.services.register(DOMAIN, SERVICE_REMOVE_NODE, remove_node)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    return True
Esempio n. 41
0
def setup(hass, config):
    """Setup Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    # pylint: disable=global-statement, import-error
    global NETWORK

    try:
        import libopenzwave
    except ImportError:
        _LOGGER.error("You are missing required dependency Python Open "
                      "Z-Wave. Please follow instructions at: "
                      "https://home-assistant.io/components/zwave/")
        return False
    from pydispatch import dispatcher
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork

    default_zwave_config_path = os.path.join(os.path.dirname(
        libopenzwave.__file__), 'config')

    # Load configuration
    use_debug = str(config[DOMAIN].get(CONF_DEBUG)) == '1'
    customize = config[DOMAIN].get(CONF_CUSTOMIZE, {})
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL, DEFAULT_CONF_AUTOHEAL)

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH, DEFAULT_CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get('config_path',
                                       default_zwave_config_path),)

    options.set_console_output(use_debug)
    options.lock()

    NETWORK = ZWaveNetwork(options, autostart=False)

    if use_debug:
        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Called when a value is added to a node on the network."""
        for (component,
             generic_device_class,
             specific_device_class,
             command_class,
             value_type,
             value_genre) in DISCOVERY_COMPONENTS:

            _LOGGER.debug("Component=%s Node_id=%s query start",
                          component, node.node_id)
            if node.generic not in generic_device_class and \
               None not in generic_device_class:
                _LOGGER.debug("node.generic %s not None and in \
                              generic_device_class %s",
                              node.generic, generic_device_class)
                continue
            if node.specific not in specific_device_class and \
               None not in specific_device_class:
                _LOGGER.debug("node.specific %s is not None and in \
                              specific_device_class %s", node.specific,
                              specific_device_class)
                continue
            if value.command_class not in command_class and \
               None not in command_class:
                _LOGGER.debug("value.command_class %s is not None \
                              and in command_class %s",
                              value.command_class, command_class)
                continue
            if value_type != value.type and value_type is not None:
                _LOGGER.debug("value.type %s != value_type %s",
                              value.type, value_type)
                continue
            if value_genre != value.genre and value_genre is not None:
                _LOGGER.debug("value.genre %s != value_genre %s",
                              value.genre, value_genre)
                continue

            # Configure node
            _LOGGER.debug("Adding Node_id=%s Generic_command_class=%s, \
                          Specific_command_class=%s, \
                          Command_class=%s, Value type=%s, \
                          Genre=%s", node.node_id,
                          node.generic, node.specific,
                          value.command_class, value.type,
                          value.genre)
            name = "{}.{}".format(component, _object_id(value))

            node_config = customize.get(name, {})
            polling_intensity = convert(
                node_config.get(CONF_POLLING_INTENSITY), int)
            if polling_intensity:
                value.enable_poll(polling_intensity)
            else:
                value.disable_poll()

            discovery.load_platform(hass, component, DOMAIN, {
                ATTR_NODE_ID: node.node_id,
                ATTR_VALUE_ID: value.value_id,
            }, config)

    def scene_activated(node, scene_id):
        """Called when a scene is activated on any node in the network."""
        name = _node_name(node)
        object_id = "{}_{}".format(slugify(name), node.node_id)

        hass.bus.fire(EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: object_id,
            ATTR_SCENE_ID: scene_id
        })

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        NETWORK.controller.add_node()

    def remove_node(service):
        """Switch into exclusion mode."""
        NETWORK.controller.remove_node()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("ZWave heal running.")
        NETWORK.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        NETWORK.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        NETWORK.test()

    def stop_zwave(event):
        """Stop Z-Wave."""
        NETWORK.stop()

    def start_zwave(event):
        """Startup Z-Wave."""
        NETWORK.start()

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(NETWORK_READY_WAIT_SECS):
            _LOGGER.debug(
                "network state: %d %s", NETWORK.state, NETWORK.state_str)
            if NETWORK.state >= NETWORK.STATE_AWAKED:
                _LOGGER.info("zwave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                NETWORK_READY_WAIT_SECS)
            _LOGGER.info(
                "final network state: %d %s", NETWORK.state, NETWORK.state_str)

        polling_interval = convert(
            config[DOMAIN].get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            NETWORK.set_poll_interval(polling_interval, False)

        poll_interval = NETWORK.get_poll_interval()
        _LOGGER.info("zwave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)

        # Register add / remove node services for Z-Wave sticks without
        # hardware inclusion button
        hass.services.register(DOMAIN, SERVICE_ADD_NODE, add_node)
        hass.services.register(DOMAIN, SERVICE_REMOVE_NODE, remove_node)
        hass.services.register(DOMAIN, SERVICE_HEAL_NETWORK, heal_network)
        hass.services.register(DOMAIN, SERVICE_SOFT_RESET, soft_reset)
        hass.services.register(DOMAIN, SERVICE_TEST_NETWORK, test_network)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("ZWave network autoheal is enabled.")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    return True
Esempio n. 42
0
    def _init_openzwave(self, zwave_device, zwave_config_path,
                        zwave_user_path):
        """Initialise the OpenZWave client, leaving it ready to start."""
        # Configure OpenZWave
        options = ZWaveOption(zwave_device,
                              config_path=zwave_config_path,
                              user_path=zwave_user_path,
                              cmd_line="")
        options.set_log_file(os.path.join(zwave_user_path, "zwave.log"))
        options.set_append_log_file(True)
        options.set_console_output(True)
        options.set_save_log_level("Warning")
        options.set_logging(True)
        options.lock()

        self._ozw_network = ZWaveNetwork(options, autostart=False)
Esempio n. 43
0
class ZWaveCommander:
    def __init__(self, stdscr):
        self._curAlert = False
        self._alertStack = list()
        self._driverInitialized = False
        self._options = None
        self._network = None
        self._listMode = True
        self._screen = stdscr
        self._version = '0.1 Beta 1'
        self._listtop = 0
        self._listindex = 0
        self._listcount = 0
        self._selectedNode = None
        self._stop = threading.Event()
        self._keys = {
            'A' : 'Add',
            'B' : 'About',
            'D' : 'Delete',
            'R' : 'Refresh',
            'S' : 'Setup',
            '+' : 'Increase',
            '-' : 'Decrease',
            '1' : 'On',
            '0' : 'Off',
            'Q' : 'Quit'
        }

        #self._network = ZWaveWrapper.getInstance(device=self._config['device'], config=self._config['config'], log=None)
        self._options = ZWaveOption( \
            device="/dev/zwave-aeon-s2", \
            config_path="openzwave/config", \
            user_path=".", \
            cmd_line="")
        self._options.set_log_file("OZW_Log.log")
        self._options.set_append_log_file(False)
        self._options.set_save_log_level('Debug')
        self._options.set_console_output(False)
        self._options.set_logging(True)
        self._options.lock()

        # TODO: add log level to config
        # TODO: add log enable/disable to config
        # TODO: logging - can ozw log be redirected to file?  If so, we can add ability to view/tail log
        FORMAT='%(asctime)s\t%(levelname)s\t%(name)s\t%(message)s'
        logging.basicConfig(filename='zwaveCommander.log', level=logging.DEBUG, format=FORMAT)
        self._log = logging.getLogger('ZWaveCommander')
        self._logbar ='\n%s\n' % ('-'*60)

    def main(self):
        '''Main run loop'''
        self._log.info('%sZWaveCommander Version %s Starting%s', self._logbar, self._version, self._logbar)
        self._initCurses(self._screen)
        try:
            self._startNetwork()
            self._runLoop()
        finally:
            self._shutdown()

    def _delayloop(self, context, duration, callback):
        self._log.debug('thread %s sleeping...', context)
        time.sleep(duration)
        self._log.debug('timer %s expired, executing callback %s', context, callback)
        if context == 'alert':
            self._curAlert = False
            if self._alertStack:
                self._alert(self._alertStack.pop())
        if callback is not None:
            callback()

    def _handleQuit(self):
        # TODO: exit confirmation dialog
        self._log.info('Stop requested')
        self._stop.set()

    def _handleRefresh(self):
        if self._selectedNode:
            self._network.refresh(self._selectedNode)

    def _handleOn(self):
        if self._selectedNode:
            self._network.setNodeOn(self._selectedNode)

    def _handleOff(self):
        if self._selectedNode:
            self._network.setNodeOff(self._selectedNode)

    def _handleIncrease(self):
        if self._selectedNode:
            curLevel = self._selectedNode.level
            newLevel = curLevel + 10
            if newLevel > 99: newLevel = 99
            self._network.setNodeLevel(self._selectedNode, newLevel)

    def _handleDecrease(self):
        if self._selectedNode:
            curLevel = self._selectedNode.level
            newLevel = curLevel - 10
            if newLevel < 0: newLevel = 0
            self._network.setNodeLevel(self._selectedNode, newLevel)

    def _setTimer(self, context, duration, callback):
        newTimer = threading.Thread(None, self._delayloop, 'cb-thread-%s' % context, (context, duration, callback), {})
        newTimer.setDaemon(True)
        newTimer.start()

    def _alert(self, text):
        '''perform program alert'''
        if not self._curAlert:
            self._curAlert = True
            curses.flash()
            self._screen.addstr(self._screensize[0] - 1, 0, ' {0:{width}}'.format(text, width=self._screensize[1] - 2),
                            curses.color_pair(self.COLOR_ERROR))
            self._screen.refresh()
            self._setTimer('alert', 1, self._redrawMenu)
        else:
            self._alertStack.append(text)

    def _layoutScreen(self):
        # TODO: handle screen resize on curses.KEY_RESIZE in loop (tear down, re-calculate, and re-build)
        # top 5 lines (fixed): system info (including list header)
        # bottom line (fixed): menu/status
        # remaining top half: item list (scrolling)
        # remaining bottom half: split - left half=static info, right half=detail (scrolling)
        # item list: 8 columns. All column widths here are padded with 1 char space (except col 0, which is always 1 char)
        # c0=1 char fixed (select indicator)
        # c1=4 char fixed (id)
        # c2=10 char min (name)
        # c3=10 char min (location)
        # c4=20 char min (type)
        # c5=9 char fixed (state)
        # c6=7 char fixed (batt)
        # c7=7 char fixed (signal)
        # last three columns: 23 chars: are optional and can fall off if space requires it (min width 45)
        # "min" columns expand evenly to fit remaining space

        self._screen.clear()
        self._log.debug("Laying out screen")
        self._colwidths=[1,4,10,10,15,12,8,8]
        self._colheaders=['','ID','Name','Location','Type','State','Batt','Signal']
        self._detailheaders=['Info','Values','Classes','Groups','Events']
        self._flexcols=[2,3,4]
        self._rowheights=[5,5,10,1]
        self._flexrows=[1,2]
        self._deviceValueColumns=['id','commandClass','instance','index','type','label','value','units']
        self._deviceValueWidths= [10,20,9,6,10,20,10,10]


        self._sortcolumn = self._colheaders[1]
        self._detailview = self._detailheaders[0]

        self._screensize = self._screen.getmaxyx()
        width = self._screensize[1]
        height = self._screensize[0]
        self._log.debug('Screen is %d wide by %d high', width, height)

        # Update dynamic column widths for device list
        self._log.debug('Initial column widths are: %s', self._colwidths)
        cwid = 0
        for i in self._colwidths: cwid += i
        flexwidth = width - cwid
        if flexwidth > 0:
            adder = divmod(flexwidth, len(self._flexcols))
            for i in self._flexcols:
                self._colwidths[i] += adder[0]
            self._colwidths[self._flexcols[-1]] += adder[1]
        self._log.debug('Adjusted column widths are: %s' ,self._colwidths)

        # Update dynamic row heights for screen sections
        self._log.debug('Initial row heights are: %s' , self._rowheights)
        cht = 0
        for i in self._rowheights: cht += i
        flexheight = height - cht
        if flexheight > 0:
            adder = divmod(flexheight, len(self._flexrows))
            for i in self._flexrows:
                self._rowheights[i] += adder[0]
            self._rowheights[self._flexrows[-1]] += adder[1]
        self._log.debug('Adjusted row heights are: %s' , self._rowheights)

        if curses.has_colors():
            self._log.debug('Curses initialized: %d colors and %d color pairs available', curses.COLORS, curses.COLOR_PAIRS)
        else:
            self._log.debug('Curses initialized, but no colors are available')

        self._listpad = curses.newpad(256,256)
        self._detailpads = {
            'Info': curses.newpad(self._rowheights[2], self._screensize[1]),
            'Values': curses.newpad(128, self._screensize[1]),
            'Classes': curses.newpad(128, self._screensize[1]),
            'Groups': curses.newpad(self._rowheights[2], self._screensize[1]),
            'Events': curses.newpad(256, self._screensize[1])
        }
        self._detailpos = dict()
        for k in self._detailpads.iterkeys():
            self._detailpos[k] = 0

        self._detailtop = self._rowheights[0] + self._rowheights[1] + 2
        self._detailbottom = self._detailtop + self._rowheights[2] - 3

        self._updateColumnHeaders()

    def _initCurses(self, stdscr):
        '''Configure ncurses application-specific environment (ncurses has already been initialized)'''
        curses.curs_set(0)

        # Re-define color attributes...
        self.COLOR_NORMAL=1
        self.COLOR_HEADER_NORMAL=2
        self.COLOR_HEADER_HI=3
        self.COLOR_ERROR=4
        self.COLOR_CRITICAL=5
        self.COLOR_WARN=6
        self.COLOR_OK=7

        curses.init_pair(self.COLOR_NORMAL, curses.COLOR_WHITE, curses.COLOR_BLACK) # normal (selected row is inverted, disabled/sleep is dim)
        curses.init_pair(self.COLOR_HEADER_NORMAL, curses.COLOR_BLACK, curses.COLOR_GREEN) # header normal
        curses.init_pair(self.COLOR_HEADER_HI, curses.COLOR_WHITE, curses.COLOR_CYAN) # header hi
        curses.init_pair(self.COLOR_ERROR, curses.COLOR_YELLOW, curses.COLOR_RED) # error text
        curses.init_pair(self.COLOR_CRITICAL, curses.COLOR_RED, curses.COLOR_BLACK) # critical
        curses.init_pair(self.COLOR_WARN, curses.COLOR_YELLOW, curses.COLOR_BLACK) # warn
        curses.init_pair(self.COLOR_OK, curses.COLOR_GREEN, curses.COLOR_BLACK) # ok

        self._layoutScreen()

    def _handleSetup(self):
        self._alert('handleSetup not yet implemented')

    def _checkIfInitialized(self):
        if not self._driverInitialized:
            msg = 'Unable to initialize driver - check configuration'
            self._alert(msg)
            self._log.warning(msg)
            self._handleSetup()
        else:
            self._log.info('OpenZWave initialized successfully.')

    def _notifyDriverReady(self, network, controller):
        self._log.info('OpenZWave Driver is Ready; homeid is %0.8x.  %d nodes were found.' % (network.home_id, network.nodes_count))
        self._driverInitialized = True
        self._addDialogText(2,'Driver initialized with homeid %0.8x' % network.home_id)
        self._addDialogText(3,'Node Count is now %' % network.nodes_count)

    def _notifyNodeAdded(self, network, node):
        self._addDialogText(3,'Node Count is now %s'.format(network.nodes_count))
        self._updateSystemInfo()

    def _redrawAll(self):
        self._clearDialog()
        self._updateSystemInfo()
        self._updateDeviceList()
        self._updateColumnHeaders()
        self._updateDeviceDetail()

    def _notifyNetworkReady(self, network, controller):
        self._log.info('OpenZWave Initialization Complete.')
        self._alert('OpenZWave Initialization Complete.')
        self._redrawAll()

    def _notifyNetworkFailed(self, network):
        self._log.info('OpenZWave Initialization failed.')
        self._alert('OpenZWave Initialization failed.')
        self._redrawAll()

    def _notifyNodeReady(self, network, node):
        self._readyNodeCount += 1
        self._addDialogText(2, 'OpenZWave is querying associated devices')
        self._addDialogText(3,'Node %s is now ready' % node.node_id)
        self._addDialogProgress(5, self._readyNodeCount, network.nodes_count)
        self._updateDeviceList()

    def _notifyValueChanged(self, signal, **kw):
        nodeId = kw['nodeId']
        self._log.debug('Got value changed notification for node {0}'.format(nodeId))
        # TODO: this is very heavy handed - just update appropriate elements
        self._updateDeviceList()
        self._updateDeviceDetail()

    def _initDialog(self, height, width, buttons=('OK',), caption=None):
        self._dialogpad = curses.newpad(height, width)
        self._dialogpad.bkgd(0x94, curses.color_pair(self.COLOR_HEADER_HI))
        self._dialogpad.clear()
        self._dialogpad.box()
        if caption:
           lh = (width / 2) - (len(caption) / 2) - 1
           self._dialogpad.addstr(0, lh, ' {0} '.format(caption), curses.color_pair(self.COLOR_NORMAL) | curses.A_STANDOUT)
        if buttons:
            if len(buttons) > 1:
                bwid = 0
                for bcap in buttons:
                    if len(bcap) > bwid: bwid = len(bcap)
                cellwid = (width - 4) / len(buttons)
                lpad = (cellwid - bwid) / 2 - 1
                rpad = cellwid - bwid - lpad - 1
                self._dialogpad.move(height - 2, 1)
            else:
                bwid = len(buttons[0])
                lpad = rpad = 1
                self._dialogpad.move(height - 2, (width / 2) - (bwid / 2) - 2)
            for button in buttons:
                self._dialogpad.addstr('{0:{wlpad}}<{1:^{wbwid}}>{0:{wrpad}}'.format('',button, wlpad=lpad, wbwid=bwid, wrpad=rpad))
        dt = (self._screensize[0] / 2) - (height / 2)
        dl = (self._screensize[1] / 2) - (width / 2)
        dc = padcoords(sminrow=dt,smincol=dl,smaxrow=dt+height - 1, smaxcol=dl+width - 1)
        self._dialogcoords = dc
        self._dialogpad.overlay(self._screen, 0, 0, dc.sminrow, dc.smincol, dc.smaxrow, dc.smaxcol)
        self._screen.refresh()

    def _clearDialog(self):
        del self._dialogpad
        self._dialogpad = None
        self._dialogcoords = None
        self._screen.touchwin()
        self._screen.refresh()

    def _updateDialog(self):
        if self._dialogpad:
            self._screen.refresh()
            dc = self._dialogcoords
            self._dialogpad.refresh(0,0,dc.sminrow, dc.smincol, dc.smaxrow, dc.smaxcol)

    def _addDialogText(self, row, text, align='^'):
        if self._dialogpad:
            self._dialogpad.addstr(row, 1, '{0:{aln}{wid}}'.format(text, aln=align, wid=self._dialogpad.getmaxyx()[1] - 2))
            self._updateDialog()

    def _addDialogProgress(self, row, current, total, showPercent=True, width=None):
        if self._dialogpad:
            dc = self._dialogcoords
            if width is None:
                width = (dc.smaxcol - dc.smincol) * 2 / 3
            pct = float(current) / float(total)
            filled = int(pct * float(width))
            lh = ((dc.smaxcol - dc.smincol) / 2) - (width / 2)
            self._dialogpad.addch(row, lh - 1, '[', curses.color_pair(self.COLOR_NORMAL) | curses.A_BOLD)
            self._dialogpad.addch(row, lh + width, ']', curses.color_pair(self.COLOR_NORMAL) | curses.A_BOLD)
            self._dialogpad.addstr(row, lh, ' '*width, curses.color_pair(self.COLOR_NORMAL))
            self._dialogpad.addstr(row, lh, '|'*filled, curses.color_pair(self.COLOR_OK) | curses.A_BOLD)
            if showPercent:
                pctstr = '{0:4.0%}'.format(pct)
                lh = ((dc.smaxcol - dc.smincol) / 2) - (len(pctstr) / 2)
                self._dialogpad.addstr(row, lh, pctstr, curses.color_pair(self.COLOR_NORMAL) | curses.A_BOLD)
            self._updateDialog()

    def _startNetwork(self):
        dispatcher.connect(self._notifyDriverReady, ZWaveNetwork.SIGNAL_DRIVER_READY)
        dispatcher.connect(self._notifyNetworkReady, ZWaveNetwork.SIGNAL_NETWORK_READY)
        dispatcher.connect(self._notifyNetworkFailed, ZWaveNetwork.SIGNAL_NETWORK_FAILED)
        dispatcher.connect(self._notifyNodeReady, ZWaveNetwork.SIGNAL_NODE_READY)
        dispatcher.connect(self._notifyValueChanged, ZWaveNetwork.SIGNAL_VALUE_CHANGED)
        dispatcher.connect(self._notifyNodeAdded, ZWaveNetwork.SIGNAL_NODE_ADDED)
        self._initDialog(10,60,['Cancel'],'Progress')
        self._addDialogText(2,'Initializing OpenZWave')
        self._log.info('Initializing OpenZWave')
        self._network = ZWaveNetwork(self._options, log=self._log)
        #self._network = ZWaveWrapper.getInstance(device=self._config['device'], config=self._config['config'], log=None)
        self._setTimer('initCheck', 3, self._checkIfInitialized)

        while not self._stop.isSet() and not self._driverInitialized:
            time.sleep(0.1)
            # TODO: handle keys here... cancel/etc

    def _runLoop(self):
        while not self._stop.isSet():
            key = self._screen.getch()
            if key == curses.KEY_DOWN: self._switchItem(1)
            elif key == curses.KEY_UP: self._switchItem(-1)
            elif key == curses.KEY_LEFT: self._switchTab(-1)
            elif key == curses.KEY_RIGHT: self._switchTab(1)
            elif key == 0x09: self._nextMode()
            elif key is not None: self._handleMnemonic(key)

    def _handleMnemonic(self, key):
        for mnemonic, func in self._keys.iteritems():
            if key == ord(mnemonic[0].lower()) or key == ord(mnemonic[0].upper()):
                funcname = '_handle%s' % func
                try:
                    method = getattr(self, funcname)
                    method()
                except AttributeError as ex:
                    msg = 'No method named [%s] defined!' % funcname
                    self._log.warn('handleMnemonic: %s', msg)
                    self._log.warn('handleMnemonic Exception Details: %s', str(ex))
                    self._alert(msg)
                break

    def _resetDetailPos(self):
        for p in self._detailpos.iterkeys():
            self._detailpos[p] = 0

    def _switchItem(self, delta):
        if self._listMode:
            n = self._listindex + delta
            if n in range(0, self._listcount):
                self._listindex = n
                self._updateDeviceList() # TODO: we don't really need to redraw everything when selection changes
                self._resetDetailPos()
                self._updateDeviceDetail()
        else:
            self._detailpos[self._detailview] += delta
            self._updateDeviceDetail()

    def _switchTab(self, delta):
        if self._listMode:
            i = self._colheaders.index(self._sortcolumn)
            i += delta
            if i > len(self._colheaders) - 1: i = 1
            elif i < 1: i = len(self._colheaders) - 1
            self._sortcolumn = self._colheaders[i]
        else:
            i = self._detailheaders.index(self._detailview)
            i += delta
            if i > len(self._detailheaders) - 1: i = 0
            elif i < 0: i = len(self._detailheaders) - 1
            self._detailview = self._detailheaders[i]
        self._updateColumnHeaders()
        self._updateDeviceList()
        self._updateDeviceDetail()

    def _nextMode(self):
        self._listMode = not self._listMode
        self._updateColumnHeaders()

    def _shutdown(self):
        # TODO: handle orderly shutdown
        pass

    def _rightPrint(self, row, data, attrs=None):
        if attrs is None:
            attrs = curses.color_pair(self.COLOR_NORMAL)
        self._screen.addstr(row, self._screensize[1] - len(data), data, attrs)

    def _updateSystemInfo(self):
        self._screen.addstr(0,1,'%s on %s' % \
            (self._network.controller.description, self._network.controller.device), \
            curses.color_pair(self.COLOR_NORMAL))
        self._screen.addstr(1,1,'Home ID 0x%0.8x' % \
            (self._network.self._network.home_id), \
            curses.color_pair(self.COLOR_NORMAL))
        self._screen.move(2,1)
        self._screen.addstr('%s Registered Nodes' % \
            (self._network.nodes_count), \
            curses.color_pair(self.COLOR_NORMAL))
        self._screen.addstr(' (%s Sleeping)' % \
            (self._network.sleeping_nodes_count), \
            curses.color_pair(self.COLOR_NORMAL) | curses.A_DIM)
        self._rightPrint(0, 'Library' % \
            (self._network.controller.library_description))
        self._rightPrint(1, 'Python Library Version %s' % \
            (self._network.controller.python_library_version))
        self._screen.refresh()

    def _updateColumnHeaders(self):
        self._screen.move(4,0)
        for text, wid in zip(self._colheaders, self._colwidths):
            clr = curses.color_pair(self.COLOR_HEADER_NORMAL) if self._listMode else curses.color_pair(self.COLOR_NORMAL) | curses.A_STANDOUT
            if text == self._sortcolumn:
                clr = curses.color_pair(self.COLOR_HEADER_HI) | curses.A_BOLD
            self._screen.addstr('{0:<{width}}'.format(text, width=wid), clr)

        self._screen.move(self._rowheights[0] + self._rowheights[1] + 1, 0)
        clr = curses.color_pair(self.COLOR_HEADER_NORMAL) if not self._listMode else curses.color_pair(self.COLOR_NORMAL) | curses.A_STANDOUT
        self._screen.addstr('{0:{width}}'.format('', width=self._screensize[1]), clr)
        self._screen.move(self._rowheights[0] + self._rowheights[1] + 1, 0)
        for text in self._detailheaders:
            clr = curses.color_pair(self.COLOR_HEADER_NORMAL) if not self._listMode else curses.color_pair(self.COLOR_NORMAL) | curses.A_STANDOUT
            if text == self._detailview:
                clr = curses.color_pair(self.COLOR_HEADER_HI) | curses.A_BOLD
            wid = len(text)
            self._screen.addstr(' {0:<{width}} '.format(text, width=wid), clr)

    def _fixColumn(self, text, width, align='<'):
        retval = '{0:{aln}{wid}}'.format(text, aln=align, wid=width)
        if len(retval) > width:
            retval = retval[:width]
        return retval

    def _getListItemColor(self, drawSelected):
        return curses.color_pair(self.COLOR_NORMAL) | curses.A_STANDOUT if drawSelected \
            else curses.color_pair(self.COLOR_NORMAL)

    def _drawMiniBar(self, value, minValue, maxValue, drawWidth, drawSelected, drawPercent=False, colorLevels=None):
        clr = self._getListItemColor(drawSelected)
        pct = float(value) / float(maxValue)
        dw = drawWidth - 2
        filled = int(pct * float(dw))
        fillcolor = clr
        if not drawSelected:
            fillcolor = curses.color_pair(self.COLOR_OK)
            if colorLevels:
                if pct <= colorLevels.error:
                    fillcolor = curses.color_pair(self.COLOR_CRITICAL)
                elif pct <= colorLevels.warning:
                    fillcolor = curses.color_pair(self.COLOR_WARN)

        self._listpad.addch('[', clr | curses.A_BOLD)
        self._listpad.addstr('|' * filled, fillcolor)
        self._listpad.addstr(' ' * (dw - filled), clr)
        self._listpad.addch(']', clr | curses.A_BOLD)
        # TODO: draw percent text if requested

    def _drawNodeStatus(self, node, drawSelected):
        clr = self._getListItemColor(drawSelected)
        if node.is_sleeping:
            self._listpad.addstr(self._fixColumn('(sleeping)', self._colwidths[5]), clr | curses.A_LOW)
        elif node.has_command_class(0x76): # lock
            self._listpad.addstr(self._fixColumn('Locked' if node.is_locked else 'Unlocked', self._colwidths[5]), clr)
        elif node.has_command_class(0x26): # multi-level switch
            self._drawMiniBar(node.level, 0, 99, self._colwidths[5], drawSelected)
        elif node.has_command_class(0x25): # binary switch
            self._listpad.addstr(self._fixColumn('ON' if node.is_on else 'OFF', self._colwidths[5]), clr)
        else:
            self._listpad.addstr(self._fixColumn('OK', self._colwidths[5]), clr)

    def _drawBatteryStatus(self, node, drawSelected):
        clr = self._getListItemColor(drawSelected)
        if node.has_command_class(0x80):
            self._drawMiniBar(node.batteryLevel, 0, 100, self._colwidths[6], drawSelected, colorLevels=colorlevels(error=0.10,warning=0.40))
        else:
            self._listpad.addstr(self._fixColumn('', self._colwidths[6]), clr)

    def _drawSignalStrength(self, node, drawSelected):
        clr = self._getListItemColor(drawSelected)
        self._listpad.addstr(self._fixColumn('', self._colwidths[7]), clr)

    def _drawDeviceNodeLine(self, node, drawSelected):
        clr = self._getListItemColor(drawSelected)
        self._listpad.addstr(' ', clr)
        self._listpad.addstr(self._fixColumn(node.id, self._colwidths[1]), clr)
        self._listpad.addstr(self._fixColumn(node.name, self._colwidths[2]), clr)
        self._listpad.addstr(self._fixColumn(node.location, self._colwidths[3]), clr)
        self._listpad.addstr(self._fixColumn(node.productType, self._colwidths[4]), clr)
        self._drawNodeStatus(node, drawSelected)
        self._drawBatteryStatus(node, drawSelected)
        self._drawSignalStrength(node, drawSelected)

    def _updateDeviceList(self):
        self._listcount = self._network.nodes_count
        idx = 0
        for node in self._network._nodes.itervalues():
            if idx == self._listindex:
                self._selectedNode = node
            self._listpad.move(idx,0)
            self._drawDeviceNodeLine(node, idx == self._listindex)
            idx += 1

        ctop = self._rowheights[0]
        listheight = self._rowheights[1]
        if self._listindex - self._listtop > listheight:
            self._listtop = self._listindex - listheight
        elif self._listindex < self._listtop:
            self._listtop = self._listindex
        self._screen.refresh()
        self._listpad.refresh(self._listtop, 0, ctop, 0, ctop + listheight, self._screensize[1] - 1)
        self._updateDialog()

    def _redrawDetailTab(self, pad):
        self._screen.refresh()
        pad.refresh(0, 0, self._detailtop, 0, self._detailbottom, self._screensize[1] - 1)

    def _updateDetail_Values(self, pad):
        # Draw column header
        clr = curses.color_pair(self.COLOR_HEADER_HI) | curses.A_BOLD
        pad.addstr(0,0,'{0:<{width}}'.format(' ', width=self._screensize[1]), clr)
        pad.move(0,1)
        for text, wid in zip(self._deviceValueColumns, self._deviceValueWidths):
            pad.addstr('{0:<{width}}'.format(text.title(), width=wid), clr)
        node = self._selectedNode
        if node and node.values:
            # Grab all items except for configuration values (they have their own tab)
            vset = list()
            for value in node.values.itervalues():
                if value.valueData:
                    vset.append(value)
            # Sort the resulting set: (1) command class, (2) instance, (3) index
            s = sorted(sorted(sorted(vset, key=lambda value: value.getValue('index')),
                              key=lambda value: value.getValue('instance')), key=lambda value: value.getValue('commandClass'))

            if self._detailpos[self._detailview] >= len(s): self._detailpos[self._detailview]=len(s)-1
            i = 0
            for value in s:
                vdic = value.valueData
                pad.move(i+1,0)
                # TODO: reset detail position on parent item change
                drawSelected = self._detailpos['Values'] == i
                clr = self._getListItemColor(drawSelected)
                pad.addstr(' ' * self._screensize[1], clr)
                pad.move(i+1,1)
                i += 1
                for key, wid in zip(self._deviceValueColumns, self._deviceValueWidths):
                    clr = self._getListItemColor(drawSelected)
                    text = value.getValue(key)
                    # strip 'COMMAND_CLASS_' prefix to save some space
                    if key == 'commandClass' and text.startswith('COMMAND_CLASS_'):
                        text = text[14:]

                    # TODO: value decorators (checkbox for Booleans, edit box for others)
                    # decimal: format to 2 places
                    # bool as checkbox
                    # byte as minibar if editable
                    # ints need to be directly edited...
                    # buttons... ?

                    # Draw editable items differently
                    if key == 'value' and not vdic['readOnly'] and drawSelected:
                        clr = curses.color_pair(self.COLOR_ERROR)
                    pad.addstr(self._fixColumn(text, wid), clr)

    def _updateDetail_Info(self, pad):
        node = self._selectedNode
        if node:
            #baudRate, basic, generic, specific, version, security
            self._deviceInfoColumns=['id','name','location','capabilities','neighbors','manufacturer','product','productType']
            if self._detailpos[self._detailview] >= len(self._deviceInfoColumns): self._detailpos[self._detailview]=len(self._deviceInfoColumns)-1
            editableColumns=['name','location','manufacturer','product']
            i = maxwid = 0
            for name in self._deviceInfoColumns: maxwid = len(name) if len(name) > maxwid else maxwid
            colwidth = maxwid + 2
            clr = self._getListItemColor(False)
            clr_rw = curses.color_pair(self.COLOR_ERROR)
            clr_ro = self._getListItemColor(True)
            clr_col = curses.color_pair(self.COLOR_OK)
            # TODO: If editable, should be textpad
            for column in self._deviceInfoColumns:
                val = str(getattr(node, column))
                pad.move(i + 1, 1)
                pad.addstr('{0:>{width}}'.format(column.title() + ':', width=colwidth), clr_col)
                selected = i == self._detailpos[self._detailview]
                thisclr = clr
                if selected: thisclr = clr_rw if column in editableColumns else clr_ro
                i += 1
                pad.addstr(' ')
                pad.addstr('{0:<{width}}'.format(val, width=30), thisclr)

    def _updateDetail_Classes(self, pad):
        clr = curses.color_pair(self.COLOR_HEADER_HI) | curses.A_BOLD
        pad.addstr(0,0,'{0:<{width}}'.format(' CommandClass', width=self._screensize[1]), clr)
        node = self._selectedNode
        if node:
            if self._detailpos[self._detailview] >= len(node.commandClasses): self._detailpos[self._detailview]=len(node.commandClasses)-1
            i = 0
            for cc in node.commandClasses:
                pad.addstr(i + 1, 0, ' {0:<{width}}'.format(self._network.getCommandClassName(cc), width=30),
                           self._getListItemColor(i == self._detailpos[self._detailview]))
                i += 1

    def _updateDetail_Groups(self, pad):
        pad.addstr(3,3,'Group view not yet implemented')
        # groups tab:
        # index label               maxMembers members
        # 1     my group            4          1, 2, 4
        # Members column is editable - enter comma-separated list?

    def _updateDetail_Events(self, pad):
        pad.addstr(3,3,'Event view not yet implemented')
        # event detail tab:
        # timestamp  commandClass  notificationType

    def _updateDeviceDetail(self):
        # TODO: detail needs to be scrollable, but to accomplish that a couple of changes need to be made.  First, the detail header band needs to be moved into a static shared section (above the detail pad); second, a new dict of 'top' positions needs to be created; finally, positioning code needs to be written to correctly offset the pad.
        pad = self._detailpads[self._detailview]
        pad.clear()
        if self._detailpos[self._detailview] < 0: self._detailpos[self._detailview]=0

        funcname = '_updateDetail_{0}'.format(self._detailview)
        try:
            method = getattr(self, funcname)
            method(pad)
        except AttributeError as ex:
            msg = 'No method named [%s] defined!' % funcname
            self._log.warn('_updateDeviceDetail: %s', msg)
            self._log.warn('_updateDeviceDetail Exception Details: %s', str(ex))
            self._alert(msg)

        self._redrawDetailTab(pad)

    def _updateMenu(self):
        menurow = self._screensize[0] - 1
        self._screen.addstr(menurow, 0, ' ' * (self._screensize[1] - 1), curses.color_pair(self.COLOR_HEADER_NORMAL))
        self._screen.move(menurow,4)
        for mnemonic, text in self._keys.iteritems():
            self._screen.addstr(' {0} '.format(mnemonic), curses.color_pair(self.COLOR_NORMAL) | curses.A_BOLD)
            self._screen.addstr('{0}'.format(text), curses.color_pair(self.COLOR_HEADER_NORMAL))

    def _redrawMenu(self):
        self._updateMenu()
        self._screen.refresh()
Esempio n. 44
0
def setup(hass, config):
    """Set up Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    descriptions = conf_util.load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    from pydispatch import dispatcher
    # pylint: disable=import-error
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    # Load configuration
    use_debug = config[DOMAIN].get(CONF_DEBUG)
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL)
    device_config = EntityValues(config[DOMAIN][CONF_DEVICE_CONFIG],
                                 config[DOMAIN][CONF_DEVICE_CONFIG_DOMAIN],
                                 config[DOMAIN][CONF_DEVICE_CONFIG_GLOB])
    new_entity_ids = config[DOMAIN][CONF_NEW_ENTITY_IDS]
    if not new_entity_ids:
        _LOGGER.warning(
            "ZWave entity_ids will soon be changing. To opt in to new "
            "entity_ids now, set `new_entity_ids: true` under zwave in your "
            "configuration.yaml. See the following blog post for details: "
            "https://home-assistant.io/blog/2017/06/15/zwave-entity-ids/")

    # Setup options
    options = ZWaveOption(config[DOMAIN].get(CONF_USB_STICK_PATH),
                          user_path=hass.config.config_dir,
                          config_path=config[DOMAIN].get(CONF_CONFIG_PATH))

    options.set_console_output(use_debug)

    if CONF_NETWORK_KEY in config[DOMAIN]:
        options.addOption("NetworkKey", config[DOMAIN][CONF_NETWORK_KEY])

    options.lock()

    network = hass.data[DATA_NETWORK] = ZWaveNetwork(options, autostart=False)
    hass.data[DATA_DEVICES] = {}
    hass.data[DATA_ENTITY_VALUES] = []

    if use_debug:  # pragma: no cover

        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Handle new added value to a node on the network."""
        # Check if this value should be tracked by an existing entity
        for values in hass.data[DATA_ENTITY_VALUES]:
            values.check_value(value)

        for schema in DISCOVERY_SCHEMAS:
            if not check_node_schema(node, schema):
                continue
            if not check_value_schema(
                    value, schema[const.DISC_VALUES][const.DISC_PRIMARY]):
                continue

            values = ZWaveDeviceEntityValues(hass, schema, value, config,
                                             device_config)

            # We create a new list and update the reference here so that
            # the list can be safely iterated over in the main thread
            new_values = hass.data[DATA_ENTITY_VALUES] + [values]
            hass.data[DATA_ENTITY_VALUES] = new_values

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    def node_added(node):
        """Handle a new node on the network."""
        entity = ZWaveNodeEntity(node, network, new_entity_ids)
        name = node_name(node)
        if new_entity_ids:
            generated_id = generate_entity_id(DOMAIN + '.{}', name, [])
        else:
            generated_id = entity.entity_id
        node_config = device_config.get(generated_id)
        if node_config.get(CONF_IGNORED):
            _LOGGER.info("Ignoring node entity %s due to device settings",
                         generated_id)
            return
        component.add_entities([entity])

    def network_ready():
        """Handle the query of all awake nodes."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes "
                     "have been queried. Sleeping nodes will be "
                     "queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Handle the querying of all nodes on network."""
        _LOGGER.info("Z-Wave network is complete. All nodes on the network "
                     "have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    dispatcher.connect(value_added,
                       ZWaveNetwork.SIGNAL_VALUE_ADDED,
                       weak=False)
    dispatcher.connect(node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
    dispatcher.connect(network_ready,
                       ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                       weak=False)
    dispatcher.connect(network_complete,
                       ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED,
                       weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Z-Wave add_node have been initialized")
        network.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Z-Wave add_node_secure have been initialized")
        network.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Z-Wwave remove_node have been initialized")
        network.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running Z-Wave command")
        network.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("Z-Wave heal running")
        network.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Z-Wave soft_reset have been initialized")
        network.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Z-Wave test_network have been initialized")
        network.test()

    def stop_network(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping Z-Wave network")
        network.stop()
        if hass.state == CoreState.running:
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info("Renamed Z-Wave node %d to %s", node_id, name)

    def rename_value(service):
        """Rename a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        name = service.data.get(const.ATTR_NAME)
        value.label = name
        _LOGGER.info("Renamed Z-Wave value (Node %d Value %d) to %s", node_id,
                     value_id, name)

    def set_poll_intensity(service):
        """Set the polling intensity of a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        intensity = service.data.get(const.ATTR_POLL_INTENSITY)
        if intensity == 0:
            if value.disable_poll():
                _LOGGER.info("Polling disabled (Node %d Value %d)", node_id,
                             value_id)
                return
            _LOGGER.info("Polling disabled failed (Node %d Value %d)", node_id,
                         value_id)
        else:
            if value.enable_poll(intensity):
                _LOGGER.info("Set polling intensity (Node %d Value %d) to %s",
                             node_id, value_id, intensity)
                return
            _LOGGER.info("Set polling intensity failed (Node %d Value %d)",
                         node_id, value_id)

    def remove_failed_node(service):
        """Remove failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to remove zwave node %d", node_id)
        network.controller.remove_failed_node(node_id)

    def replace_failed_node(service):
        """Replace failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to replace zwave node %d", node_id)
        network.controller.replace_failed_node(node_id)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE)
        for value in (node.get_values(
                class_id=const.COMMAND_CLASS_CONFIGURATION).values()):
            if value.index != param:
                continue
            if value.type in [const.TYPE_LIST, const.TYPE_BOOL]:
                value.data = selection
                _LOGGER.info(
                    "Setting config list parameter %s on Node %s "
                    "with selection %s", param, node_id, selection)
                return
            value.data = int(selection)
            _LOGGER.info(
                "Setting config parameter %s on Node %s "
                "with selection %s", param, node_id, selection)
            return
        node.set_config_param(param, selection, size)
        _LOGGER.info(
            "Setting unknown config parameter %s on Node %s "
            "with selection %s", param, node_id, selection)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info("Config parameter %s on Node %s: %s", param, node_id,
                     get_config_value(node, param))

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, network, node_id)
        if association_type == 'add':
            node.add_association(target_node_id, instance)
            _LOGGER.info(
                "Adding association for node:%s in group:%s "
                "target node:%s, instance=%s", node_id, group, target_node_id,
                instance)
        if association_type == 'remove':
            node.remove_association(target_node_id, instance)
            _LOGGER.info(
                "Removing association for node:%s in group:%s "
                "target node:%s, instance=%s", node_id, group, target_node_id,
                instance)

    @asyncio.coroutine
    def async_refresh_entity(service):
        """Refresh values that specific entity depends on."""
        entity_id = service.data.get(ATTR_ENTITY_ID)
        async_dispatcher_send(hass,
                              SIGNAL_REFRESH_ENTITY_FORMAT.format(entity_id))

    def refresh_node(service):
        """Refresh all node info."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        node.refresh_info()

    def reset_node_meters(service):
        """Reset meter counters of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        instance = service.data.get(const.ATTR_INSTANCE)
        node = network.nodes[node_id]
        for value in (node.get_values(
                class_id=const.COMMAND_CLASS_METER).values()):
            if value.index != const.INDEX_METER_RESET:
                continue
            if value.instance != instance:
                continue
            network.manager.pressButton(value.value_id)
            network.manager.releaseButton(value.value_id)
            _LOGGER.info("Resetting meters on node %s instance %s....",
                         node_id, instance)
            return
        _LOGGER.info(
            "Node %s on instance %s does not have resettable "
            "meters.", node_id, instance)

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting Z-Wave network...")
        network.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(const.NETWORK_READY_WAIT_SECS):
            _LOGGER.debug("network state: %d %s", network.state,
                          network.state_str)
            if network.state >= network.STATE_AWAKED:
                _LOGGER.info("Z-Wave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                const.NETWORK_READY_WAIT_SECS)
            _LOGGER.info("final network state: %d %s", network.state,
                         network.state_str)

        polling_interval = convert(config[DOMAIN].get(CONF_POLLING_INTERVAL),
                                   int)
        if polling_interval is not None:
            network.set_poll_interval(polling_interval, False)

        poll_interval = network.get_poll_interval()
        _LOGGER.info("Z-Wave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
                               descriptions[const.SERVICE_ADD_NODE])
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure,
                               descriptions[const.SERVICE_ADD_NODE_SECURE])
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
                               descriptions[const.SERVICE_REMOVE_NODE])
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command,
                               descriptions[const.SERVICE_CANCEL_COMMAND])
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network,
                               descriptions[const.SERVICE_HEAL_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
                               descriptions[const.SERVICE_SOFT_RESET])
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network,
                               descriptions[const.SERVICE_TEST_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
                               stop_network,
                               descriptions[const.SERVICE_STOP_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
                               start_zwave,
                               descriptions[const.SERVICE_START_NETWORK])
        hass.services.register(DOMAIN,
                               const.SERVICE_RENAME_NODE,
                               rename_node,
                               descriptions[const.SERVICE_RENAME_NODE],
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_RENAME_VALUE,
                               rename_value,
                               descriptions[const.SERVICE_RENAME_VALUE],
                               schema=RENAME_VALUE_SCHEMA)
        hass.services.register(
            DOMAIN,
            const.SERVICE_SET_CONFIG_PARAMETER,
            set_config_parameter,
            descriptions[const.SERVICE_SET_CONFIG_PARAMETER],
            schema=SET_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(
            DOMAIN,
            const.SERVICE_PRINT_CONFIG_PARAMETER,
            print_config_parameter,
            descriptions[const.SERVICE_PRINT_CONFIG_PARAMETER],
            schema=PRINT_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REMOVE_FAILED_NODE,
                               remove_failed_node,
                               descriptions[const.SERVICE_REMOVE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REPLACE_FAILED_NODE,
                               replace_failed_node,
                               descriptions[const.SERVICE_REPLACE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)

        hass.services.register(DOMAIN,
                               const.SERVICE_CHANGE_ASSOCIATION,
                               change_association,
                               descriptions[const.SERVICE_CHANGE_ASSOCIATION],
                               schema=CHANGE_ASSOCIATION_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               descriptions[const.SERVICE_SET_WAKEUP],
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_PRINT_NODE,
                               print_node,
                               descriptions[const.SERVICE_PRINT_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REFRESH_ENTITY,
                               async_refresh_entity,
                               descriptions[const.SERVICE_REFRESH_ENTITY],
                               schema=REFRESH_ENTITY_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_REFRESH_NODE,
                               refresh_node,
                               descriptions[const.SERVICE_REFRESH_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_RESET_NODE_METERS,
                               reset_node_meters,
                               descriptions[const.SERVICE_RESET_NODE_METERS],
                               schema=RESET_NODE_METERS_SCHEMA)
        hass.services.register(DOMAIN,
                               const.SERVICE_SET_POLL_INTENSITY,
                               set_poll_intensity,
                               descriptions[const.SERVICE_SET_POLL_INTENSITY],
                               schema=SET_POLL_INTENSITY_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("Z-Wave network autoheal is enabled")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    return True
Esempio n. 45
0
device="/dev/ttyUSB0"
log="Debug"

for arg in sys.argv:
    if arg.startswith("--device"):
        temp,device = arg.split("=")
    elif arg.startswith("--log"):
        temp,log = arg.split("=")
    elif arg.startswith("--help"):
        print("help : ")
        print("  --device=/dev/yourdevice ")
        print("  --log=Info|Debug")

#Define some manager options
options = ZWaveOption(device, \
  config_path="../openzwave/config", \
  user_path=".", cmd_line="")
options.set_log_file("OZW_Log.log")
options.set_append_log_file(False)
options.set_console_output(True)
options.set_save_log_level(log)
#options.set_save_log_level('Info')
options.set_logging(False)
options.lock()

print("Memory use : %s Mo" % (resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024.0))

#Create a network object
network = ZWaveNetwork(options, log=None)

time_started = 0
Esempio n. 46
0
def _init_controller():
    if P.module_imported:
        device = '{}{}'.format(P.device, P.device_index)
        L.l.info('Zwave initialising on {}'.format(device))
        _stop_net()
        # Define some manager options
        try:
            options = ZWaveOption(device,
                                  config_path="../openzwave/config",
                                  user_path=".",
                                  cmd_line="")
            options.set_log_file(P.log_file)
            options.set_append_log_file(True)
            options.set_console_output(False)
            # options.set_save_log_level('Debug')
            # options.set_save_log_level('Info')
            options.set_save_log_level('Warning')
            # options.set_save_log_level('Error')
            options.set_logging(False)
            #options.set_logging(True)
            # options.set_poll_interval(5)
            options.set_save_configuration(True)
            options.lock()

            # Create a network object
            P.network = ZWaveNetwork(options, log=None, autostart=False)
            dispatcher.connect(louie_network_started,
                               ZWaveNetwork.SIGNAL_NETWORK_STARTED)
            dispatcher.connect(louie_network_failed,
                               ZWaveNetwork.SIGNAL_NETWORK_FAILED)
            dispatcher.connect(louie_network_resetted,
                               ZWaveNetwork.SIGNAL_NETWORK_RESETTED)
            dispatcher.connect(louie_network_ready,
                               ZWaveNetwork.SIGNAL_NETWORK_READY)
            dispatcher.connect(louie_network_stopped,
                               ZWaveNetwork.SIGNAL_NETWORK_STOPPED)
            dispatcher.connect(louie_network_awaked,
                               ZWaveNetwork.SIGNAL_NETWORK_AWAKED)

            P.network.start()

            L.l.info("Waiting for zwave driver")
            for i in range(0, 120):
                if P.network.state >= P.network.STATE_STARTED:
                    L.l.info("Zwave driver started")
                    break
                else:
                    time.sleep(0.1)
            if P.network.state < P.network.STATE_STARTED:
                L.l.info(
                    "Can't initialise zwave driver. Look at the logs in {}".
                    format(P.log_file))
                return False
            L.l.info("Home id : {}, Nodes in network : {}".format(
                P.network.home_id_str, P.network.nodes_count))

            L.l.info("Waiting 120 sec for zwave network to become ready")
            for i in range(0, 240):
                if P.network.state >= P.network.STATE_READY:
                    break
                else:
                    time.sleep(0.5)
                    # L.l.info("state = {}".format(P.network.state))
            if not P.network.is_ready:
                L.l.info(
                    "Can't start network! Look at the logs in OZW_Log.log")
                P.network.stop()
                return False
            else:
                L.l.info("Zwave network is started!")
            # print nodes
            for node_id in P.network.nodes:
                node = P.network.nodes[node_id]
                try:
                    L.l.info("Node {}={}".format(node_id, node))
                    # L.l.info("Node {} attrib: model={} man={} prod_name={} prod_id={}".format(
                    #     node_id, node.manufacturer_name, node.product_name, node.product_id))
                except Exception as ex:
                    pass
            # not working
            # P.network.set_poll_interval(milliseconds=3000, bIntervalBetweenPolls=False)
            # P.network.test(1)
            variable.USB_PORTS_IN_USE.append(device)
            return True
        except ZWaveException as ze:
            L.l.error('Unable to init zwave, exception={}'.format(ze))
            P.device_index += 1
            if P.device_index > 3:
                P.device_index = 0
    return False
Esempio n. 47
0
async def async_setup_entry(hass, config_entry):
    """Set up Z-Wave from a config entry.

    Will automatically load components to support devices found on the network.
    """
    from pydispatch import dispatcher
    # pylint: disable=import-error
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    config = {}
    if DATA_ZWAVE_CONFIG in hass.data:
        config = hass.data[DATA_ZWAVE_CONFIG]

    # Load configuration
    use_debug = config.get(CONF_DEBUG, DEFAULT_DEBUG)
    autoheal = config.get(CONF_AUTOHEAL,
                          DEFAULT_CONF_AUTOHEAL)
    device_config = EntityValues(
        config.get(CONF_DEVICE_CONFIG),
        config.get(CONF_DEVICE_CONFIG_DOMAIN),
        config.get(CONF_DEVICE_CONFIG_GLOB))

    # Setup options
    options = ZWaveOption(
        config_entry.data[CONF_USB_STICK_PATH],
        user_path=hass.config.config_dir,
        config_path=config.get(CONF_CONFIG_PATH))

    options.set_console_output(use_debug)

    if CONF_NETWORK_KEY in config_entry.data:
        options.addOption("NetworkKey", config_entry.data[CONF_NETWORK_KEY])

    await hass.async_add_executor_job(options.lock)
    network = hass.data[DATA_NETWORK] = ZWaveNetwork(options, autostart=False)
    hass.data[DATA_DEVICES] = {}
    hass.data[DATA_ENTITY_VALUES] = []

    if use_debug:  # pragma: no cover
        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED,
                                    ZWaveNetwork
                                    .SIGNAL_ALL_NODES_QUERIED_SOME_DEAD):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Handle new added value to a node on the network."""
        # Check if this value should be tracked by an existing entity
        for values in hass.data[DATA_ENTITY_VALUES]:
            values.check_value(value)

        for schema in DISCOVERY_SCHEMAS:
            if not check_node_schema(node, schema):
                continue
            if not check_value_schema(
                    value,
                    schema[const.DISC_VALUES][const.DISC_PRIMARY]):
                continue

            values = ZWaveDeviceEntityValues(
                hass, schema, value, config, device_config, registry)

            # We create a new list and update the reference here so that
            # the list can be safely iterated over in the main thread
            new_values = hass.data[DATA_ENTITY_VALUES] + [values]
            hass.data[DATA_ENTITY_VALUES] = new_values

    component = EntityComponent(_LOGGER, DOMAIN, hass)
    registry = await async_get_registry(hass)

    def node_added(node):
        """Handle a new node on the network."""
        entity = ZWaveNodeEntity(node, network)

        def _add_node_to_component():
            if hass.data[DATA_DEVICES].get(entity.unique_id):
                return

            name = node_name(node)
            generated_id = generate_entity_id(DOMAIN + '.{}', name, [])
            node_config = device_config.get(generated_id)
            if node_config.get(CONF_IGNORED):
                _LOGGER.info(
                    "Ignoring node entity %s due to device settings",
                    generated_id)
                return

            hass.data[DATA_DEVICES][entity.unique_id] = entity
            component.add_entities([entity])

        if entity.unique_id:
            _add_node_to_component()
            return

        @callback
        def _on_ready(sec):
            _LOGGER.info("Z-Wave node %d ready after %d seconds",
                         entity.node_id, sec)
            hass.async_add_job(_add_node_to_component)

        @callback
        def _on_timeout(sec):
            _LOGGER.warning(
                "Z-Wave node %d not ready after %d seconds, "
                "continuing anyway",
                entity.node_id, sec)
            hass.async_add_job(_add_node_to_component)

        hass.add_job(check_has_unique_id, entity, _on_ready, _on_timeout,
                     hass.loop)

    def network_ready():
        """Handle the query of all awake nodes."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes "
                     "have been queried. Sleeping nodes will be "
                     "queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Handle the querying of all nodes on network."""
        _LOGGER.info("Z-Wave network is complete. All nodes on the network "
                     "have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    def network_complete_some_dead():
        """Handle the querying of all nodes on network."""
        _LOGGER.info("Z-Wave network is complete. All nodes on the network "
                     "have been queried, but some nodes are marked dead")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE_SOME_DEAD)

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
    dispatcher.connect(
        network_ready, ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED, weak=False)
    dispatcher.connect(
        network_complete, ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED, weak=False)
    dispatcher.connect(
        network_complete_some_dead,
        ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED_SOME_DEAD, weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Z-Wave add_node have been initialized")
        network.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Z-Wave add_node_secure have been initialized")
        network.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Z-Wwave remove_node have been initialized")
        network.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running Z-Wave command")
        network.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("Z-Wave heal running")
        network.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Z-Wave soft_reset have been initialized")
        network.controller.soft_reset()

    def update_config(service):
        """Update the config from git."""
        _LOGGER.info("Configuration update has been initialized")
        network.controller.update_ozw_config()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Z-Wave test_network have been initialized")
        network.test()

    def stop_network(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping Z-Wave network")
        network.stop()
        if hass.state == CoreState.running:
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info(
            "Renamed Z-Wave node %d to %s", node_id, name)

    def rename_value(service):
        """Rename a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        name = service.data.get(const.ATTR_NAME)
        value.label = name
        _LOGGER.info(
            "Renamed Z-Wave value (Node %d Value %d) to %s",
            node_id, value_id, name)

    def set_poll_intensity(service):
        """Set the polling intensity of a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        intensity = service.data.get(const.ATTR_POLL_INTENSITY)
        if intensity == 0:
            if value.disable_poll():
                _LOGGER.info("Polling disabled (Node %d Value %d)",
                             node_id, value_id)
                return
            _LOGGER.info("Polling disabled failed (Node %d Value %d)",
                         node_id, value_id)
        else:
            if value.enable_poll(intensity):
                _LOGGER.info(
                    "Set polling intensity (Node %d Value %d) to %s",
                    node_id, value_id, intensity)
                return
            _LOGGER.info("Set polling intensity failed (Node %d Value %d)",
                         node_id, value_id)

    def remove_failed_node(service):
        """Remove failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to remove zwave node %d", node_id)
        network.controller.remove_failed_node(node_id)

    def replace_failed_node(service):
        """Replace failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to replace zwave node %d", node_id)
        network.controller.replace_failed_node(node_id)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE)
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION)
                .values()):
            if value.index != param:
                continue
            if value.type in [const.TYPE_LIST, const.TYPE_BOOL]:
                value.data = str(selection)
                _LOGGER.info("Setting config parameter %s on Node %s "
                             "with list/bool selection %s", param, node_id,
                             str(selection))
                return
            if value.type == const.TYPE_BUTTON:
                network.manager.pressButton(value.value_id)
                network.manager.releaseButton(value.value_id)
                _LOGGER.info("Setting config parameter %s on Node %s "
                             "with button selection %s", param, node_id,
                             selection)
                return
            value.data = int(selection)
            _LOGGER.info("Setting config parameter %s on Node %s "
                         "with selection %s", param, node_id,
                         selection)
            return
        node.set_config_param(param, selection, size)
        _LOGGER.info("Setting unknown config parameter %s on Node %s "
                     "with selection %s", param, node_id,
                     selection)

    def refresh_node_value(service):
        """Refresh the specified value from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        node.values[value_id].refresh()
        _LOGGER.info("Node %s value %s refreshed", node_id, value_id)

    def set_node_value(service):
        """Set the specified value on a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        node = network.nodes[node_id]
        node.values[value_id].data = value
        _LOGGER.info("Node %s value %s set to %s", node_id, value_id, value)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info("Config parameter %s on Node %s: %s",
                     param, node_id, get_config_value(node, param))

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, network, node_id)
        if association_type == 'add':
            node.add_association(target_node_id, instance)
            _LOGGER.info("Adding association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)
        if association_type == 'remove':
            node.remove_association(target_node_id, instance)
            _LOGGER.info("Removing association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)

    async def async_refresh_entity(service):
        """Refresh values that specific entity depends on."""
        entity_id = service.data.get(ATTR_ENTITY_ID)
        async_dispatcher_send(
            hass, SIGNAL_REFRESH_ENTITY_FORMAT.format(entity_id))

    def refresh_node(service):
        """Refresh all node info."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        node.refresh_info()

    def reset_node_meters(service):
        """Reset meter counters of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        instance = service.data.get(const.ATTR_INSTANCE)
        node = network.nodes[node_id]
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_METER)
                .values()):
            if value.index != const.INDEX_METER_RESET:
                continue
            if value.instance != instance:
                continue
            network.manager.pressButton(value.value_id)
            network.manager.releaseButton(value.value_id)
            _LOGGER.info("Resetting meters on node %s instance %s....",
                         node_id, instance)
            return
        _LOGGER.info("Node %s on instance %s does not have resettable "
                     "meters.", node_id, instance)

    def heal_node(service):
        """Heal a node on the network."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        update_return_routes = service.data.get(const.ATTR_RETURN_ROUTES)
        node = network.nodes[node_id]
        _LOGGER.info("Z-Wave node heal running for node %s", node_id)
        node.heal(update_return_routes)

    def test_node(service):
        """Send test messages to a node on the network."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        messages = service.data.get(const.ATTR_MESSAGES)
        node = network.nodes[node_id]
        _LOGGER.info("Sending %s test-messages to node %s.", messages, node_id)
        node.test(messages)

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting Z-Wave network...")
        network.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        async def _check_awaked():
            """Wait for Z-wave awaked state (or timeout) and finalize start."""
            _LOGGER.debug(
                "network state: %d %s", network.state,
                network.state_str)

            start_time = dt_util.utcnow()
            while True:
                waited = int((dt_util.utcnow()-start_time).total_seconds())

                if network.state >= network.STATE_AWAKED:
                    # Need to be in STATE_AWAKED before talking to nodes.
                    _LOGGER.info("Z-Wave ready after %d seconds", waited)
                    break
                elif waited >= const.NETWORK_READY_WAIT_SECS:
                    # Wait up to NETWORK_READY_WAIT_SECS seconds for the Z-Wave
                    # network to be ready.
                    _LOGGER.warning(
                        "Z-Wave not ready after %d seconds, continuing anyway",
                        waited)
                    _LOGGER.info(
                        "final network state: %d %s", network.state,
                        network.state_str)
                    break
                else:
                    await asyncio.sleep(1, loop=hass.loop)

            hass.async_add_job(_finalize_start)

        hass.add_job(_check_awaked)

    def _finalize_start():
        """Perform final initializations after Z-Wave network is awaked."""
        polling_interval = convert(
            config.get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            network.set_poll_interval(polling_interval, False)

        poll_interval = network.get_poll_interval()
        _LOGGER.info("Z-Wave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node)
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure)
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node)
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command)
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network)
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset)
        hass.services.register(DOMAIN, const.SERVICE_UPDATE_CONFIG,
                               update_config)
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network)
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
                               stop_network)
        hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node,
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_RENAME_VALUE,
                               rename_value,
                               schema=RENAME_VALUE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
                               set_config_parameter,
                               schema=SET_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_NODE_VALUE,
                               set_node_value,
                               schema=SET_NODE_VALUE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_NODE_VALUE,
                               refresh_node_value,
                               schema=REFRESH_NODE_VALUE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_CONFIG_PARAMETER,
                               print_config_parameter,
                               schema=PRINT_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_FAILED_NODE,
                               remove_failed_node,
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REPLACE_FAILED_NODE,
                               replace_failed_node,
                               schema=NODE_SERVICE_SCHEMA)

        hass.services.register(DOMAIN, const.SERVICE_CHANGE_ASSOCIATION,
                               change_association,
                               schema=CHANGE_ASSOCIATION_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_NODE,
                               print_node,
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_ENTITY,
                               async_refresh_entity,
                               schema=REFRESH_ENTITY_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_NODE,
                               refresh_node,
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_RESET_NODE_METERS,
                               reset_node_meters,
                               schema=RESET_NODE_METERS_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_POLL_INTENSITY,
                               set_poll_intensity,
                               schema=SET_POLL_INTENSITY_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NODE,
                               heal_node,
                               schema=HEAL_NODE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_TEST_NODE,
                               test_node,
                               schema=TEST_NODE_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("Z-Wave network autoheal is enabled")
        async_track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    hass.services.async_register(DOMAIN, const.SERVICE_START_NETWORK,
                                 start_zwave)

    for entry_component in SUPPORTED_PLATFORMS:
        hass.async_create_task(hass.config_entries.async_forward_entry_setup(
            config_entry, entry_component))

    return True
Esempio n. 48
0
class Open_zwave(HAInterface):
    VERSION = '0.0.2'
    awake = False
    ready = False
    nodesdisplayed = False

    def louie_network_ready(network):
	self._logger.info(">>>>>>> Hello from network : I'm ready : %d nodes were found." % self._network.nodes_count)     
	self._logger.info(">>>>>>> Hello from network : my controller is : %s" % self._network.controller)
	dispatcher.connect(self.louie_node_update, ZWaveNetwork.SIGNAL_NODE)
	dispatcher.connect(self.louie_value_update, ZWaveNetwork.SIGNAL_VALUE)

    def louie_node_update(network, node):
    	self._logger.info('>>>>>>> Hello from node : %s.' % node)

    def louie_value_update(network, node, value):
    	self._logger.info('>>>>>>> Hello from value : %s.' % value)

    def __init__(self, *args, **kwargs):
        self._serialDevicePath = kwargs.get('serialDevicePath', None)
        self._options = ZWaveOption(self._serialDevicePath, \
          config_path="/usr/local/etc/openzwave/", \
          user_path=".", cmd_line="")
        self._options.set_log_file("OZW_Log.log")
        self._options.set_append_log_file(False)
        self._options.set_console_output(False)
        #self._options.set_save_log_level(log)
        self._options.set_save_log_level('Info')
        self._options.set_logging(True)
	self._options.set_notify_transactions(True)
        self._options.lock()

        self._network = ZWaveNetwork(self._options, log=None,autostart=False)
	dispatcher.connect(self.louie_network_ready, ZWaveNetwork.SIGNAL_NETWORK_READY)
	self._network.start()
        super(Open_zwave, self).__init__(self, *args, **kwargs)

    def _printNetwork(self, node):
        print
        print "------------------------------------------------------"
        print "%s - Name : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].name)
        print "%s - Manufacturer name / id : %s / %s" % (
            self._network.nodes[node].node_id,
            self._network.nodes[node].manufacturer_name,
            self._network.nodes[node].manufacturer_id)
        print "%s - Product name / id / type : %s / %s / %s" % (
            self._network.nodes[node].node_id,
            self._network.nodes[node].product_name,
            self._network.nodes[node].product_id,
            self._network.nodes[node].product_type)
        print "%s - Version : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].version)
        print "%s - Command classes : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].command_classes_as_string)
        print "%s - Capabilities : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].capabilities)
        print "%s - Neighbors : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].neighbors)
        print "%s - Can sleep : %s" % (self._network.nodes[node].node_id,
            self._network.nodes[node].can_wake_up())

    def _init(self, *args, **kwargs):
        super(Open_zwave, self)._init(self, *args, **kwargs)

    def _readInterface(self, lastPacketHash):
        if (self._network.state >= self._network.STATE_AWAKED
            and not self.awake):
            self.awake = True
            self._logger.info("Network Awaked")
        if (self._network.state >= self._network.STATE_READY
            and not self.ready):
            self.ready = True
            self._logger.info("Network Ready")
	    self._logger.info("********************************* NETWORK READY ************************************")
        if not self.awake:
            time.sleep(1.0)
            self._logger.debug("Not awaked")
            return
        if self.awake and not self.ready:
            time.sleep(1.0)
            self._logger.debug("Not ready")
            return
        if not self.nodesdisplayed and self.ready:
            for node in self._network.nodes:
                self._printNetwork(node)
            self.nodesdisplayed = True
        time.sleep(1)

    def version(self):
        self._logger.info("Open_zwave Pytomation Driver version " +
                          self.VERSION)
        self._logger.info("Use openzwave library : %s" %
                          self._network.controller.ozw_library_version)
        self._logger.info("Use python library : %s" %
                          self._network.controller.python_library_version)
        self._logger.info("Use ZWave library : %s" %
                          self._network.controller.library_description)

    def on(self, address):
	node = int(address)
	for val in self._network.nodes[node].get_switches() :
		self._logger.info("Activate switch")
		self._network.nodes[node].set_switch(val,True)

	for val in self._network.nodes[node].get_dimmers() :
		self._logger.info("Activate dimmer : %s" % self._network.nodes[node])
		self._network.nodes[node].set_dimmer(val,99)


    def off(self, address):
	node = int(address)
	for val in self._network.nodes[node].get_switches() :
		self._logger.info("Activate switch")
		self._network.nodes[node].set_switch(val,False)

	for val in self._network.nodes[node].get_dimmers() :
		self._logger.info("Activate dimmer : %s" % self._network.nodes[node])
		self._network.nodes[node].set_dimmer(val,0)

    def status(self, address):
	node = int(address)
	for val in self._network.nodes[node].get_dimmers() :
	   level = self._network.nodes[nodeid].get_dimmer_level(val)
Esempio n. 49
0
    from openzwave.value import ZWaveValue
    from openzwave.scene import ZWaveScene
    from openzwave.controller import ZWaveController
    from openzwave.network import ZWaveNetwork
    from openzwave.option import ZWaveOption
import time

device="/dev/zwave-aeon-s2"

for arg in sys.argv:
    if arg.startswith("--device"):
        temp,device = arg.split("=")

#Define some manager options
options = ZWaveOption(device, \
  config_path="../openzwave/config", \
  user_path=".", cmd_line="")
options.set_log_file("OZW_Log.log")
options.set_append_log_file(False)
options.set_console_output(False)
options.set_save_log_level('Debug')
#options.set_save_log_level('Info')
options.set_logging(True)
options.lock()

#Create a network object
network = ZWaveNetwork(options, log=None)

print "------------------------------------------------------------"
print "Waiting for driver : "
print "------------------------------------------------------------"
Esempio n. 50
0
def setup(hass, config):
    """Setup Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    # pylint: disable=global-statement, import-error
    global NETWORK

    descriptions = conf_util.load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    try:
        import libopenzwave
    except ImportError:
        _LOGGER.error("You are missing required dependency Python Open "
                      "Z-Wave. Please follow instructions at: "
                      "https://home-assistant.io/components/zwave/")
        return False
    from pydispatch import dispatcher
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    default_zwave_config_path = os.path.join(os.path.dirname(
        libopenzwave.__file__), 'config')

    # Load configuration
    use_debug = config[DOMAIN].get(CONF_DEBUG)
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL)
    hass.data[DATA_DEVICE_CONFIG] = EntityValues(
        config[DOMAIN][CONF_DEVICE_CONFIG],
        config[DOMAIN][CONF_DEVICE_CONFIG_DOMAIN],
        config[DOMAIN][CONF_DEVICE_CONFIG_GLOB])

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get(
            CONF_CONFIG_PATH, default_zwave_config_path))

    options.set_console_output(use_debug)
    options.lock()

    NETWORK = ZWaveNetwork(options, autostart=False)

    if use_debug:
        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Called when a value is added to a node on the network."""
        for (component,
             generic_device_class,
             specific_device_class,
             command_class,
             value_type,
             value_genre) in DISCOVERY_COMPONENTS:

            _LOGGER.debug("Component=%s Node_id=%s query start",
                          component, node.node_id)
            if node.generic not in generic_device_class and \
               None not in generic_device_class:
                _LOGGER.debug("node.generic %s not None and in "
                              "generic_device_class %s",
                              node.generic, generic_device_class)
                continue
            if node.specific not in specific_device_class and \
               None not in specific_device_class:
                _LOGGER.debug("node.specific %s is not None and in "
                              "specific_device_class %s", node.specific,
                              specific_device_class)
                continue
            if value.command_class not in command_class and \
               None not in command_class:
                _LOGGER.debug("value.command_class %s is not None "
                              "and in command_class %s",
                              value.command_class, command_class)
                continue
            if value_type != value.type and value_type is not None:
                _LOGGER.debug("value.type %s != value_type %s",
                              value.type, value_type)
                continue
            if value_genre != value.genre and value_genre is not None:
                _LOGGER.debug("value.genre %s != value_genre %s",
                              value.genre, value_genre)
                continue

            # Configure node
            _LOGGER.debug("Adding Node_id=%s Generic_command_class=%s, "
                          "Specific_command_class=%s, "
                          "Command_class=%s, Value type=%s, "
                          "Genre=%s as %s", node.node_id,
                          node.generic, node.specific,
                          value.command_class, value.type,
                          value.genre, component)
            workaround_component = workaround.get_device_component_mapping(
                value)
            if workaround_component and workaround_component != component:
                if workaround_component == workaround.WORKAROUND_IGNORE:
                    _LOGGER.info("Ignoring device %s due to workaround.",
                                 "{}.{}".format(component, object_id(value)))
                    continue
                _LOGGER.debug("Using %s instead of %s",
                              workaround_component, component)
                component = workaround_component

            name = "{}.{}".format(component, object_id(value))
            node_config = hass.data[DATA_DEVICE_CONFIG].get(name)

            if node_config.get(CONF_IGNORED):
                _LOGGER.info(
                    "Ignoring device %s due to device settings.", name)
                return

            polling_intensity = convert(
                node_config.get(CONF_POLLING_INTENSITY), int)
            if polling_intensity:
                value.enable_poll(polling_intensity)
            else:
                value.disable_poll()

            discovery.load_platform(hass, component, DOMAIN, {
                const.ATTR_NODE_ID: node.node_id,
                const.ATTR_VALUE_ID: value.value_id,
            }, config)

    def scene_activated(node, scene_id):
        """Called when a scene is activated on any node in the network."""
        hass.bus.fire(const.EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: _node_object_id(node),
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_SCENE_ID: scene_id
        })

    def node_event_activated(node, value):
        """Called when a nodeevent is activated on any node in the network."""
        hass.bus.fire(const.EVENT_NODE_EVENT, {
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_BASIC_LEVEL: value
        })

    def network_ready():
        """Called when all awake nodes have been queried."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes"
                     " have been queried. Sleeping nodes will be"
                     " queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Called when all nodes on network have been queried."""
        _LOGGER.info("Zwave network is complete. All nodes on the network"
                     " have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
    dispatcher.connect(
        node_event_activated, ZWaveNetwork.SIGNAL_NODE_EVENT, weak=False)
    dispatcher.connect(
        network_ready, ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED, weak=False)
    dispatcher.connect(
        network_complete, ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED, weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Zwave add_node have been initialized.")
        NETWORK.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Zwave add_node_secure have been initialized.")
        NETWORK.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Zwave remove_node have been initialized.")
        NETWORK.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running ZWave command.")
        NETWORK.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("ZWave heal running.")
        NETWORK.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Zwave soft_reset have been initialized.")
        NETWORK.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Zwave test_network have been initialized.")
        NETWORK.test()

    def stop_zwave(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping ZWave network.")
        NETWORK.stop()
        if hass.state == 'RUNNING':
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        state = hass.states.get(service.data.get(ATTR_ENTITY_ID))
        node_id = state.attributes.get(const.ATTR_NODE_ID)
        node = NETWORK.nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info(
            "Renamed ZWave node %d to %s", node_id, name)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = NETWORK.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE, 2)
        i = 0
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION)
                .values()):
            if value.index == param and value.type == const.TYPE_LIST:
                _LOGGER.debug('Values for parameter %s: %s', param,
                              value.data_items)
                i = len(value.data_items) - 1
        if i == 0:
            node.set_config_param(param, selection, size)
        else:
            if selection > i:
                _LOGGER.info('Config parameter selection does not exist!'
                             ' Please check zwcfg_[home_id].xml in'
                             ' your homeassistant config directory. '
                             ' Available selections are 0 to %s', i)
                return
            node.set_config_param(param, selection, size)
            _LOGGER.info('Setting config parameter %s on Node %s '
                         'with selection %s and size=%s', param, node_id,
                         selection, size)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = NETWORK.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info("Config parameter %s on Node %s : %s",
                     param, node_id, get_config_value(node, param))

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = NETWORK.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = NETWORK.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, NETWORK, node_id)
        if association_type == 'add':
            node.add_association(target_node_id, instance)
            _LOGGER.info("Adding association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)
        if association_type == 'remove':
            node.remove_association(target_node_id, instance)
            _LOGGER.info("Removing association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting ZWave network.")
        NETWORK.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(const.NETWORK_READY_WAIT_SECS):
            _LOGGER.debug(
                "network state: %d %s", NETWORK.state, NETWORK.state_str)
            if NETWORK.state >= NETWORK.STATE_AWAKED:
                _LOGGER.info("zwave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                const.NETWORK_READY_WAIT_SECS)
            _LOGGER.info(
                "final network state: %d %s", NETWORK.state, NETWORK.state_str)

        polling_interval = convert(
            config[DOMAIN].get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            NETWORK.set_poll_interval(polling_interval, False)

        poll_interval = NETWORK.get_poll_interval()
        _LOGGER.info("zwave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zwave)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
                               descriptions[const.SERVICE_ADD_NODE])
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure,
                               descriptions[const.SERVICE_ADD_NODE_SECURE])
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
                               descriptions[const.SERVICE_REMOVE_NODE])
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command,
                               descriptions[const.SERVICE_CANCEL_COMMAND])
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network,
                               descriptions[const.SERVICE_HEAL_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
                               descriptions[const.SERVICE_SOFT_RESET])
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network,
                               descriptions[const.SERVICE_TEST_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK, stop_zwave,
                               descriptions[const.SERVICE_STOP_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
                               start_zwave,
                               descriptions[const.SERVICE_START_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node,
                               descriptions[const.SERVICE_RENAME_NODE],
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
                               set_config_parameter,
                               descriptions[
                                   const.SERVICE_SET_CONFIG_PARAMETER],
                               schema=SET_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_CONFIG_PARAMETER,
                               print_config_parameter,
                               descriptions[
                                   const.SERVICE_PRINT_CONFIG_PARAMETER],
                               schema=PRINT_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_CHANGE_ASSOCIATION,
                               change_association,
                               descriptions[
                                   const.SERVICE_CHANGE_ASSOCIATION],
                               schema=CHANGE_ASSOCIATION_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               descriptions[
                                   const.SERVICE_SET_WAKEUP],
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_NODE,
                               print_node,
                               descriptions[
                                   const.SERVICE_PRINT_NODE],
                               schema=PRINT_NODE_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("ZWave network autoheal is enabled.")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    return True
Esempio n. 51
0
import time
import six

if six.PY3:
    from pydispatch import dispatcher
else:
    from louie import dispatcher

# Program options
device = "/dev/ttyACM0"
log = "None"
sniff = 300.0

# manager options
options = ZWaveOption(device, \
    user_path="/home/pi/Embedded_OS/final/zwave_cfg/", cmd_line="")
options.set_log_file("OZW_Log.log")
options.set_append_log_file(False)
options.set_console_output(False)
options.set_save_log_level(log)
options.set_logging(True)
options.lock()


# fill below with more useful things later
def louie_network_started(network):
    print(
        "Hello from network : I'm started : homeid {:08x} - {} nodes were found."
        .format(network.home_id, network.nodes_count))

Esempio n. 52
0
class TestApi(TestPyZWave):
    """
    Parent test class for api
    """
    @classmethod
    def setUpClass(self):
        super(TestApi, self).setUpClass()
        self.options = ZWaveOption(device=self.device, user_path=self.userpath)
        self.options.set_log_file("OZW_Log.log")
        self.options.set_append_log_file(False)
        self.options.set_console_output(self.ozwout)
        self.options.set_save_log_level(self.ozwlog)
        self.options.set_logging(True)
        self.options.lock()
        dispatcher.connect(self.node_update, ZWaveNetwork.SIGNAL_NODE)
        self.network = ZWaveNetwork(self.options)
        self.node_result = None
        self.ctrl_command_result = None
        self.ctrl_command_signal = None
        #dispatcher.connect(self.ctrl_message, ZWaveNetwork.SIGNAL_CONTROLLER_COMMAND)
        time.sleep(1.0)

    @classmethod
    def tearDownClass(self):
        self.network.stop()
        time.sleep(2.0)
        self.network.destroy()
        time.sleep(1.0)
        super(TestApi, self).tearDownClass()
        self.network = None

    def setUp(self):
        self.node_result = None
        self.ctrl_command_result = None
        self.ctrl_command_signal = None
        self.wait_for_network_state(self.network.STATE_AWAKED, 1)
        time.sleep(1.0)
        self.wait_for_queue()
        self.active_nodes = {}
        for node in self.network.nodes:
            if self.network.nodes[node].is_info_received:
                self.active_nodes[node] = self.network.nodes[node]
        print('active nodes : %s' % self.active_nodes)

    def wait_for_queue(self):
        for i in range(0, 60):
            if self.network.controller.send_queue_count <= 0:
                break
            else:
                time.sleep(0.5)

    def wait_for_network_state(self, state, multiply=1):
        for i in range(0, SLEEP * multiply):
            if self.network.state >= state:
                break
            else:
                time.sleep(1.0)

    def ctrl_message(
        self,
        network,
        controller,
        node,
        node_id,
        state_int,
        state,
        state_full,
        error_int,
        error,
        error_full,
    ):
        self.ctrl_state_result = state
        self.ctrl_command_signal = {
            'network': network,
            'controller': controller,
            'node': node,
            'node_id': node_id,
            'state_int': state_int,
            'state': state,
            'state_full': state_full,
            'error_int': error_int,
            'error': error,
            'error_full': error_full,
        }

    def ctrl_waiting(self, network, controller, state_int, state, state_full):
        self.ctrl_state_result = state

    def node_update(self, network, node):
        self.node_result = node
Esempio n. 53
0
def start_zwnetwork(app):
    options = ZWaveOption(device=app.config['ZWAVE_DEVICE'],
                          config_path=app.config['ZWAVE_DIR'],
                          user_path=app.config['USER_DIR'])
    options.set_log_file("OZW_Log.log")
    options.set_append_log_file(False)
    options.set_console_output(False)
    options.set_save_log_level(app.config['ZWAVE_DEBUG'])
    options.set_logging(app.config['ZWAVE_LOGGING'])
    options.lock()
    zwnetwork = ZWaveNetwork(options)
    return zwnetwork
Esempio n. 54
0
def setup(hass, config):
    """Set up Z-Wave.

    Will automatically load components to support devices found on the network.
    """
    descriptions = conf_util.load_yaml_config_file(
        os.path.join(os.path.dirname(__file__), 'services.yaml'))

    from pydispatch import dispatcher
    # pylint: disable=import-error
    from openzwave.option import ZWaveOption
    from openzwave.network import ZWaveNetwork
    from openzwave.group import ZWaveGroup

    # Load configuration
    use_debug = config[DOMAIN].get(CONF_DEBUG)
    autoheal = config[DOMAIN].get(CONF_AUTOHEAL)
    device_config = EntityValues(
        config[DOMAIN][CONF_DEVICE_CONFIG],
        config[DOMAIN][CONF_DEVICE_CONFIG_DOMAIN],
        config[DOMAIN][CONF_DEVICE_CONFIG_GLOB])

    # Setup options
    options = ZWaveOption(
        config[DOMAIN].get(CONF_USB_STICK_PATH),
        user_path=hass.config.config_dir,
        config_path=config[DOMAIN].get(CONF_CONFIG_PATH))

    options.set_console_output(use_debug)

    if CONF_NETWORK_KEY in config[DOMAIN]:
        options.addOption("NetworkKey", config[DOMAIN][CONF_NETWORK_KEY])

    options.lock()

    network = hass.data[DATA_NETWORK] = ZWaveNetwork(options, autostart=False)
    hass.data[DATA_DEVICES] = {}
    hass.data[DATA_ENTITY_VALUES] = []

    if use_debug:  # pragma: no cover
        def log_all(signal, value=None):
            """Log all the signals."""
            print("")
            print("SIGNAL *****", signal)
            if value and signal in (ZWaveNetwork.SIGNAL_VALUE_CHANGED,
                                    ZWaveNetwork.SIGNAL_VALUE_ADDED,
                                    ZWaveNetwork.SIGNAL_SCENE_EVENT,
                                    ZWaveNetwork.SIGNAL_NODE_EVENT,
                                    ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED,
                                    ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED):
                pprint(_obj_to_dict(value))

            print("")

        dispatcher.connect(log_all, weak=False)

    def value_added(node, value):
        """Handle new added value to a node on the network."""
        # Check if this value should be tracked by an existing entity
        for values in hass.data[DATA_ENTITY_VALUES]:
            values.check_value(value)

        for schema in DISCOVERY_SCHEMAS:
            if not check_node_schema(node, schema):
                continue
            if not check_value_schema(
                    value,
                    schema[const.DISC_VALUES][const.DISC_PRIMARY]):
                continue

            values = ZWaveDeviceEntityValues(
                hass, schema, value, config, device_config)

            # We create a new list and update the reference here so that
            # the list can be safely iterated over in the main thread
            new_values = hass.data[DATA_ENTITY_VALUES] + [values]
            hass.data[DATA_ENTITY_VALUES] = new_values

    component = EntityComponent(_LOGGER, DOMAIN, hass)

    def node_added(node):
        """Handle a new node on the network."""
        entity = ZWaveNodeEntity(node, network)
        node_config = device_config.get(entity.entity_id)
        if node_config.get(CONF_IGNORED):
            _LOGGER.info(
                "Ignoring node entity %s due to device settings",
                entity.entity_id)
            return
        component.add_entities([entity])

    def scene_activated(node, scene_id):
        """Handle an activated scene on any node in the network."""
        hass.bus.fire(const.EVENT_SCENE_ACTIVATED, {
            ATTR_ENTITY_ID: _node_object_id(node),
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_SCENE_ID: scene_id
        })

    def node_event_activated(node, value):
        """Handle a nodeevent on any node in the network."""
        hass.bus.fire(const.EVENT_NODE_EVENT, {
            const.ATTR_OBJECT_ID: _node_object_id(node),
            const.ATTR_BASIC_LEVEL: value
        })

    def network_ready():
        """Handle the query of all awake nodes."""
        _LOGGER.info("Zwave network is ready for use. All awake nodes "
                     "have been queried. Sleeping nodes will be "
                     "queried when they awake.")
        hass.bus.fire(const.EVENT_NETWORK_READY)

    def network_complete():
        """Handle the querying of all nodes on network."""
        _LOGGER.info("Z-Wave network is complete. All nodes on the network "
                     "have been queried")
        hass.bus.fire(const.EVENT_NETWORK_COMPLETE)

    dispatcher.connect(
        value_added, ZWaveNetwork.SIGNAL_VALUE_ADDED, weak=False)
    dispatcher.connect(
        node_added, ZWaveNetwork.SIGNAL_NODE_ADDED, weak=False)
    dispatcher.connect(
        scene_activated, ZWaveNetwork.SIGNAL_SCENE_EVENT, weak=False)
    dispatcher.connect(
        node_event_activated, ZWaveNetwork.SIGNAL_NODE_EVENT, weak=False)
    dispatcher.connect(
        network_ready, ZWaveNetwork.SIGNAL_AWAKE_NODES_QUERIED, weak=False)
    dispatcher.connect(
        network_complete, ZWaveNetwork.SIGNAL_ALL_NODES_QUERIED, weak=False)

    def add_node(service):
        """Switch into inclusion mode."""
        _LOGGER.info("Z-Wave add_node have been initialized")
        network.controller.add_node()

    def add_node_secure(service):
        """Switch into secure inclusion mode."""
        _LOGGER.info("Z-Wave add_node_secure have been initialized")
        network.controller.add_node(True)

    def remove_node(service):
        """Switch into exclusion mode."""
        _LOGGER.info("Z-Wwave remove_node have been initialized")
        network.controller.remove_node()

    def cancel_command(service):
        """Cancel a running controller command."""
        _LOGGER.info("Cancel running Z-Wave command")
        network.controller.cancel_command()

    def heal_network(service):
        """Heal the network."""
        _LOGGER.info("Z-Wave heal running")
        network.heal()

    def soft_reset(service):
        """Soft reset the controller."""
        _LOGGER.info("Z-Wave soft_reset have been initialized")
        network.controller.soft_reset()

    def test_network(service):
        """Test the network by sending commands to all the nodes."""
        _LOGGER.info("Z-Wave test_network have been initialized")
        network.test()

    def stop_network(_service_or_event):
        """Stop Z-Wave network."""
        _LOGGER.info("Stopping Z-Wave network")
        network.stop()
        if hass.state == CoreState.running:
            hass.bus.fire(const.EVENT_NETWORK_STOP)

    def rename_node(service):
        """Rename a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        name = service.data.get(const.ATTR_NAME)
        node.name = name
        _LOGGER.info(
            "Renamed Z-Wave node %d to %s", node_id, name)

    def rename_value(service):
        """Rename a node value."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        value_id = service.data.get(const.ATTR_VALUE_ID)
        node = network.nodes[node_id]
        value = node.values[value_id]
        name = service.data.get(const.ATTR_NAME)
        value.label = name
        _LOGGER.info(
            "Renamed Z-Wave value (Node %d Value %d) to %s",
            node_id, value_id, name)

    def remove_failed_node(service):
        """Remove failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to remove zwave node %d", node_id)
        network.controller.remove_failed_node(node_id)

    def replace_failed_node(service):
        """Replace failed node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        _LOGGER.info("Trying to replace zwave node %d", node_id)
        network.controller.replace_failed_node(node_id)

    def set_config_parameter(service):
        """Set a config parameter to a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        selection = service.data.get(const.ATTR_CONFIG_VALUE)
        size = service.data.get(const.ATTR_CONFIG_SIZE)
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_CONFIGURATION)
                .values()):
            if value.index != param:
                continue
            if value.type in [const.TYPE_LIST, const.TYPE_BOOL]:
                value.data = selection
                _LOGGER.info("Setting config list parameter %s on Node %s "
                             "with selection %s", param, node_id,
                             selection)
                return
            else:
                value.data = int(selection)
                _LOGGER.info("Setting config parameter %s on Node %s "
                             "with selection %s", param, node_id,
                             selection)
                return
        node.set_config_param(param, selection, size)
        _LOGGER.info("Setting unknown config parameter %s on Node %s "
                     "with selection %s", param, node_id,
                     selection)

    def print_config_parameter(service):
        """Print a config parameter from a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        param = service.data.get(const.ATTR_CONFIG_PARAMETER)
        _LOGGER.info("Config parameter %s on Node %s: %s",
                     param, node_id, get_config_value(node, param))

    def print_node(service):
        """Print all information about z-wave node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        nice_print_node(node)

    def set_wakeup(service):
        """Set wake-up interval of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        value = service.data.get(const.ATTR_CONFIG_VALUE)
        if node.can_wake_up():
            for value_id in node.get_values(
                    class_id=const.COMMAND_CLASS_WAKE_UP):
                node.values[value_id].data = value
                _LOGGER.info("Node %s wake-up set to %d", node_id, value)
        else:
            _LOGGER.info("Node %s is not wakeable", node_id)

    def change_association(service):
        """Change an association in the zwave network."""
        association_type = service.data.get(const.ATTR_ASSOCIATION)
        node_id = service.data.get(const.ATTR_NODE_ID)
        target_node_id = service.data.get(const.ATTR_TARGET_NODE_ID)
        group = service.data.get(const.ATTR_GROUP)
        instance = service.data.get(const.ATTR_INSTANCE)

        node = ZWaveGroup(group, network, node_id)
        if association_type == 'add':
            node.add_association(target_node_id, instance)
            _LOGGER.info("Adding association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)
        if association_type == 'remove':
            node.remove_association(target_node_id, instance)
            _LOGGER.info("Removing association for node:%s in group:%s "
                         "target node:%s, instance=%s", node_id, group,
                         target_node_id, instance)

    @asyncio.coroutine
    def async_refresh_entity(service):
        """Refresh values that specific entity depends on."""
        entity_id = service.data.get(ATTR_ENTITY_ID)
        async_dispatcher_send(
            hass, SIGNAL_REFRESH_ENTITY_FORMAT.format(entity_id))

    def refresh_node(service):
        """Refresh all node info."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        node = network.nodes[node_id]
        node.refresh_info()

    def reset_node_meters(service):
        """Reset meter counters of a node."""
        node_id = service.data.get(const.ATTR_NODE_ID)
        instance = service.data.get(const.ATTR_INSTANCE)
        node = network.nodes[node_id]
        for value in (
                node.get_values(class_id=const.COMMAND_CLASS_METER)
                .values()):
            if value.index != const.METER_RESET_INDEX:
                continue
            if value.instance != instance:
                continue
            network.manager.pressButton(value.value_id)
            network.manager.releaseButton(value.value_id)
            _LOGGER.info("Resetting meters on node %s instance %s....",
                         node_id, instance)
            return
        _LOGGER.info("Node %s on instance %s does not have resettable "
                     "meters.", node_id, instance)

    def start_zwave(_service_or_event):
        """Startup Z-Wave network."""
        _LOGGER.info("Starting Z-Wave network...")
        network.start()
        hass.bus.fire(const.EVENT_NETWORK_START)

        # Need to be in STATE_AWAKED before talking to nodes.
        # Wait up to NETWORK_READY_WAIT_SECS seconds for the zwave network
        # to be ready.
        for i in range(const.NETWORK_READY_WAIT_SECS):
            _LOGGER.debug(
                "network state: %d %s", network.state,
                network.state_str)
            if network.state >= network.STATE_AWAKED:
                _LOGGER.info("Z-Wave ready after %d seconds", i)
                break
            time.sleep(1)
        else:
            _LOGGER.warning(
                "zwave not ready after %d seconds, continuing anyway",
                const.NETWORK_READY_WAIT_SECS)
            _LOGGER.info(
                "final network state: %d %s", network.state,
                network.state_str)

        polling_interval = convert(
            config[DOMAIN].get(CONF_POLLING_INTERVAL), int)
        if polling_interval is not None:
            network.set_poll_interval(polling_interval, False)

        poll_interval = network.get_poll_interval()
        _LOGGER.info("Z-Wave polling interval set to %d ms", poll_interval)

        hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_network)

        # Register node services for Z-Wave network
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE, add_node,
                               descriptions[const.SERVICE_ADD_NODE])
        hass.services.register(DOMAIN, const.SERVICE_ADD_NODE_SECURE,
                               add_node_secure,
                               descriptions[const.SERVICE_ADD_NODE_SECURE])
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_NODE, remove_node,
                               descriptions[const.SERVICE_REMOVE_NODE])
        hass.services.register(DOMAIN, const.SERVICE_CANCEL_COMMAND,
                               cancel_command,
                               descriptions[const.SERVICE_CANCEL_COMMAND])
        hass.services.register(DOMAIN, const.SERVICE_HEAL_NETWORK,
                               heal_network,
                               descriptions[const.SERVICE_HEAL_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_SOFT_RESET, soft_reset,
                               descriptions[const.SERVICE_SOFT_RESET])
        hass.services.register(DOMAIN, const.SERVICE_TEST_NETWORK,
                               test_network,
                               descriptions[const.SERVICE_TEST_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_STOP_NETWORK,
                               stop_network,
                               descriptions[const.SERVICE_STOP_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_START_NETWORK,
                               start_zwave,
                               descriptions[const.SERVICE_START_NETWORK])
        hass.services.register(DOMAIN, const.SERVICE_RENAME_NODE, rename_node,
                               descriptions[const.SERVICE_RENAME_NODE],
                               schema=RENAME_NODE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_RENAME_VALUE,
                               rename_value,
                               descriptions[const.SERVICE_RENAME_VALUE],
                               schema=RENAME_VALUE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_CONFIG_PARAMETER,
                               set_config_parameter,
                               descriptions[
                                   const.SERVICE_SET_CONFIG_PARAMETER],
                               schema=SET_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_CONFIG_PARAMETER,
                               print_config_parameter,
                               descriptions[
                                   const.SERVICE_PRINT_CONFIG_PARAMETER],
                               schema=PRINT_CONFIG_PARAMETER_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REMOVE_FAILED_NODE,
                               remove_failed_node,
                               descriptions[const.SERVICE_REMOVE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REPLACE_FAILED_NODE,
                               replace_failed_node,
                               descriptions[const.SERVICE_REPLACE_FAILED_NODE],
                               schema=NODE_SERVICE_SCHEMA)

        hass.services.register(DOMAIN, const.SERVICE_CHANGE_ASSOCIATION,
                               change_association,
                               descriptions[
                                   const.SERVICE_CHANGE_ASSOCIATION],
                               schema=CHANGE_ASSOCIATION_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_SET_WAKEUP,
                               set_wakeup,
                               descriptions[
                                   const.SERVICE_SET_WAKEUP],
                               schema=SET_WAKEUP_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_PRINT_NODE,
                               print_node,
                               descriptions[
                                   const.SERVICE_PRINT_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_ENTITY,
                               async_refresh_entity,
                               descriptions[
                                   const.SERVICE_REFRESH_ENTITY],
                               schema=REFRESH_ENTITY_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_REFRESH_NODE,
                               refresh_node,
                               descriptions[
                                   const.SERVICE_REFRESH_NODE],
                               schema=NODE_SERVICE_SCHEMA)
        hass.services.register(DOMAIN, const.SERVICE_RESET_NODE_METERS,
                               reset_node_meters,
                               descriptions[
                                   const.SERVICE_RESET_NODE_METERS],
                               schema=RESET_NODE_METERS_SCHEMA)

    # Setup autoheal
    if autoheal:
        _LOGGER.info("Z-Wave network autoheal is enabled")
        track_time_change(hass, heal_network, hour=0, minute=0, second=0)

    hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave)

    if 'frontend' in hass.config.components:
        register_built_in_panel(hass, 'zwave', 'Z-Wave', 'mdi:nfc')
        hass.http.register_view(api.ZWaveNodeValueView)
        hass.http.register_view(api.ZWaveNodeGroupView)
        hass.http.register_view(api.ZWaveNodeConfigView)
        hass.http.register_view(api.ZWaveUserCodeView)
        hass.http.register_static_path(
            URL_API_OZW_LOG, hass.config.path(OZW_LOG_FILENAME), False)

    return True
Esempio n. 55
0
class ZStickInterface(object):
    def __init__(self):
        self.sensor_events = []
        self.device = "/dev/ttyACM0"
        config_path = "plugins/python-openzwave/openzwave/config"
        user_path = "plugins/python-openzwave/config"
        # If using older Z-sticks, use the below device:
        # self.device = "/dev/ttyUSB0"
        # Change config paths where appropriate
        self.options = ZWaveOption(self.device, config_path=config_path,
                                   user_path=user_path, cmd_line="")
        # Turn off ozw console output
        self.options.set_console_output(False)
        self.options.set_save_log_level("Info")
        self.options.set_logging(False)
        self.options.lock()

        self.manager = libopenzwave.PyManager()
        self.manager.create()
        self.manager.addWatcher(self.event_callback)
        self.manager.addDriver(self.device)

        print("Starting Z-Wave Network...")
        self.network = ZWaveNetwork(self.options, log=None)
        # Wait for network to start
        while not self.network.state >= self.network.STATE_AWAKED:
            time.sleep(1)
        print("Z-Wave Network Started")

    def toggle_switch(self, node_id):
        try:
            in_work_node = self.network.nodes[node_id]
            switch_val = in_work_node.get_switches().keys()[0]
            if in_work_node.get_switch_state(switch_val):
                in_work_node.set_switch(switch_val, False)
            else:
                in_work_node.set_switch(switch_val, True)
        except:
            print("Invalid node id")

    def switch(self, node_id, state, function):
        try:
            in_work_node = self.network.nodes[node_id]
            if function == "dimmer":
                switch_val = in_work_node.get_dimmers().keys()[0]
                if state == "False":
                    in_work_node.set_dimmer(switch_val, 0)
                elif state == "True":
                    in_work_node.set_dimmer(switch_val, 99)
                else:
                    in_work_node.set_dimmer(switch_val, int(state))
            elif function == "switch":
                switch_val = in_work_node.get_switches().keys()[0]
                if state == "False":
                    in_work_node.set_switch(switch_val, False)
                else:
                    in_work_node.set_switch(switch_val, True)
        except:
            print("Invalid node id")

    def event_callback(self, args):
        if args["notificationType"] in ("ValueAdded", "ValueChanged"):
            cmd_class = args["valueId"]["commandClass"]
            if cmd_class == "COMMAND_CLASS_SENSOR_BINARY":
                node_id = args["valueId"]["nodeId"]
                state = args["valueId"]["value"]
                data = {"node_id": node_id, "state": state}
                self.sensor_events.append(data)

    def get_sensor_events(self):
        last_events = self.sensor_events
        self.sensor_events = []
        return last_events

    def stop_network(self):
        self.network.stop()
        else:
                assert False, "unhandled option"

# Check command line
if len(args) < 1:
        usage()
device = args[0]

# Open the communication with syslogd
loglevel = syslog.LOG_PID
if logstderr:
        loglevel |= syslog.LOG_PERROR
syslog.openlog(NAME, loglevel, syslog.LOG_USER)

# Define some manager options and create a network object
options = ZWaveOption(device, config_path = "./openzwave/config",
			user_path = ".", cmd_line = "")
options.set_log_file(NAME + ".log")
options.set_append_log_file(False)
#options.set_console_output(True)
options.set_console_output(False)
options.set_save_log_level(log)
options.set_logging(True)
options.lock()
network = ZWaveNetwork(options, log = None)

# Add the basic callbacks
dispatcher.connect(louie_network_started,
			ZWaveNetwork.SIGNAL_NETWORK_STARTED)
dispatcher.connect(louie_network_resetted,
			ZWaveNetwork.SIGNAL_NETWORK_RESETTED)
dispatcher.connect(louie_network_ready,