|
| 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] |
0 commit comments