ISY994 Variables as Sensors

All, if anyone is interested (besides myself and @Blueman2) – I am testing the ability to add ISY Variables as sensor devices within Home Assistant.

There is an initial demo available as a custom_component here:

To Use:

  1. Download the contents of that folder to your -hass-config-/custom_components/isy994/ folder and restart.
  2. Add the variable IDs you want to include into your configuration.yaml file:
isy994:
  host: !secret isy_host
  username: !secret isy_username
  password: !secret isy_password
  ignore_string: "[i]"
  sensor_string: "[s]"
  isy_variables:
    sensors:
      - id: 23                    # ISY Variable ID
        type: 2                   # ISY Variable Type (1=Int, 2=State)
        unit_of_measurement: '%'  # Optional UoM
        device_class: 'battery'   # Optional Device Class
        icon: mdi:house           # Optional Icon
    binary_sensor:
      - id: 24                    # ISY Variable ID
        type: 2                   # ISY Variable Type (1=Int, 2=State)
        'on': 1                   # Optional Value for ON
        'off': 0                  # Optional Value for OFF
        device_class: 'moisture'  # Optional Device Class
    switches:
      - id: 25
        type: 2

Capture

If there is enough interest, I will work on a PR to get this included in an upcoming release.

1 Like

Very cool! Actually, I have your component already installed on my Hassio (RPi3) because it gave me a perfectly working Insteon Thermostat! I also noticed in the log that is was sucking up Variable data on startup, but I never saw that it turned them into Sensors. I will get your latest drop and test it. Is there anything else I need to do to create the sensors via a platform config entry?

edit: ah, I missed the need to put variables in the configuration.yaml. Cool I assume the just does State variables? That is all I care about, but just wanted to ask.

Also, is the variable update being done by polling every x seconds? That was the downside to other methods I have seen. I wish there was the ability to use the Node capabilities of the ISY to push changes when needed to reduce traffic and load.

FYI, I am getting an error on load.

2019-06-26 15:39:57 WARNING (MainThread) [homeassistant.loader] You are using a custom integration for isy994 which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you do experience issues with Home Assistant.
2019-06-26 15:39:58 WARNING (MainThread) [homeassistant.components.http] Configuring api_password via the http component has been deprecated. Use the legacy api password auth provider instead. For instructions, see https://www.home-assistant.io/docs/authentication/providers/#legacy-api-password
2019-06-26 15:39:58 WARNING (MainThread) [homeassistant.components.http.auth] legacy_api_password support has been enabled.
2019-06-26 15:40:02 ERROR (MainThread) [homeassistant.setup] Error during setup of component person
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/setup.py", line 153, in _async_setup_component
    hass, processed_config)
  File "/usr/src/homeassistant/homeassistant/components/person/__init__.py", line 272, in async_setup
    await manager.async_initialize()
  File "/usr/src/homeassistant/homeassistant/components/person/__init__.py", line 105, in async_initialize
    raw_storage = await self.store.async_load()
  File "/usr/src/homeassistant/homeassistant/helpers/storage.py", line 81, in async_load
    return await self._load_task
concurrent.futures._base.CancelledError
2019-06-26 15:40:02 ERROR (MainThread) [homeassistant.setup] Error during setup of component config
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/setup.py", line 153, in _async_setup_component
    hass, processed_config)
  File "/usr/src/homeassistant/homeassistant/components/config/__init__.py", line 65, in async_setup
    await asyncio.wait(tasks)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 363, in wait
    return await _wait(fs, timeout, return_when, loop)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 456, in _wait
    await waiter
concurrent.futures._base.CancelledError
2019-06-26 15:40:02 ERROR (MainThread) [homeassistant.setup] Error during setup of component script
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/setup.py", line 153, in _async_setup_component
    hass, processed_config)
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 60, in async_setup
    await _async_process_config(hass, config, component)
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 125, in _async_process_config
    await component.async_add_entities(scripts)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 221, in async_add_entities
    await asyncio.wait(tasks)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 363, in wait
    return await _wait(fs, timeout, return_when, loop)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 456, in _wait
    await waiter
