Skip to content

Commit 554c0ed

Browse files
committed
Moved ihc platform to sub folder and optimizations for faster startup
1 parent 3e88e89 commit 554c0ed

File tree

9 files changed

+248
-203
lines changed

9 files changed

+248
-203
lines changed

custom_components/binary_sensor/ihc.py

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
"""
22
IHC binary sensor platform.
33
"""
4-
# pylint: disable=too-many-arguments, too-many-instance-attributes, bare-except
4+
# pylint: disable=too-many-arguments, too-many-instance-attributes, bare-except, missing-docstring
55
import logging
6-
import xml.etree.ElementTree
76
import voluptuous as vol
87
import homeassistant.helpers.config_validation as cv
98
from homeassistant.components.binary_sensor import (
109
BinarySensorDevice, PLATFORM_SCHEMA, DEVICE_CLASSES_SCHEMA)
1110
from homeassistant.const import STATE_UNKNOWN, CONF_NAME, CONF_TYPE
12-
from ..ihc import IHCDevice, get_ihc_instance
11+
from ..ihc import get_ihc_platform
12+
from ..ihc.ihcdevice import IHCDevice
1313

1414
DEPENDENCIES = ['ihc']
1515

@@ -72,10 +72,10 @@
7272
# pylint: disable=unused-argument
7373
def setup_platform(hass, config, add_devices, discovery_info=None):
7474
"""Set up the IHC binary setsor platform."""
75-
ihccontroller = get_ihc_instance(hass)
75+
ihcplatform = get_ihc_platform(hass)
7676
devices = []
7777
if config.get(CONF_AUTOSETUP):
78-
auto_setup(ihccontroller, devices)
78+
auto_setup(ihcplatform, devices)
7979

8080
ids = config.get(CONF_IDS)
8181
if ids != None:
@@ -85,30 +85,22 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
8585
name = data[CONF_NAME]
8686
sensortype = sensortype = data[CONF_TYPE] if CONF_TYPE in data else None
8787
inverting = data[CONF_INVERTING] if CONF_INVERTING in data else False
88-
add_sensor(devices, ihccontroller, int(ihcid), name, sensortype, True, inverting)
88+
add_sensor(devices, ihcplatform.ihc, int(ihcid), name, sensortype, True, inverting)
8989

9090
add_devices(devices)
9191
# Start notification after devices has been added
9292
for device in devices:
93-
device.ihc.add_notify_event(device.get_ihcid(), device.on_ihc_change)
93+
device.ihc.add_notify_event(device.get_ihcid(), device.on_ihc_change, True)
9494

95-
def auto_setup(ihccontroller, devices):
95+
def auto_setup(ihcplatform, devices):
9696
"""auto setup ihc binary sensors from ihc project."""
9797
_LOGGER.info("Auto setup - IHC Binary sensors")
98-
project = ihccontroller.get_project()
99-
xdoc = xml.etree.ElementTree.fromstring(project)
100-
groups = xdoc.findall(r'.//group')
101-
for group in groups:
102-
groupname = group.attrib['name']
103-
for productcfg in PRODUCTAUTOSETUP:
104-
products = group.findall(productcfg['xpath'])
105-
for product in products:
106-
node = product.find(productcfg['node'])
107-
ihcid = int(node.attrib['id'].strip('_'), 0)
108-
name = groupname + "_" + str(ihcid)
109-
add_sensor_from_node(devices, ihccontroller, ihcid, name,
110-
product, productcfg['type'],
111-
productcfg['inverting'])
98+
def setup_product(ihcid, name, product, productcfg):
99+
add_sensor_from_node(devices, ihcplatform.ihc, ihcid, name,
100+
product, productcfg['type'],
101+
productcfg['inverting'])
102+
ihcplatform.autosetup(PRODUCTAUTOSETUP, setup_product)
103+
112104

113105
class IHCBinarySensor(IHCDevice, BinarySensorDevice):
114106
"""IHC Binary Sensor."""

