Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

New device and entity architecture #8

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 45 additions & 2 deletions custom_components/homee/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import Entity

from pymee import Homee
from pymee import model
from pymee.model import HomeeAttribute, HomeeNode
import voluptuous as vol

from .const import (
ATTR_ATTRIBUTE,
ATTR_NODE,
ATTR_VALUE,
BRAIN_CUBE,
CONF_ADD_HOME_DATA,
CONF_INITIAL_OPTIONS,
DOMAIN,
NodeProfileNames,
SERVICE_SET_VALUE,
UNKNOWN_MODEL,
)

_LOGGER = logging.getLogger(DOMAIN)
Expand Down Expand Up @@ -63,8 +69,24 @@ def handle_set_value(call: ServiceCall):

hass.async_create_task(homee.set_value(node, attribute, value))

# Register services
hass.services.async_register(DOMAIN, SERVICE_SET_VALUE, handle_set_value)

# Register homee device
# TODO: Add homee cube device using entities
# BODY: homee cube device should be added using `device_info` on homee cube related entities.
device_registry = await dr.async_get_registry(hass)

device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, homee.host)},
identifiers={(DOMAIN, homee.settings.uid)},
manufacturer="homee GmbH",
name=f"{homee.settings.homee_name} Cube",
sw_version=homee.settings.cubes[0]["firmware"],
model=BRAIN_CUBE,
)

