Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support TCW241 and move API to own module #17

Merged
merged 3 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 101 additions & 47 deletions custom_components/teracom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
import xml.etree.ElementTree as ET
from datetime import timedelta

from homeassistant.components.rest.data import RestData
import xmltodict
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.event import async_track_time_interval

from .const import DOMAIN, SIGNAL_UPDATE_TERACOM
from .helper import TcwApi
from .const import DOMAIN, SIGNAL_UPDATE_TERACOM, TCW122B_CM, TCW181B_CM, TCW241, TCW242
from .pyteracom import TeracomAPI

_LOGGER = logging.getLogger(__name__)

Expand All @@ -33,45 +35,107 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):

async def poll_update(event_time):
# _LOGGER.debug("Entered pollupdate")
await _hassdata["api"].get_data()
# _LOGGER.debug("Calling dispatcher_send")
data = await _hassdata["api"].get_data()
# _LOGGER.debug("Calling dispatcher_send")
parse_response(data)
dispatcher_send(hass, SIGNAL_UPDATE_TERACOM)

def parse_response(data):
"""Parse the response."""
_hassdata["xml"] = data
try:
result_dict = xmltodict.parse(data)
except Exception as exc: # pylint: disable=broad-except
raise HomeAssistantError("Cannot parse response") from exc
_hassdata["data_dict"] = result_dict
root = ET.fromstring(data)
model = config["model"]
if model == TCW122B_CM:
_hassdata["temperature1"] = (
None
if root.find("Temperature1").text == "---"
else float(root.find("Temperature1").text[0:-2])
)
_hassdata["temperature2"] = (
None
if root.find("Temperature2").text == "---"
else float(root.find("Temperature2").text[0:-2])
)
_hassdata["humidity1"] = (
None
if root.find("Humidity1").text == "---"
else float(root.find("Humidity1").text[0:-1])
)
_hassdata["humidity2"] = (
None
if root.find("Humidity2").text == "---"
else float(root.find("Humidity2").text[0:-1])
)
_hassdata["voltage1"] = float(root.find("AnalogInput1").text[0:-1])
_hassdata["voltage2"] = float(root.find("AnalogInput2").text[0:-1])
_hassdata["digital1"] = root.find("DigitalInput1").text == "CLOSED"
_hassdata["digital2"] = root.find("DigitalInput2").text == "CLOSED"
_hassdata["relay1"] = root.find("Relay1").text == "ON"
_hassdata["relay2"] = root.find("Relay2").text == "ON"
if model == TCW181B_CM:
_hassdata["digital"] = root.find("DigitalInput").text == "CLOSED"
for nox in range(1, 9):
_hassdata[f"relay{nox}"] = root.find(f"Relay{nox}").text == "ON"
if model in (TCW241,):
for i in range(1, 5):
_hassdata[f"analog{i}"] = _hassdata["data_dict"]["Monitor"]["AI"][
f"AI{i}"
]["value"]
for i in range(1, 5):
_hassdata[f"digital{i}"] = (
_hassdata["data_dict"]["Monitor"]["DI"][f"DI{i}"]["valuebin"] == "0"
)
if model in (TCW241, TCW242):
for i in range(1, 5):
_hassdata[f"relay{i}"] = (
_hassdata["data_dict"]["Monitor"]["R"][f"R{i}"]["valuebin"] == "1"
)

hass.data[DOMAIN][entry.entry_id] = {}
_hassdata = hass.data[DOMAIN][entry.entry_id]