custom_components/ihc.py

Lines changed: 0 additions & 110 deletions
This file was deleted.

custom_components/ihc/__init__.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"""
2+
IHC platform.
3+
"""
4+
# pylint: disable=too-many-arguments, too-many-instance-attributes, bare-except
5+
import time
6+
import logging
7+
import os.path
8+
import asyncio
9+
import xml.etree.ElementTree
10+
import voluptuous as vol
11+
12+
import homeassistant.helpers.config_validation as cv
13+
from homeassistant.const import CONF_URL, CONF_USERNAME, CONF_PASSWORD
14+
from homeassistant.config import load_yaml_config_file
15+
16+
from . import const
17+
18+
REQUIREMENTS = ['ihcsdk==2.1.0']
19+
DOMAIN = 'ihc'
20+
21+
CONF_INFO = 'info'
22+
23+
CONFIG_SCHEMA = vol.Schema({
24+
DOMAIN: vol.Schema({
25+
vol.Required(CONF_URL): cv.string,
26+
vol.Required(CONF_USERNAME): cv.string,
27+
vol.Required(CONF_PASSWORD): cv.string,
28+
vol.Required(CONF_INFO): cv.boolean
29+
}),
30+
}, extra=vol.ALLOW_EXTRA)
31+
32+
_LOGGER = logging.getLogger(__name__)
33+
34+
def setup(hass, config):
35+
"""Setyp the IHC platform."""
36+
from ihcsdk.ihccontroller import IHCController
37+
url = config[DOMAIN].get(CONF_URL)
38+
username = config[DOMAIN].get(CONF_USERNAME)
39+
password = config[DOMAIN].get(CONF_PASSWORD)
40+
ihc = IHCController(url, username, password)
41+
ihc.info = config[DOMAIN].get(CONF_INFO)
42+
43+
if not ihc.authenticate():
44+
_LOGGER.error("Unable to authenticate on ihc controller. Username/password may be wrong")
45+
return False
46+
47+
hass.data[DOMAIN] = IHCPlatform(ihc)
48+
49+
#Service functions
50+
51+
def set_runtime_value_bool(call):
52+
"""Set a IHC runtime bool value service function """
53+
ihcid = int(call.data.get('ihcid', 0))
54+
value = bool(call.data.get('value', 0))
55+
ihc.set_runtime_value_bool(ihcid, value)
56+
57+
def set_runtime_value_int(call):
58+
"""Set a IHC runtime integer value service function """
59+
ihcid = int(call.data.get('ihcid', 0))
60+
value = int(call.data.get('value', 0))
61+
ihc.set_runtime_value_int(ihcid, value)
62+
63+
def set_runtime_value_float(call):
64+
"""Set a IHC runtime float value service function """
65+
ihcid = int(call.data.get('ihcid', 0))
66+
value = float(call.data.get('value', 0))
67+
ihc.set_runtime_value_float(ihcid, value)
68+
69+
descriptions = load_yaml_config_file(
70+
os.path.join(os.path.dirname(__file__), 'services.yaml'))
71+
72+
hass.services.register(DOMAIN, const.SERVICE_SET_RUNTIME_VALUE_BOOL,
73+
set_runtime_value_bool,
74+
descriptions[const.SERVICE_SET_RUNTIME_VALUE_BOOL])
75+
hass.services.register(DOMAIN, const.SERVICE_SET_RUNTIME_VALUE_INT,
76+
set_runtime_value_int,
77+
descriptions[const.SERVICE_SET_RUNTIME_VALUE_INT])
78+
hass.services.register(DOMAIN, const.SERVICE_SET_RUNTIME_VALUE_FLOAT,
79+
set_runtime_value_float,
80+
descriptions[const.SERVICE_SET_RUNTIME_VALUE_FLOAT])
81+
82+
#hass.http.register_view(IHCSetupView())
83+
return True
84+
85+
86+
87+
class IHCPlatform:
88+
"""Wraps the IHCController for caching of ihc project and autosetup"""
89+
def __init__(self, ihccontroller):
90+
self.ihc = ihccontroller
91+
project = self.ihc.get_project()
92+
self._project = xml.etree.ElementTree.fromstring(project)
93+
self._groups = self._project.findall(r'.//group')
94+
95+
def get_project_xml(self):
96+
"""Get the cached ihc project as xml"""
97+
return self._project
98+
99+
def get_groups_xml(self):
100+
"""Get the groups from the ihc project and cache the result"""
101+
return self._groups
102+
103+
def autosetup(self, productautosetup, callback):
104+
"""Do autosetup of a component usign the specified productautosetup"""
105+
groups = self.get_groups_xml()
106+
for group in groups:
107+
groupname = group.attrib['name']
108+
for productcfg in productautosetup:
109+
products = group.findall(productcfg['xpath'])
110+
for product in products:
111+
nodes = product.findall(productcfg['node'])
112+
for node in nodes:
113+
if 'setting' in node.attrib and node.attrib['setting'] == 'yes':
114+
continue
115+
ihcid = int(node.attrib['id'].strip('_'), 0)
116+
name = groupname + "_" + str(ihcid)
117+
callback(ihcid, name, product, productcfg)
118+
119+
def get_ihc_platform(hass) -> IHCPlatform:
120+
"""Get the ihc platform instance from the hass configuration
121+
This is a singleton object.
122+
"""
123+
while not DOMAIN in hass.data:
124+
time.sleep(0.1)
125+
return hass.data[DOMAIN]