# Forward entry setup to the platforms
for component in PLATFORMS:
hass.async_create_task(
Expand Down Expand Up @@ -157,12 +179,12 @@ def _on_node_updated(self, node: HomeeNode, attribute: HomeeAttribute):
class HomeeNodeEntity:
def __init__(self, node: HomeeNode, entity: Entity, entry: ConfigEntry) -> None:
"""Initialize the wrapper using a HomeeNode and target entity."""
self._node = node
self._node: HomeeNode = node
self._entity = entity
self._clear_node_listener = None
self._unique_id = node.id
self._entry = entry

self._homee: Homee = None
self._homee_data = {
"id": node.id,
"name": node.name,
Expand All @@ -173,6 +195,7 @@ def __init__(self, node: HomeeNode, entity: Entity, entry: ConfigEntry) -> None:
async def async_added_to_hass(self) -> None:
"""Add the homee binary sensor device to home assistant."""
self.register_listener()
self._homee = self._entity.hass.data[DOMAIN][self._entry.entry_id]

async def async_will_remove_from_hass(self):
"""Cleanup the entity."""
Expand All @@ -193,6 +216,26 @@ def name(self):
"""Return the display name of this entity."""
return self._node.name

@property
def device_info(self):
"""Return the info about the associated homee device."""

# entity.hass is only defined after the entity has been added
# however, device_info is called before async_added_to_hass
self._homee = self._entity.hass.data[DOMAIN][self._entry.entry_id]

info = {
"identifiers": {
# Serial numbers are unique identifiers within a specific domain
(DOMAIN, self._homee.settings.uid, self.unique_id)
},
"name": self._node.name,
"model": NodeProfileNames.get(self._node.profile, UNKNOWN_MODEL),
"via_device": (DOMAIN, self._homee.settings.uid),
}

return info

@property
def raw_data(self):
"""Return the raw data of the node."""
Expand Down
140 changes: 140 additions & 0 deletions custom_components/homee/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
# General
DOMAIN = "homee"

# Cubes
BRAIN_CUBE = "Brain Cube"
ZWAVE_CUBE = "Z-Wave Cube"
ZIGBEE_CUBE = "Zigbee Cube"
ENOCEAN_CUBE = "EnOcean Cube"


# Services
SERVICE_SET_VALUE = "set_value"

Expand All @@ -20,3 +27,136 @@
CONF_GROUPS = "groups"
CONF_WINDOW_GROUPS = "window_groups"
CONF_DOOR_GROUPS = "door_groups"

# Other
UNKNOWN_MANUFACTURER = "-"
UNKNOWN_MODEL = "-"

# TODO: Move NodeProfileNames to pymee
NodeProfileNames = {
0: "None",
1: "Homee",
10: "On Off Plug",
11: "Dimmable Metering Switch",
12: "Metering Switch",
13: "Metering Plug",
14: "Dimmable Plug",
15: "Dimmable Switch",
16: "On Off Switch",
18: "Double On Off Switch",
19: "Dimmable Metering Plug",
20: "One Button Remote",
21: "Binary Input",
22: "Dimmable Color Metering Plug",
23: "Double Binary Input",
24: "Two Button Remote",
25: "Three Button Remote",
26: "Four Button Remote",
27: "Alarm Sensor",
28: "Double On Off Plug",
29: "On Off Switch With Binary Input",
30: "Watch Dog With Pressure And Temperatures",
31: "Fibaro Button",
32: "Energy Meter",
33: "Double Metering Switch",
34: "Fibaro Swipe",
38: "Energy Manager",
39: "Level Meter",
40: "Range Extender",
41: "Remote",
42: "Impulse Plug",
43: "Impulse Relay",
1e3: "Brightness Sensor",
1001: "Dimmable Color Light",
1002: "Dimmable Extended Color Light",
1003: "Dimmable Color Temperature Light",
1004: "Dimmable Light",
1005: "Dimmable Light With Brightness Sensor",
1006: "Dimmable Light With Brightness And Presence Sensor",
1007: "Dimmable Light With Presence Sensor",
1008: "Dimmable Rgbwlight",
2e3: "Open Close Sensor",
2001: "Window Handle",
2002: "Shutter Position Switch",
2003: "Open Close And Temperature Sensor",
2004: "Electric Motor Metering Switch",
2005: "Open Close With Temperature And Brightness Sensor",
2006: "Electric Motor Metering Switch Without Slat Position",
2007: "Lock",
2008: "Window Handle With Buttons",
2009: "Window Handle With Buttons And Temperature And Humidity Sensor",
2010: "Entrance Gate Operator",
2011: "Perimeter Protection System",
2012: "Garage Door Operator",
2013: "Gate Operator",
2014: "Inner Door Operator",
2015: "Garage Door Impulse Operator",
3001: "Temperature And Humidity Sensor",
3002: "Co2sensor",
3003: "Room Thermostat",
3004: "Room Thermostat With Humidity Sensor",
3005: "Binary Input With Temperature Sensor",
3006: "Radiator Thermostat",
3009: "Temperature Sensor",
3010: "Humidity Sensor",
3011: "Water Valve",
3012: "Water Meter",
3013: "Weather Station",
3014: "Netatmo Main Module",
3015: "Netatmo Outdoor Module",
3016: "Netatmo Indoor Module",
3017: "Netatmo Rain Module",
3018: "Cosi Therm Channel",
3019: "Ventilation Control",
3022: "Thermostat With Heating And Cooling",
3023: "Netatmo Wind Module",
3024: "Electrical Heating",
3025: "Valve Drive",
3026: "Camera",
3027: "Camera With Floodlight",
3028: "Heating System",
3029: "Warm Water Circuit",
3030: "Heating Circuit",
4010: "Motion Detector With Temperature Brightness And Humidity Sensor",
4011: "Motion Detector",
4012: "Smoke Detector",
4013: "Flood Detector",
4014: "Presence Detector",
4015: "Motion Detector With Temperature And Brightness Sensor",
4016: "Smoke Detector With Temperature Sensor",
4017: "Flood Detector With Temperature Sensor",
4018: "Watch Dog Device",
4019: "Lag",
4020: "Owu",
4021: "Eurovac",
4022: "Owwg3",
4023: "Europress",
4024: "Minimum Detector",
4025: "Maximum Detector",
4026: "Smoke Detector And Codetector",
4027: "Siren",
4028: "Motion Detector With Open Close Temperature And Brightness Sensor",
4029: "Motion Detector With Brightness",
4030: "Doorbell",
4031: "Smoke Detector And Siren",
4032: "Flood Detector With Temperature And Humidity Sensor",
4033: "Minimum Detector With Temperature Sensor",
4034: "Maximum Detector With Temperature Sensor",
4035: "Presence Detector With Temperature And Brightness Sensor",
4036: "Codetector",
5e3: "Inova Alarm System",
5001: "Inova Detector",
5002: "Inova Siren",
5003: "Inova Command",
5004: "Inova Transmitter",
5005: "Inova Reciever",
5006: "Inova Koala",
5007: "Inova Internal Transmitter",
5008: "Inova Control Panel",
5009: "Inova Input Output Extension",
5010: "Inova Motion Detector With Vod",
5011: "Inova Motion Detector",
6e3: "Washing Machine",
6001: "Tumble Dryer",
6002: "Dishwasher",
}