concurrent.futures._base.CancelledError
2019-06-26 15:40:02 ERROR (MainThread) [homeassistant.setup] Error during setup of component sensor
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "uvloop/loop.pyx", line 1451, in uvloop.loop.Loop.run_until_complete
  File "/usr/src/homeassistant/homeassistant/__main__.py", line 290, in setup_and_run_hass
    log_no_color=args.log_no_color)
  File "/usr/src/homeassistant/homeassistant/bootstrap.py", line 188, in async_from_config_file
    config_dict, hass, enable_log=False, skip_pip=skip_pip)
  File "/usr/src/homeassistant/homeassistant/bootstrap.py", line 92, in async_from_config_dict
    await _async_set_up_integrations(hass, config)
  File "/usr/src/homeassistant/homeassistant/bootstrap.py", line 411, in _async_set_up_integrations
    for domain in domains_to_load
  File "/usr/src/homeassistant/homeassistant/setup.py", line 50, in async_setup_component
    return await task  # type: ignore
  File "/usr/src/homeassistant/homeassistant/setup.py", line 126, in _async_setup_component
    hass, config, integration)
  File "/usr/src/homeassistant/homeassistant/config.py", line 668, in async_process_component_config
    component = integration.get_component()
  File "/usr/src/homeassistant/homeassistant/loader.py", line 130, in get_component
    cache[self.domain] = importlib.import_module(self.pkg_path)
  File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 724, in exec_module
  File "<frozen importlib._bootstrap_external>", line 860, in get_code
  File "<frozen importlib._bootstrap_external>", line 791, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/config/custom_components/isy994/__init__.py", line 7
    <!DOCTYPE html>
    ^
SyntaxError: invalid syntax

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/setup.py", line 153, in _async_setup_component
    hass, processed_config)
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 42, in async_setup
    await component.async_setup(config)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 112, in async_setup
    await asyncio.wait(tasks)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 363, in wait
    return await _wait(fs, timeout, return_when, loop)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 456, in _wait
    await waiter
concurrent.futures._base.CancelledError

No, the ISY provides a websocket connection which the Hass integration uses to subscribe to changes to nodes, programs and variables.

Regarding the error, it looks like you may not have saved the ‘raw’ files from GitHub

D’oh! Yes, I should have recognized the error. After downloading the sensor and init components correctly (I already had the older components in correct RAW format) it fired right up! The variables I had placed in the config came over, even keeping their correct names! shbatm, this is a HUGE thing for my setup. You saved me from having to write about a dozen network resources on the ISY to send variables over to the HA. Well done, sir!!

I see you put this into the climate branch, so I will move over that that one.

