Skip to content

Commit

Permalink
Merge pull request #24 from w1ll1am23/test_workflows
Browse files Browse the repository at this point in the history
chore: move version to variable in setup.py
  • Loading branch information
w1ll1am23 authored Dec 10, 2022
2 parents d5b1ad7 + a4e0b9c commit 3094d08
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 179 deletions.
73 changes: 0 additions & 73 deletions CHANGELOG.md

This file was deleted.

19 changes: 0 additions & 19 deletions script/lint

This file was deleted.

88 changes: 63 additions & 25 deletions src/pyeconet/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
from typing import Type, TypeVar, List, Dict, Optional
import logging

from pyeconet.errors import PyeconetError, InvalidCredentialsError, GenericHTTPError, InvalidResponseFormat
from pyeconet.errors import (
PyeconetError,
InvalidCredentialsError,
GenericHTTPError,
InvalidResponseFormat,
)
from pyeconet.equipment import Equipment, EquipmentType
from pyeconet.equipment.water_heater import WaterHeater
from pyeconet.equipment.thermostat import Thermostat
Expand All @@ -21,7 +26,7 @@
HEADERS = {
"ClearBlade-SystemKey": CLEAR_BLADE_SYSTEM_KEY,
"ClearBlade-SystemSecret": CLEAR_BLADE_SYSTEM_SECRET,
"Content-Type": "application/json; charset=UTF-8"
"Content-Type": "application/json; charset=UTF-8",
}

_LOGGER = logging.getLogger(__name__)
Expand All @@ -34,8 +39,9 @@ class EcoNetApiInterface:
API interface object.
"""

def __init__(self, email: str, password: str, account_id: str = None,
user_token: str = None) -> None:
def __init__(
self, email: str, password: str, account_id: str = None, user_token: str = None
) -> None:
"""
Create the EcoNet API interface object.
Args:
Expand All @@ -62,32 +68,43 @@ def account_id(self) -> str:
return self._account_id

@classmethod
async def login(cls: Type[ApiType],
email: str,
password: str) -> ApiType:
async def login(cls: Type[ApiType], email: str, password: str) -> ApiType:
"""Create an EcoNetApiInterface object using email and password
Args:
email (str): EcoNet account email address.
password (str): EcoNet account password.
"""
this_class = cls(email, password)
await this_class._authenticate(
{"email": email, "password": password}
)
await this_class._authenticate({"email": email, "password": password})
return this_class

def subscribe(self):
"""Subscribe to the MQTT updates"""
if not self._equipment:
_LOGGER.error("Equipment list is empty, did you call get_equipment before subscribing?")
_LOGGER.error(
"Equipment list is empty, did you call get_equipment before subscribing?"
)
return False

self._mqtt_client = mqtt.Client(self._get_client_id(), clean_session=True, userdata=None, protocol=mqtt.MQTTv311)
self._mqtt_client.username_pw_set(self._user_token, password=CLEAR_BLADE_SYSTEM_KEY)
self._mqtt_client = mqtt.Client(
self._get_client_id(),
clean_session=True,
userdata=None,
protocol=mqtt.MQTTv311,
)
self._mqtt_client.username_pw_set(
self._user_token, password=CLEAR_BLADE_SYSTEM_KEY
)
self._mqtt_client.enable_logger()
self._mqtt_client.tls_set(ca_certs=None, certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED,
tls_version=ssl.PROTOCOL_TLS, ciphers=None)
self._mqtt_client.tls_set(
ca_certs=None,
certfile=None,
keyfile=None,
cert_reqs=ssl.CERT_REQUIRED,
tls_version=ssl.PROTOCOL_TLS,
ciphers=None,
)
self._mqtt_client.on_connect = self._on_connect
self._mqtt_client.on_message = self._on_message
self._mqtt_client.on_disconnect = self._on_disconnect
Expand All @@ -98,9 +115,16 @@ def publish(self, payload: Dict, device_id: str, serial_number: str):
"""Publish payload to the specified topic"""
date_time = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
transaction_id = f"ANDROID_{date_time}"
publish_payload = {"transactionId": transaction_id, "device_name": device_id, "serial_number": serial_number}
publish_payload = {
"transactionId": transaction_id,
"device_name": device_id,
"serial_number": serial_number,
}
publish_payload.update(payload)
self._mqtt_client.publish(f"user/{self._account_id}/device/desired", payload=json.dumps(publish_payload))
self._mqtt_client.publish(
f"user/{self._account_id}/device/desired",
payload=json.dumps(publish_payload),
)