config = entry.data
_hassdata["api"] = TcwApi(
hass, entry, config.get("host"), config.get("user"), config.get("password")

websession = async_get_clientsession(hass)
_hassdata["api"] = TeracomAPI(
websession=websession,
host=config.get(CONF_HOST),
username=config.get(CONF_USERNAME),
password=config.get(CONF_PASSWORD),
)
method = "GET"
payload = None
auth = None
# verify_ssl = DEFAULT_VERIFY_SSL
headers = {}
endpoint = f"http://{config.get('host')}/status.xml"
encoding = ""
result_text = await _hassdata["api"].get_data()

try:
rest = RestData(
hass, method, endpoint, encoding, auth, headers, None, payload, False
result_dict = xmltodict.parse(result_text)
except Exception as exc: # pylint: disable=broad-except
raise HomeAssistantError("Cannot parse response") from exc

_hassdata["data_dict"] = result_dict
_hassdata["xml"] = result_text

if config.get("model") in (TCW122B_CM, TCW181B_CM):
_hassdata["id"] = _hassdata["data_dict"]["Monitor"]["ID"].replace(":", "")
_hassdata["device"] = _hassdata["data_dict"]["Monitor"]["Device"].strip()
_hassdata["hostname"] = _hassdata["data_dict"]["Monitor"]["Hostname"].strip()
_hassdata["fw"] = _hassdata["data_dict"]["Monitor"]["FW"].strip()
else:
_hassdata["id"] = _hassdata["data_dict"]["Monitor"]["DeviceInfo"]["ID"].replace(
":", ""
)
await rest.async_update()
except Exception as err:
raise ConfigEntryNotReady from err

if rest.data is None:
_LOGGER.error("Unable to fetch data from device - async-setup_entry()")
return False

# Process rest.data to find static values as device_name etc
_hassdata["xml"] = rest.data
root = ET.fromstring(rest.data)
_hassdata["id"] = root.find("ID").text.replace(":", "")
_hassdata["device"] = root.find("Device").text.strip()
_hassdata["hostname"] = root.find("Hostname").text.strip().title()
_hassdata["fw"] = root.find("FW").text
_LOGGER.debug("setup_entry: %s", entry.entry_id)
_hassdata["device"] = _hassdata["data_dict"]["Monitor"]["DeviceInfo"][
"DeviceName"
].strip()
_hassdata["hostname"] = _hassdata["data_dict"]["Monitor"]["DeviceInfo"][
"HostName"
].strip()
_hassdata["fw"] = _hassdata["data_dict"]["Monitor"]["DeviceInfo"][
"FwVer"
].strip()

device_info = DeviceInfo(
connections={(dr.CONNECTION_NETWORK_MAC, _hassdata["id"])},
Expand All @@ -83,16 +147,13 @@ async def poll_update(event_time):
configuration_url=f"http://{config.get('host')}",
)
_LOGGER.debug("Adding or updating teracom device %s", _hassdata["id"])
# device_registry = await hass.helpers.device_registry.async_get_registry()
device_registry = dr.async_get(hass)
device_registry.async_get_or_create(**device_info)

await _hassdata["api"].get_data()
data = await _hassdata["api"].get_data()
parse_response(data)

for component in PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, component)
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

async_track_time_interval(hass, poll_update, SCAN_INTERVAL)
dispatcher_send(hass, SIGNAL_UPDATE_TERACOM)
Expand All @@ -101,14 +162,7 @@ async def poll_update(event_time):

async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Unload a config entry."""
unload_ok = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(entry, component)
for component in PLATFORMS
]
)
)
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)

Expand Down
23 changes: 15 additions & 8 deletions custom_components/teracom/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Binary sensors"""

from .const import TCW122B_CM, TCW181B_CM, TCW241, TCW242
from .entity import TcwEntity


Expand All @@ -8,14 +9,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities):

def get_entities():
sensors = []
if config_entry.data["model"] == "TCW122B-CM":
if config_entry.data["model"] == TCW122B_CM:
sensors.append(
TcwBinarySensor(
hass,
config_entry,
"digital1",
"dig1",
"Digital input 1",
None,
None,
None,
Expand All @@ -26,26 +25,34 @@ def get_entities():
hass,
config_entry,
"digital2",
"dig2",
"Digital input 2",
None,
None,
None,
)
)
elif config_entry.data["model"] == "TCW181B-CM":
elif config_entry.data["model"] == TCW181B_CM:
sensors.append(
TcwBinarySensor(
hass,
config_entry,
"digital",
"dig",
"Digital input",
None,
None,
None,
)
)
elif config_entry.data["model"] in (TCW241,):
for i in range(1, 5):
sensors.append(
TcwBinarySensor(
hass,
config_entry,
f"digital{i}",
None,
None,
None,
)
)
return sensors

async_add_entities(await hass.async_add_job(get_entities), True)
Expand Down
Loading