I missed this comment earlier. No, this works for both State and Integer variables. The Variable ID is unique across both (e.g. you wont have a #5 State and #5 Integer). When I get time I’m going to expand this a bit to include the ability to specify a Unit of Measurement, Device Type, and/or classify a variable as a binary_sensor. Let me know if there’s any other use cases you may have.

Thanks, @shbatm! So far, this pretty much nails what I needed! I am using a manually configured Alexa skill with HA as the endpoint to support asking Alexa for states of different devices in my house. For example, “Alexa, ask Pool water temperature” or “Alexa, ask Pool Salt Level”. I have the vast majority of my devices controlled by the ISY with status stored in variables. So having variables accessible on HA allows me to get status of all my devices.

As for State and Integer, I am confused. I do have a State variable ID#5 and an Integer variable ID#5. In the ISY, #5 state is 2/5 and #5 integer is 1/5. With your config, I do not see a way to get Integer values into HA. But, this is not an issue for me since I do not care to pull Integer values over.

On another note, you must have done some tweaking to the base code in terms of better identifying z-wave sensors. With the original code base, all z-wave sensors came over a binary sensor. For example, z-wave power meters now come across correctly as Sensor, not Binary Sensor. However, they still do not populate with a value. I know not an issue you are working on, but just wanted to mention it.

Yeah, this was a side effect of troubleshooting the z-wave thermostats. ISY reports all Z-Wave devices as the same “type” and its difficult trying to get the Hass implementation to correctly sort through them without having a Z-wave enabled ISY and being able to grab the /rest/node definitions.

Welp, that’s interesting. I didn’t think there were common IDs on the variables, but that may be a firmware thing on the ISY end. What firmware version are you using?

Both state and integer variables come over–I search both state and integer lists for the variable ID–so it shouldn’t be much to add the type to the config to make sure it gets the right one.

D’oh again! Your are correct, sir. Both State and Integer did come over just fine. Since I only have 3 Integer variables and over 100 State variables, I just missed them. I am running ISY v5.14A.

Do you have an ISY994 without z-wave? Do you want a Z-wave module for it? I would be happy to send you one.

I am having an issue where the Entity IDs and Names of State and Integer variables are being interchanged. The Names do match the correct values, but the Entity IDs refer to a different variable, being the one with the same ISY ID for both Integer and State. Odd thing is that reboots will somewhat randomly change which sensors this impacts, but it is always sensors which have and ISY ID that is the same across State and Integer. So there definitely is something wonky going on.

I made some more updates (got busy working on this instead of what I should have been working on…)

You can now declare both kinds of variables as sensors, binary_sensors, or switches

isy994:
  host: !secret isy_host
  username: !secret isy_username
  password: !secret isy_password
  ignore_string: "[i]"
  sensor_string: "[s]"
  isy_variables:
    sensors:
      - id: 23                    # ISY Variable ID
        type: 2                   # ISY Variable Type (1=Int, 2=State)
        unit_of_measurement: '%'  # Optional UoM
        device_class: 'battery'   # Optional Device Class
        icon: mdi:house           # Optional Icon
    binary_sensors:
      - id: 24                    # ISY Variable ID
        type: 2                   # ISY Variable Type (1=Int, 2=State)
        payload_on: 1                   # Optional Value for ON
        payload_off: 0                  # Optional Value for OFF
        device_class: 'moisture'  # Optional Device Class
    switches:
      - id: 25
        type: 2

@shbatm, Really appreciate the work you are doing on this. Thanks!

Thanks again, @shbatm! FYI, your z-wave module is going in the mail today. Going regular first class so no tracking, but should arrive mid next week.

I will give your new code a try today. What do the ignore_string values do?

I am getting a config error. Here is my configuration.yaml entry:

isy994:
  host: http://192.168.1.145
  username: xxxx
  password: xxxx
  isy_variables:
    sensors:
      - id: 1
        type: 2
      - id: 2
        type: 2
      - id: 3
        type: 2
        unit_of_measurement: '°F'
        device_class: 'temperature'
      - id: 4
        type: 2
        unit_of_measurement: '°F'
        device_class: 'temperature'

And here is the error I am getting:

Invalid config for [isy994]: expected int @ data['isy994']['isy_variables'][0]. Got None. (See /config/configuration.yaml, line 74). Please check the docs at https://home-assistant.io/components/isy994/

Is it ‘sensors’ and ‘binary_sensor’? Maybe plural is wrong?

Nope, plural is correct for both. It looks like you didn’t update __init__.py and it’d still looking for the old config style.

These are in the original ISY994 implementation. Any node, scene, group, etc. with that string in the name on the ISY are ignored and not imported into Hass. I use it for things that report independently to Hass and the ISY (like Hue and TPLink Kasa)

Hmm. I am pretty darn sure I have the correct init file. I opened it and it does have your new code. But not matter what I do, it keeps giving that same error message. I am on Hassio 0.94.0, if that matters. Not urgent as all my variables that were imported before still work just fine. But I really do like the new features you have added!!

Double check that this line is:

vol.Optional(CONF_ISY_VARIABLES, default={}): ISY_VARIABLES_SCHEMA

and not:

vol.Optional(CONF_ISY_VARIABLES, default=[]): vol.All(cv.ensure_list,
                                                              [vol.Coerce(int)])

You can also delete the custom_components/isy994/__pycache__ folder to make sure it refreshes.

And don’t forget to restart Home Assistant–done that more times than I can count.

1 Like

Uh, that fact that pycache never came back should have been my clue. You nailed it. I was doing Hassio Restart, but I guess I needed to do full reboot. On reboot, it is now reading variables. It is hitting another error now on ‘binary_sensor:’ section, but I will see what I did wrong.

Live and learn…

edit: so is it ‘binary_sensor:’ as listed in the example above, or binary_sensors? The .py code seems to imply binary_sensors. Just checking.

edit:edit: yes, it is ‘binary_sensors’, all plural like you mentioned above. All errors are now gone. Re-adding the variables back into my custom UI. happy, happy!

edit:edit:edit: I noticed this is forked off of the code that did not have the update for Thermostats. Guessing that gets merged back in down the road.