def unsubscribe(self) -> None:
self._mqtt_client.loop_stop(force=True)
Expand All @@ -116,10 +140,16 @@ async def _get_equipment(self) -> None:
# They spelled it wrong...
for _equip in _location.get("equiptments"):
_equip_obj: Equipment = None
if Equipment._coerce_type_from_string(_equip.get("device_type")) == EquipmentType.WATER_HEATER:
if (
Equipment._coerce_type_from_string(_equip.get("device_type"))
== EquipmentType.WATER_HEATER
):
_equip_obj = WaterHeater(_equip, self)
self._equipment[_equip_obj.serial_number] = _equip_obj
elif Equipment._coerce_type_from_string(_equip.get("device_type")) == EquipmentType.THERMOSTAT:
elif (
Equipment._coerce_type_from_string(_equip.get("device_type"))
== EquipmentType.THERMOSTAT
):
_equip_obj = Thermostat(_equip, self)
self._equipment[_equip_obj.serial_number] = _equip_obj
for zoning_device in _equip.get("zoning_devices", []):
Expand Down Expand Up @@ -155,7 +185,9 @@ async def _get_location(self) -> List[Dict]:

_session = ClientSession()
try:
async with _session.post(f"{REST_URL}/code/{CLEAR_BLADE_SYSTEM_KEY}/getLocation", headers=HEADERS) as resp:
async with _session.post(
f"{REST_URL}/code/{CLEAR_BLADE_SYSTEM_KEY}/getLocation", headers=HEADERS
) as resp:
if resp.status == 200:
_json = await resp.json()
_LOGGER.debug(_json)
Expand All @@ -178,8 +210,9 @@ async def get_dynamic_action(self, payload: Dict) -> Dict:
_session = ClientSession()
try:
async with _session.post(
f"{REST_URL}/code/{CLEAR_BLADE_SYSTEM_KEY}/dynamicAction", json=payload,
headers=HEADERS
f"{REST_URL}/code/{CLEAR_BLADE_SYSTEM_KEY}/dynamicAction",
json=payload,
headers=HEADERS,
) as resp:
if resp.status == 200:
_json = await resp.json()
Expand All @@ -198,7 +231,9 @@ async def get_dynamic_action(self, payload: Dict) -> Dict:
async def _authenticate(self, payload: dict) -> None:

_session = ClientSession()
async with _session.post(f"{REST_URL}/user/auth", json=payload, headers=HEADERS) as resp:
async with _session.post(
f"{REST_URL}/user/auth", json=payload, headers=HEADERS
) as resp:
if resp.status == 200:
_json = await resp.json()
_LOGGER.debug(_json)
Expand Down Expand Up @@ -241,8 +276,11 @@ def _on_message(self, client, userdata, msg):
# Don't break after update for multi zone HVAC systems
_equipment.update_equipment_info(unpacked_json)
else:
_LOGGER.debug("Received update for non-existent equipment with device name: %s and serial number %s",
_name, _serial)
_LOGGER.debug(
"Received update for non-existent equipment with device name: %s and serial number %s",
_name,
_serial,
)
except Exception as e:
_LOGGER.exception(e)
_LOGGER.error("Failed to parse MQTT message: %s", msg.payload)
22 changes: 17 additions & 5 deletions src/pyeconet/equipment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,38 @@ def update_equipment_info(self, update: dict):
if update.get("device_name") == self.device_id:
for key, value in update.items():
if key[0] == "@":
_LOGGER.debug("Before update %s : %s", key, self._equipment_info.get(key))
_LOGGER.debug(
"Before update %s : %s", key, self._equipment_info.get(key)
)
try:
if isinstance(value, Dict):
for _key, _value in value.items():
self._equipment_info[key][_key] = _value
_LOGGER.debug("Updating [%s][%s] = %s", key, _key, _value)
_LOGGER.debug(
"Updating [%s][%s] = %s", key, _key, _value
)
else:
if isinstance(self._equipment_info.get(key), Dict):
if self._equipment_info[key].get("value") is not None:
self._equipment_info[key]["value"] = value
_LOGGER.debug("Updating [%s][value] = %s", key, value)
_LOGGER.debug(
"Updating [%s][value] = %s", key, value
)
else:
self._equipment_info[key] = value
_LOGGER.debug("Updating [%s] = %s", key, value)
except Exception:
_LOGGER.error("Failed to update with message: %s", update)
_LOGGER.debug("After update %s : %s", key, self._equipment_info.get(key))
_LOGGER.debug(
"After update %s : %s", key, self._equipment_info.get(key)
)
_set = True
else:
_LOGGER.debug("Not updating field because it isn't editable: %s, %s", key, value)
_LOGGER.debug(
"Not updating field because it isn't editable: %s, %s",
key,
value,
)
pass

else:
Expand Down
Loading

0 comments on commit 3094d08

Please sign in to comment.