| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- """API Placeholder.
- You should create your api seperately and have it hosted on PYPI. This is included here for the sole purpose
- of making this example code executable.
- """
- from copy import deepcopy
- import logging
- from typing import Any
- import requests
- _LOGGER = logging.getLogger(__name__)
- MOCK_DATA = [
- {
- "device_id": 1,
- "device_type": "SOCKET",
- "device_name": "Lounge Socket 1",
- "device_uid": "0123-4567-8910-1112",
- "software_version": "2.13",
- "state": "ON",
- "voltage": 239,
- "current": 1.2,
- "energy_delivered": 3247,
- "last_reboot": "2024-01-01T10:04:23Z",
- },
- {
- "device_id": 2,
- "device_type": "SOCKET",
- "device_name": "Lounge Socket 2",
- "device_uid": "0123-4567-8910-3723",
- "software_version": "2.13",
- "state": "ON",
- "voltage": 237,
- "current": 0.1,
- "energy_delivered": 634,
- "last_reboot": "2024-03-12T17:33:01Z",
- },
- {
- "device_id": 3,
- "device_type": "ON_OFF_LIGHT",
- "device_name": "Lounge Light",
- "device_uid": "0123-4567-8910-4621",
- "software_version": "1.30",
- "state": "ON",
- "voltage": 237,
- "current": 0.2,
- "off_timer": "00:00",
- "last_reboot": "2023-11-11T09:03:01Z",
- },
- {
- "device_id": 4,
- "device_type": "DIMMABLE_LIGHT",
- "device_name": "Kitchen Light",
- "device_uid": "0123-4967-8940-4691",
- "software_version": "1.35",
- "state": "ON",
- "brightness": 85,
- "voltage": 237,
- "current": 1.275,
- "off_timer": "00:00",
- "last_reboot": "2023-11-11T09:03:01Z",
- },
- {
- "device_id": 5,
- "device_type": "TEMP_SENSOR",
- "device_name": "Kitchen Temp Sensor",
- "device_uid": "0123-4567-8910-9254",
- "software_version": "3.00",
- "temperature": 18.3,
- "last_reboot": "2024-05-02T19:46:00Z",
- },
- {
- "device_id": 6,
- "device_type": "TEMP_SENSOR",
- "device_name": "Lounge Temp Sensor",
- "device_uid": "0123-4567-8910-9255",
- "software_version": "1.30",
- "temperature": 19.2,
- "last_reboot": "2024-03-12T17:33:01Z",
- },
- {
- "device_id": 7,
- "device_type": "CONTACT_SENSOR",
- "device_name": "Kitchen Door Sensor",
- "device_uid": "0123-4567-8911-6295",
- "software_version": "1.41",
- "state": "OPEN",
- },
- {
- "device_id": 8,
- "device_type": "CONTACT_SENSOR",
- "device_name": "Lounge Door Sensor",
- "device_uid": "0123-4567-8911-1753",
- "software_version": "1.41",
- "state": "CLOSED",
- },
- {
- "device_id": 9,
- "device_type": "FAN",
- "device_name": "Lounge Fan",
- "device_uid": "0123-4599-1541-1793",
- "software_version": "2.11",
- "state": "ON",
- "oscillating": "OFF",
- "speed": 2,
- },
- ]
- class API:
- """Class for example API."""
- def __init__(self, host: str, user: str, pwd: str, mock: bool = False) -> None:
- """Initialise."""
- self.host = host
- self.user = user
- self.pwd = pwd
- # For getting and setting the mock data
- self.mock = mock
- self.mock_data = deepcopy(MOCK_DATA)
- # Mock auth error if user != test and pwd != 1234
- if mock and (self.user != "test" or self.pwd != "1234"):
- raise APIAuthError("Invalid credentials!")
- def get_data(self) -> list[dict[str, Any]]:
- """Get api data."""
- if self.mock:
- return self.get_mock_data()
- try:
- r = requests.get(f"http://{self.host}/api", timeout=10)
- return r.json()
- except requests.exceptions.ConnectTimeout as err:
- raise APIConnectionError("Timeout connecting to api") from err
- def set_data(self, device_id: int, parameter: str, value: Any) -> bool:
- """Set api data."""
- if self.mock:
- return self.set_mock_data(device_id, parameter, value)
- try:
- data = {parameter, value}
- r = requests.post(
- f"http://{self.host}/api/{device_id}", json=data, timeout=10
- )
- except requests.exceptions.ConnectTimeout as err:
- raise APIConnectionError("Timeout connecting to api") from err
- else:
- return r.status_code == 200
- # ----------------------------------------------------------------------------
- # The below methods are used to mimic a real api for the example that changes
- # its values based on commands from the switches and lights and obvioulsy will
- # not be needed wiht your real api.
- # ----------------------------------------------------------------------------
- def get_mock_data(self) -> dict[str, Any]:
- """Get mock api data."""
- return self.mock_data
- def set_mock_data(self, device_id: int, parameter: str, value: Any) -> bool:
- """Update mock data."""
- try:
- device = [
- devices
- for devices in self.mock_data
- if devices.get("device_id") == device_id
- ][0]
- except IndexError:
- # Device id does not exist
- return False
- other_devices = [
- devices
- for devices in self.mock_data
- if devices.get("device_id") != device_id
- ]
- # Modify device parameter
- if device.get(parameter):
- device[parameter] = value
- else:
- # Parameter does not exist on device
- return False
- # For sockets and lights, modify current values when off/on to mimic
- # real api and show changing sensors from your actions.
- if device["device_type"] in ["SOCKET", "ON_OFF_LIGHT", "DIMMABLE_LIGHT"]:
- if value == "OFF":
- device["current"] = 0
- else:
- original_device = [
- devices
- for devices in MOCK_DATA
- if devices.get("device_id") == device_id
- ][0]
- device["current"] = original_device.get("current")
- # For dimmable lights if brightness is set to > 0, set to on
- if device["device_type"] == "DIMMABLE_LIGHT":
- if parameter == "brightness":
- if value > 0:
- device["state"] = "ON"
- device["current"] = value * 0.015
- else:
- device["state"] = "OFF"
- if parameter == "state":
- if value == "ON":
- device["brightness"] = 100
- else:
- device["brightness"] = 0
- _LOGGER.debug("Device Updated: %s", device)
- # Update mock data
- self.mock_data = other_devices
- self.mock_data.append(device)
- return True
- class APIAuthError(Exception):
- """Exception class for auth error."""
- class APIConnectionError(Exception):
- """Exception class for connection error."""
|