custom_components/ihc/const.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
IHC platform constants
3+
"""
4+
5+
SERVICE_SET_RUNTIME_VALUE_BOOL = "set_runtime_value_bool"
6+
SERVICE_SET_RUNTIME_VALUE_INT = "set_runtime_value_int"
7+
SERVICE_SET_RUNTIME_VALUE_FLOAT = "set_runtime_value_float"

custom_components/ihc/ihcdevice.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# pylint: disable=missing-docstring, too-many-arguments
2+
3+
class IHCDevice:
4+
"""Base class for all ihc devices"""
5+
def __init__(self, ihccontroller, name, ihcid, ihcname: str, ihcnote: str, ihcposition: str):
6+
self.ihc = ihccontroller
7+
self._name = name
8+
self._ihcid = ihcid
9+
self.ihcname = ihcname
10+
self.ihcnote = ihcnote
11+
self.ihcposition = ihcposition
12+
13+
@property
14+
def name(self):
15+
"""Return the device name"""
16+
return self._name
17+
18+
def get_ihcid(self) -> int:
19+
"""Return the ihc resource id."""
20+
return self._ihcid
21+
22+
def set_name(self, name):
23+
"""Set the name"""
24+
self._name = name
25+
26+
@property
27+
def device_state_attributes(self):
28+
"""Return the state attributes."""
29+
if not self.ihc.info:
30+
return {}
31+
return {
32+
'ihcid': self._ihcid,
33+
'ihcname' : self.ihcname,
34+
'ihcnote' : self.ihcnote,
35+
'ihcposition' : self.ihcposition
36+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Describes the format for available ihc services
2+
3+
set_runtime_value_bool:
4+
description: Set a boolean runtime value on the ihc controller
5+
fields:
6+
ihcid:
7+
description: The integer ihc resource id
8+
value:
9+
description: The boolean value to set
10+
11+
set_runtime_value_int:
12+
description: Set a integer runtime value on the ihc controller
13+
fields:
14+
ihcid:
15+
description: The integer ihc resource id
16+
value:
17+
description: The integer value to set
18+
19+
set_runtime_value_float:
20+
description: Set a float runtime value on the ihc controller
21+
fields:
22+
ihcid:
23+
description: The integer ihc resource id
24+
value:
25+
description: The float value to set
26+

0 commit comments

Comments
 (0)