diff --git a/CHANGELOG.md b/CHANGELOG.md
index c1609ca..14894e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -176,4 +176,11 @@ Thank for @pblxptr add new code line from him
**Full Changelog**: [https://github.com/jontofront/ecoNET-300-Home-Assistant-Integration/compare/v0.3.3...v1.0.5](https://github.com/jontofront/ecoNET-300-Home-Assistant-Integration/compare/v0.3.3...v1.0.5)
-## [v1.0.5]
\ No newline at end of file
+## [v1.0.11]
+
+Additions and Updates to Sensors:
+Added boilerPowerKW as a new sensor type in custom_components/econet300/const.py and updated its unit, device class, and icon. [1] [2] [3] [4] [5]
+Added feederWorks as a new binary sensor in custom_components/econet300/const.py and updated its icon. [1] [2] [3]
+Updates to Existing Sensors:
+Renamed the lighter sensor to lighterWorks in custom_components/econet300/const.py and updated its icon. [1] [2]
+Updated the names of the lighter, boilerPower, and feeder sensors in custom_components/econet300/strings.json and custom_components/econet300/translations/en.json. [1] [2] [3] [4] [5] [6]
\ No newline at end of file
diff --git a/README.md b/README.md
index 2abadc1..6e28acf 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,22 @@ he **ecoNET300 Home Assistant Integration** allows local control and monitoring
- **Easy Configuration**: Integrate directly via Home Assistant UI.
- **Tested With**: ecoMAX810P-L TOUCH controller from [Plum Sp. z o.o.](https://www.plum.pl/)
+## Table of Contents
+1. [ecoNET300 Home Assistant Integration](#econet300-home-assistant-integration)
+2. [Overview](#overview)
+3. [Versions](#versions)
+ - [Migrating to v1.0.0_beta](#migrating-to-v100_beta)
+4. [Example](#example)
+5. [Installation](#installation)
+ - [HACS (Recommended)](#hacs-recommended)
+ - [Manual Installation](#manual-installation)
+6. [Configuration](#configuration)
+7. [Entities](#entities)
+ - [Sensors](#sensors)
+ - [Binary Sensors](#binary-sensors)
+8. [Contributing](#contributing)
+9. [Acknowledgments](#acknowledgments)
+10. [Disclaimer](#disclaimer)
## versions
* v0.3.3 - version is stable. Most of the work was done by @pblxpt, for which we're very thankful as the community.
@@ -103,36 +119,72 @@ __Password__: Local password (NOT the password that you use to login to econet24
## Entities
+
### Sensors
-These sensors are retrieved from the `../econet/regParams` endpoint. Below is the list of available entity keys and their descriptions:
+These sensors are retrieved from the `../econet/regParams` and `../econet/sysParams` endpoints. Below is the list of available entity keys, their descriptions, and the corresponding API endpoint keys:
+
+ **馃憠 Click here to expand the table**
+
+
+| Entity Key | Description | Endpoint |
+|----------------------|-----------------------------------------------------------|-----------------------|
+| `tempFeeder` | Temperature of the feeder mechanism | `../econet/regParams` |
+| `fuelLevel` | Current fuel level in the system | `../econet/regParams` |
+| `tempCO` | Current fireplace temperature | `../econet/regParams` |
+| `tempCOSet` | Desired fireplace set temperature | `../econet/regParams` |
+| `statusCWU` | Status of the hot water (CWU) system | `../econet/regParams` |
+| `tempCWU` | Current hot water (CWU) temperature | `../econet/regParams` |
+| `tempCWUSet` | Desired hot water (CWU) temperature | `../econet/regParams` |
+| `tempFlueGas` | Exhaust temperature reading | `../econet/regParams` |
+| `mode` | Current operational mode of the device | `../econet/regParams` |
+| `fanPower` | Current fan power usage | `../econet/regParams` |
+| `thermostat` | Thermostat status or set temperature | `../econet/regParams` |
+| `tempExternalSensor` | Outside (external) temperature | `../econet/regParams` |
+| `tempLowerBuffer` | Temperature of the lower thermal buffer | `../econet/regParams` |
+| `tempUpperBuffer` | Temperature of the upper thermal buffer | `../econet/regParams` |
+| `boilerPower` | Current power output of the boiler | `../econet/regParams` |
+| `quality` | Fuel quality or system quality indicator (if applicable) | `../econet/sysParams` |
+| `signal` | Signal strength or communication status | `../econet/sysParams` |
+| `softVer` | Software version of the controller | `../econet/sysParams` |
+| `controllerID` | Unique identifier for the controller | `../econet/sysParams` |
+| `moduleASoftVer` | Software version of Module A | `../econet/sysParams` |
+| `moduleBSoftVer` | Software version of Module B | `../econet/sysParams` |
+| `moduleCSoftVer` | Software version of Module C | `../econet/sysParams` |
+| `moduleLambdaSoftVer`| Software version of the lambda module | `../econet/sysParams` |
+| `modulePanelSoftVer` | Software version of the control panel | `../econet/sysParams` |
+
+
+### Binary Sensors
-| sensor Key | Description |
-|----------------------|------------------------------------------|
-| `tempFeeder` | Temperature of the feeder mechanism |
-| `fuelLevel` | Current fuel level in the system |
-| `tempCO` | Current fireplace temperature |
-| `tempCOSet` | Desired fireplace set temperature |
-| `statusCWU` | Status of the hot water (CWU) system |
-| `tempCWUSet` | Desired hot water (CWU) temperature |
-| `tempFlueGas` | Exhaust temperature reading |
-| `mode` | Current operational mode of the device |
-| `fanPower` | Current fan power usage |
-| `thermostat` | Thermostat status or set temperature |
-| `tempExternalSensor` | Outside (external) temperature |
+These binary sensors are retrieved from the `../econet/regParams` and `../econet/sysParams` endpoints. Below is the list of available entity keys, their descriptions, and the corresponding API endpoint keys:
+
+ **馃憠 Click here to expand the table**
+
+| Entity Key | Description | Endpoint |
+|----------------------|--------------------------------------------------|-----------------------|
+| `lighter` | Indicates if the lighter is active | `../econet/regParams` |
+| `pumpCOWorks` | Indicates if the fireplace pump is working | `../econet/regParams` |
+| `fanWorks` | Indicates if the fan is currently active | `../econet/regParams` |
+| `pumpFireplaceWorks` | Indicates if the fireplace pump is working | `../econet/regParams` |
+| `pumpCWUWorks` | Indicates if the hot water (CWU) pump is active | `../econet/regParams` |
+| `mainSrv` | Indicates if the main server is operational | `../econet/sysParams` |
+| `wifi` | Indicates if the Wi-Fi connection is active | `../econet/sysParams` |
+| `lan` | Indicates if the LAN connection is active | `../econet/sysParams` |
+
+### Number Entities
-### Binary Sensors
+These number entities are retrieved from the `../econet/rmCurrentDataParamsEdits` endpoint. Below is the list of available entity keys, their descriptions, and the corresponding API endpoint keys:
-These binary sensors are retrieved from the `../econet/regParams` endpoint. Below is the list of available entity keys and their descriptions:
-| Entity Key | Description |
-|----------------------|---------------------------------------------|
-| `lighter` | Indicates if the lighter is active |
-| `pumpCOWorks` | Indicates if the fireplace pump is working |
-| `fanWorks` | Indicates if the fan is currently active |
-| `pumpFireplaceWorks` | Indicates if the fireplace pump is working |
-| `pumpCWUWorks` | Indicates if the hot water (CWU) pump is active |
+
+ **馃憠 Click here to expand the table**
+| Entity Key | Description | Endpoint |
+|----------------------|----------------------------------------------|--------------------------------------|
+| `tempCOSet` | Desired fireplace set temperature | `../econet/rmCurrentDataParamsEdits` |
+| `tempCWUSet` | Desired hot water (CWU) set temperature | `../econet/rmCurrentDataParamsEdits` |
+
## Contributing
diff --git a/custom_components/econet300/binary_sensor.py b/custom_components/econet300/binary_sensor.py
index 35ae0e0..819da5e 100644
--- a/custom_components/econet300/binary_sensor.py
+++ b/custom_components/econet300/binary_sensor.py
@@ -4,6 +4,7 @@
import logging
from homeassistant.components.binary_sensor import (
+ BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
@@ -84,7 +85,9 @@ def create_binary_entity_description(key: str) -> EconetBinarySensorEntityDescri
entity_description = EconetBinarySensorEntityDescription(
key=key,
translation_key=camel_to_snake(key),
- device_class=ENTITY_BINARY_DEVICE_CLASS_MAP.get(key, None),
+ device_class=ENTITY_BINARY_DEVICE_CLASS_MAP.get(
+ key, BinarySensorDeviceClass.RUNNING
+ ),
icon=ENTITY_ICON.get(key, None),
icon_off=ENTITY_ICON_OFF.get(key, None),
)
@@ -95,20 +98,31 @@ def create_binary_entity_description(key: str) -> EconetBinarySensorEntityDescri
def create_binary_sensors(coordinator: EconetDataCoordinator, api: Econet300Api):
"""Create binary sensors."""
entities: list[EconetBinarySensor] = []
- coordinator_data = coordinator.data["regParams"]
+ data_regParams = coordinator.data.get("regParams", {})
+ data_sysParams = coordinator.data.get("sysParams", {})
+
for data_key in BINARY_SENSOR_MAP_KEY["_default"]:
- _LOGGER.debug("Processing binary sensor data_key: %s", data_key)
- if data_key in coordinator_data:
+ _LOGGER.debug(
+ "Processing binary sensor data_key: %s from regParams & sysParams", data_key
+ )
+ if data_key in data_regParams:
+ entity = EconetBinarySensor(
+ create_binary_entity_description(data_key), coordinator, api
+ )
+ entities.append(entity)
+ _LOGGER.debug("Created and appended entity from regParams: %s", entity)
+ elif data_key in data_sysParams:
entity = EconetBinarySensor(
create_binary_entity_description(data_key), coordinator, api
)
entities.append(entity)
- _LOGGER.debug("Created and appended entity: %s", entity)
+ _LOGGER.debug("Created and appended entity from sysParams: %s", entity)
else:
_LOGGER.warning(
- "key: %s is not mapped, binary sensor entity will not be added",
+ "key: %s is not mapped in regParams, binary sensor entity will not be added",
data_key,
)
+ _LOGGER.info("Total entities created: %d", len(entities))
return entities
diff --git a/custom_components/econet300/common.py b/custom_components/econet300/common.py
index 2679d31..6ff15ca 100644
--- a/custom_components/econet300/common.py
+++ b/custom_components/econet300/common.py
@@ -60,7 +60,7 @@ async def _async_update_data(self):
try:
# Note: asyncio.TimeoutError and aiohttp.ClientError are already
# handled by the data update coordinator.
- async with asyncio.timeout(10):
+ async with asyncio.timeout(20):
data = await self._api.fetch_sys_params()
reg_params = await self._api.fetch_reg_params()
params_edits = await self._api.fetch_param_edit_data()
diff --git a/custom_components/econet300/const.py b/custom_components/econet300/const.py
index 9e574e0..ef0dab0 100644
--- a/custom_components/econet300/const.py
+++ b/custom_components/econet300/const.py
@@ -11,6 +11,7 @@
STATE_PROBLEM,
STATE_UNKNOWN,
EntityCategory,
+ UnitOfPower,
UnitOfTemperature,
UnitOfTime,
)
@@ -25,6 +26,7 @@
DEVICE_INFO_MODEL = "ecoNET300"
DEVICE_INFO_CONTROLLER_NAME = "PLUM ecoNET300"
DEVICE_INFO_MIXER_NAME = "Mixer device"
+DEVICE_INFO_LAMBDA_NAME = "Module Lambda"
CONF_ENTRY_TITLE = "ecoNET300"
CONF_ENTRY_DESCRIPTION = "PLUM Econet300"
@@ -44,14 +46,7 @@
API_REG_PARAMS_DATA_URI = "regParamsData"
API_REG_PARAMS_DATA_PARAM_DATA = "data"
-## Map names for params data in API_REG_PARAMS_DATA_URI
-API_RM_CURRENT_DATA_PARAMS_URI = "rmCurrentDataParams"
-
-## Map units for params data map API_RM_CURRENT_DATA_PARAMS_URI
-API_RM_PARAMSUNITSNAMES_URI = "rmParamsUnitsNames"
-
# Boiler status keys map
-# boiler mode names from endpoint http://LocalIP/econet/rmParamsEnums?
OPERATION_MODE_NAMES = {
0: STATE_OFF,
1: "fire_up",
@@ -83,7 +78,7 @@
# Dynamically generate SENSOR_MIXER_KEY
SENSOR_MIXER_KEY = {
- str(i): {f"{MIXER_AVAILABILITY_KEY}{i}", f"{MIXER_SET_AVAILABILITY_KEY}{i}"}
+ i: {f"{MIXER_AVAILABILITY_KEY}{i}", f"{MIXER_SET_AVAILABILITY_KEY}{i}"}
for i in range(1, AVAILABLE_NUMBER_OF_MIXERS + 1)
}
@@ -102,27 +97,45 @@
"lambdaLevel",
},
"_default": {
+ "boilerPower",
+ "boilerPowerKW",
"tempFeeder",
"fuelLevel",
"tempCO",
"tempCOSet",
"statusCWU",
+ "tempCWU",
"tempCWUSet",
"tempFlueGas",
"mode",
"fanPower",
"thermostat",
"tempExternalSensor",
+ "tempLowerBuffer",
+ "tempUpperBuffer",
+ "quality",
+ "signal",
+ "softVer",
+ "controllerID",
+ "moduleASoftVer",
+ "moduleBSoftVer",
+ "moduleCSoftVer",
+ "moduleLambdaSoftVer",
+ "modulePanelSoftVer",
},
}
BINARY_SENSOR_MAP_KEY = {
"_default": {
- "lighter",
+ "lighterWorks",
"pumpCOWorks",
"fanWorks",
+ "feederWorks",
"pumpFireplaceWorks",
"pumpCWUWorks",
+ "mainSrv",
+ "wifi",
+ "lan",
},
}
@@ -131,6 +144,7 @@
"1281": "tempCWUSet",
}
+# By default all sensors unit_of_measurement are None
ENTITY_UNIT_MAP = {
"tempCO": UnitOfTemperature.CELSIUS,
"tempCOSet": UnitOfTemperature.CELSIUS,
@@ -143,7 +157,6 @@
"workAt50": UnitOfTime.HOURS,
"workAt30": UnitOfTime.HOURS,
"FeederWork": UnitOfTime.HOURS,
- "FiringUpCount": None,
"thermoTemp": UnitOfTemperature.CELSIUS,
"fanPower": PERCENTAGE,
"tempFlueGas": UnitOfTemperature.CELSIUS,
@@ -152,6 +165,7 @@
"tempBack": UnitOfTemperature.CELSIUS,
"tempCWU": UnitOfTemperature.CELSIUS,
"boilerPower": PERCENTAGE,
+ "boilerPowerKW": UnitOfPower.KILO_WATT,
"fuelLevel": PERCENTAGE,
"tempUpperBuffer": UnitOfTemperature.CELSIUS,
"tempLowerBuffer": UnitOfTemperature.CELSIUS,
@@ -163,36 +177,22 @@
"mixerSetTemp": UnitOfTemperature.CELSIUS,
}
-STATE_CLASS_MAP: dict[str, SensorStateClass] = {
- "tempFeeder": SensorStateClass.MEASUREMENT,
- "tempExternalSensor": SensorStateClass.MEASUREMENT,
- "lambdaSet": SensorStateClass.MEASUREMENT,
- "lambdaLevel": SensorStateClass.MEASUREMENT,
- "workAt100": SensorStateClass.MEASUREMENT,
- "workAt50": SensorStateClass.MEASUREMENT,
- "workAt30": SensorStateClass.MEASUREMENT,
- "FeederWork": SensorStateClass.MEASUREMENT,
- "FiringUpCount": SensorStateClass.MEASUREMENT,
- "tempCO": SensorStateClass.MEASUREMENT,
- "tempCOSet": SensorStateClass.MEASUREMENT,
- "tempCWUSet": SensorStateClass.MEASUREMENT,
- "boiler_power": SensorStateClass.MEASUREMENT,
- "fanPower": SensorStateClass.MEASUREMENT,
- "tempFlueGas": SensorStateClass.MEASUREMENT,
- "mixerSetTemp1": SensorStateClass.MEASUREMENT,
- "tempBack": SensorStateClass.MEASUREMENT,
- "tempCWU": SensorStateClass.MEASUREMENT,
- "fuelLevel": SensorStateClass.MEASUREMENT,
- "tempUpperBuffer": SensorStateClass.MEASUREMENT,
- "tempLowerBuffer": SensorStateClass.MEASUREMENT,
- "signal": SensorStateClass.MEASUREMENT,
- "quality": SensorStateClass.MEASUREMENT,
- "valveMixer1": SensorStateClass.MEASUREMENT,
- "burnerOutput": SensorStateClass.MEASUREMENT,
- "mixerTemp": SensorStateClass.MEASUREMENT,
- "mixerSetTemp": SensorStateClass.MEASUREMENT,
+# By default all sensors state_class are MEASUREMENT
+STATE_CLASS_MAP: dict[str, SensorStateClass | None] = {
+ "lambdaStatus": None,
+ "mode": None,
+ "thermostat": None,
+ "statusCWU": None,
+ "softVer": None,
+ "controllerID": None,
+ "moduleASoftVer": None,
+ "moduleBSoftVer": None,
+ "moduleCSoftVer": None,
+ "moduleLambdaSoftVer": None,
+ "modulePanelSoftVer": None,
}
+# By default all sensors device_class are None
ENTITY_SENSOR_DEVICE_CLASS_MAP: dict[str, SensorDeviceClass | None] = {
#############################
# SENSORS
@@ -201,6 +201,7 @@
"tempExternalSensor": SensorDeviceClass.TEMPERATURE,
"tempCO": SensorDeviceClass.TEMPERATURE,
"boilerPower": SensorDeviceClass.POWER_FACTOR,
+ "boilerPowerKW": SensorDeviceClass.POWER,
"fanPower": SensorDeviceClass.POWER_FACTOR,
"tempFlueGas": SensorDeviceClass.TEMPERATURE,
"mixerSetTemp1": SensorDeviceClass.TEMPERATURE,
@@ -212,17 +213,7 @@
"tempUpperBuffer": SensorDeviceClass.TEMPERATURE,
"tempLowerBuffer": SensorDeviceClass.TEMPERATURE,
"signal": SensorDeviceClass.SIGNAL_STRENGTH,
- "softVer": None,
- "moduleASoftVer": None,
- "moduleBSoftVer": None,
- "modulePanelSoftVer": None,
- "moduleLambdaSoftVer": None,
- "protocolType": None,
- "controllerID": None,
- "valveMixer1": None,
"servoMixer1": SensorDeviceClass.ENUM,
- "Status_wifi": None,
- "main_server": None,
}
ENTITY_NUMBER_SENSOR_DEVICE_CLASS_MAP = {
@@ -238,15 +229,10 @@
#############################
# BINARY SENSORS
#############################
- "lighter": BinarySensorDeviceClass.RUNNING,
- "weatherControl": BinarySensorDeviceClass.RUNNING,
- "unseal": BinarySensorDeviceClass.RUNNING,
- "pumpCOWorks": BinarySensorDeviceClass.RUNNING,
- "fanWorks": BinarySensorDeviceClass.RUNNING,
- "additionalFeeder": BinarySensorDeviceClass.RUNNING,
- "pumpFireplaceWorks": BinarySensorDeviceClass.RUNNING,
- "pumpCWUWorks": BinarySensorDeviceClass.RUNNING,
- "mixerPumpWorks": BinarySensorDeviceClass.RUNNING,
+ # By default all binary sensors device_class are RUNNING
+ "mainSrv": BinarySensorDeviceClass.CONNECTIVITY,
+ "wifi": BinarySensorDeviceClass.CONNECTIVITY,
+ "lan": BinarySensorDeviceClass.CONNECTIVITY,
}
"""Add only keys where precision more than 0 needed"""
@@ -263,25 +249,37 @@
"tempCWU": 1,
"tempFlueGas": 1,
"fanPower": 0,
+ "statusCWU": None,
+ "thermostat": None,
+ "lambdaStatus": None,
+ "mode": None,
+ "softVer": None,
+ "controllerID": None,
+ "moduleASoftVer": None,
+ "moduleBSoftVer": None,
+ "moduleCSoftVer": None,
+ "moduleLambdaSoftVer": None,
+ "modulePanelSoftVer": None,
}
ENTITY_ICON = {
"mode": "mdi:sync",
"fanPower": "mdi:fan",
"temCO": "mdi:thermometer-lines",
- "tempCOSet": "mdi:thermometer-chevron-up",
- "tempCWUSet": "mdi:thermometer-chevron-up",
"statusCWU": "mdi:water-boiler",
"thermostat": "mdi:thermostat",
"boilerPower": "mdi:gauge",
+ "boilerPowerKW": "mdi:gauge",
"fuelLevel": "mdi:gas-station",
"lambdaLevel": "mdi:lambda",
"lambdaSet": "mdi:lambda",
"lambdaStatus": "mdi:lambda",
+ "lighterWorks": "mdi:fire",
"workAt100": "mdi:counter",
"workAt50": "mdi:counter",
"workAt30": "mdi:counter",
"FeederWork": "mdi:counter",
+ "feederWorks": "mdi:screw-lag",
"FiringUpCount": "mdi:counter",
"quality": "mdi:signal",
"pumpCOWorks": "mdi:pump",
@@ -289,14 +287,21 @@
"additionalFeeder": "mdi:screw-lag",
"pumpFireplaceWorks": "mdi:pump",
"pumpCWUWorks": "mdi:pump",
- "main_server": "mdi:server",
"mixerPumpWorks": "mdi:pump",
"mixerTemp": "mdi:thermometer",
"mixerSetTemp": "mdi:thermometer",
"valveMixer1": "mdi:valve",
- "mixerSetTemp1": "mdi:thermometer-chevron-up",
"servoMixer1": "mdi:valve",
"mixerTemp1": "mdi:thermometer",
+ "mainSrv": "mdi:server-network",
+ "lan": "mdi:lan-connect",
+ "softVer": "mdi:alarm-panel-outline",
+ "controllerID": "mdi:alarm-panel-outline",
+ "moduleASoftVer": "mdi:raspberry-pi",
+ "moduleBSoftVer": "mdi:raspberry-pi",
+ "moduleCSoftVer": "mdi:raspberry-pi",
+ "moduleLambdaSoftVer": "mdi:raspberry-pi",
+ "modulePanelSoftVer": "mdi:alarm-panel-outline",
}
ENTITY_ICON_OFF = {
@@ -306,6 +311,9 @@
"pumpFireplaceWorks": "mdi:pump-off",
"pumpCWUWorks": "mdi:pump-off",
"statusCWU": "mdi:water-boiler-off",
+ "mainSrv": "mdi:server-network-off",
+ "lan": "mdi:lan-disconnect",
+ "lighterWorks": "mdi:fire-off",
}
NO_CWU_TEMP_SET_STATUS_CODE = 128
@@ -319,8 +327,6 @@
else ("start" if x == 1 else ("working" if x == 2 else STATE_UNKNOWN))
)
),
- "status_wifi": lambda x: "Connected" if x == 1 else "Disconnected",
- "main_server": lambda x: "Server available" if x == 1 else "Server not available",
"statusCWU": lambda x: "Not set" if x == NO_CWU_TEMP_SET_STATUS_CODE else "Set",
"thermostat": lambda x: "ON" if x == 1 else "OFF",
}
@@ -336,13 +342,10 @@
"moduleLambdaSoftVer": EntityCategory.DIAGNOSTIC,
"protocolType": EntityCategory.DIAGNOSTIC,
"controllerID": EntityCategory.DIAGNOSTIC,
- "status_wifi": EntityCategory.DIAGNOSTIC,
- "main_server": EntityCategory.DIAGNOSTIC,
- "workAt100": EntityCategory.DIAGNOSTIC,
- "workAt50": EntityCategory.DIAGNOSTIC,
- "workAt30": EntityCategory.DIAGNOSTIC,
- "FeederWork": EntityCategory.DIAGNOSTIC,
- "FiringUpCount": EntityCategory.DIAGNOSTIC,
+ "moduleCSoftVer": EntityCategory.DIAGNOSTIC,
+ "mainSrv": EntityCategory.DIAGNOSTIC,
+ "wifi": EntityCategory.DIAGNOSTIC,
+ "lan": EntityCategory.DIAGNOSTIC,
}
ENTITY_MIN_VALUE = {
@@ -359,8 +362,3 @@
"tempCOSet": 1,
"tempCWUSet": 1,
}
-
-ENTITY_VISIBLE = {
- "tempCOSet": True,
- "tempCWUSet": True,
-}
diff --git a/custom_components/econet300/entity.py b/custom_components/econet300/entity.py
index 6beb722..acbaa69 100644
--- a/custom_components/econet300/entity.py
+++ b/custom_components/econet300/entity.py
@@ -10,6 +10,7 @@
from .common import EconetDataCoordinator
from .const import (
DEVICE_INFO_CONTROLLER_NAME,
+ DEVICE_INFO_LAMBDA_NAME,
DEVICE_INFO_MANUFACTURER,
DEVICE_INFO_MIXER_NAME,
DEVICE_INFO_MODEL,
@@ -79,9 +80,9 @@ async def async_added_to_hass(self):
sys_params = self.coordinator.data.get("sysParams", {})
reg_params = self.coordinator.data.get("regParams", {})
params_edits = self.coordinator.data.get("paramsEdits", {})
- _LOGGER.debug("sysParams: %s", sys_params)
- _LOGGER.debug("regParams: %s", reg_params)
- _LOGGER.debug("paramsEdits: %s", params_edits)
+ _LOGGER.debug("async_sysParams: %s", sys_params)
+ _LOGGER.debug("async_regParams: %s", reg_params)
+ _LOGGER.debug("async_paramsEdits: %s", params_edits)
# Check if the coordinator has a 'data' attributes
if "data" not in dir(self.coordinator):
@@ -155,3 +156,28 @@ def device_info(self) -> DeviceInfo | None:
sw_version=self.api.sw_rev,
via_device=(DOMAIN, self.api.uid),
)
+
+
+class LambdaEntity(EconetEntity):
+ """Represents EcosterEntity."""
+
+ def __init__(
+ self,
+ description: EntityDescription,
+ coordinator: EconetDataCoordinator,
+ api: Econet300Api,
+ ):
+ super().__init__(description, coordinator, api)
+
+ @property
+ def device_info(self) -> DeviceInfo | None:
+ """Return device info of the entity."""
+ return DeviceInfo(
+ identifiers={(DOMAIN, f"{self.api.uid}lambda")},
+ name=f"{DEVICE_INFO_LAMBDA_NAME}",
+ manufacturer=DEVICE_INFO_MANUFACTURER,
+ model=DEVICE_INFO_MODEL,
+ configuration_url=self.api.host,
+ sw_version=self.api.sw_rev,
+ via_device=(DOMAIN, self.api.uid),
+ )
diff --git a/custom_components/econet300/manifest.json b/custom_components/econet300/manifest.json
index 8482bae..65a5076 100644
--- a/custom_components/econet300/manifest.json
+++ b/custom_components/econet300/manifest.json
@@ -12,6 +12,6 @@
"issue_tracker": "https://github.com/jontofront/ecoNET-300-Home-Assistant-Integration/issues",
"requirements": [],
"ssdp": [],
- "version": "v1.0.6",
+ "version": "v1.0.11",
"zeroconf": []
}
\ No newline at end of file
diff --git a/custom_components/econet300/number.py b/custom_components/econet300/number.py
index 524b992..208f1ab 100644
--- a/custom_components/econet300/number.py
+++ b/custom_components/econet300/number.py
@@ -19,7 +19,6 @@
ENTITY_NUMBER_SENSOR_DEVICE_CLASS_MAP,
ENTITY_STEP,
ENTITY_UNIT_MAP,
- ENTITY_VISIBLE,
NUMBER_MAP,
SERVICE_API,
SERVICE_COORDINATOR,
@@ -129,10 +128,17 @@ async def async_set_native_value(self, value: float) -> None:
def can_add(key: str, coordinator: EconetDataCoordinator):
"""Check if a given entity can be added based on the availability of data in the coordinator."""
- return coordinator.has_param_edit_data(key) and coordinator.data["paramsEdits"][key]
+ try:
+ return (
+ coordinator.has_param_edit_data(key)
+ and coordinator.data["paramsEdits"][key]
+ )
+ except KeyError as e:
+ _LOGGER.error("KeyError in can_add: %s", e)
+ return False
-def apply_limits(desc: EconetNumberEntityDescription, limits: Limits):
+def apply_limits(desc: EconetNumberEntityDescription, limits: Limits) -> None:
"""Set the native minimum and maximum values for the given entity description."""
desc.native_min_value = limits.min
desc.native_max_value = limits.max
@@ -149,7 +155,6 @@ def create_number_entity_description(key: str) -> EconetNumberEntityDescription:
icon=ENTITY_ICON.get(map_key),
device_class=ENTITY_NUMBER_SENSOR_DEVICE_CLASS_MAP.get(map_key),
native_unit_of_measurement=ENTITY_UNIT_MAP.get(map_key),
- entity_registry_visible_default=ENTITY_VISIBLE.get(map_key, True),
min_value=ENTITY_MIN_VALUE.get(map_key),
max_value=ENTITY_MAX_VALUE.get(map_key),
native_step=ENTITY_STEP.get(map_key, 1),
diff --git a/custom_components/econet300/sensor.py b/custom_components/econet300/sensor.py
index 46f045d..ee7fc3c 100644
--- a/custom_components/econet300/sensor.py
+++ b/custom_components/econet300/sensor.py
@@ -5,7 +5,11 @@
import logging
from typing import Any
-from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
+from homeassistant.components.sensor import (
+ SensorEntity,
+ SensorEntityDescription,
+ SensorStateClass,
+)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@@ -26,7 +30,7 @@
SERVICE_COORDINATOR,
STATE_CLASS_MAP,
)
-from .entity import EconetEntity, MixerEntity
+from .entity import EconetEntity, LambdaEntity, MixerEntity
_LOGGER = logging.getLogger(__name__)
@@ -55,13 +59,15 @@ def __init__(
self._attr_native_value = None
super().__init__(coordinator)
- def _sync_state(self, value):
+ def _sync_state(self, value) -> None:
"""Synchronize the state of the sensor entity."""
self._attr_native_value = self.entity_description.process_val(value)
self.async_write_ha_state()
-# TODO: Add MixerSensor check class
+# Add MixerSensor check class Mypy warning
+# Definition of "entity_description" in base class "EconetEntity" is incompatible with definition in base
+# class "SensorEntity"
class MixerSensor(MixerEntity, EconetSensor):
"""Mixer sensor class."""
@@ -76,6 +82,19 @@ def __init__(
super().__init__(description, coordinator, api, idx)
+class LambdaSensors(LambdaEntity, EconetSensor):
+ """Lambda sensor class."""
+
+ def __init__(
+ self,
+ description: EconetSensorEntityDescription,
+ coordinator: EconetDataCoordinator,
+ api: Econet300Api,
+ ):
+ """Initialize a new instance of the EconetSensor class."""
+ super().__init__(description, coordinator, api)
+
+
def create_sensor_entity_description(key: str) -> EconetSensorEntityDescription:
"""Create ecoNET300 sensor entity based on supplied key."""
_LOGGER.debug("Creating sensor entity description for key: %s", key)
@@ -86,35 +105,54 @@ def create_sensor_entity_description(key: str) -> EconetSensorEntityDescription:
translation_key=camel_to_snake(key),
icon=ENTITY_ICON.get(key, None),
native_unit_of_measurement=ENTITY_UNIT_MAP.get(key, None),
- state_class=STATE_CLASS_MAP.get(key, None),
- suggested_display_precision=ENTITY_PRECISION.get(key, None),
+ state_class=STATE_CLASS_MAP.get(key, SensorStateClass.MEASUREMENT),
+ suggested_display_precision=ENTITY_PRECISION.get(key, 0),
process_val=ENTITY_VALUE_PROCESSOR.get(key, lambda x: x),
)
_LOGGER.debug("Created sensor entity description: %s", entity_description)
return entity_description
-def create_controller_sensors(coordinator: EconetDataCoordinator, api: Econet300Api):
+def create_controller_sensors(
+ coordinator: EconetDataCoordinator, api: Econet300Api
+) -> list[EconetSensor]:
"""Create controller sensor entities."""
entities: list[EconetSensor] = []
- coordinator_data = coordinator.data.get("regParams", {})
+
+ data_regParams = coordinator.data.get("regParams", {})
+ data_sysParams = coordinator.data.get("sysParams", {})
+
for data_key in SENSOR_MAP_KEY["_default"]:
- if data_key in coordinator_data:
- entities.append(
- EconetSensor(
- create_sensor_entity_description(data_key), coordinator, api
+ _LOGGER.debug(
+ "Processing entity sensor data_key: %s from regParams & sysParams", data_key
+ )
+ if data_key in data_regParams:
+ entity = EconetSensor(
+ create_sensor_entity_description(data_key), coordinator, api
+ )
+ entities.append(entity)
+ _LOGGER.debug(
+ "Created and appended sensor entity from regParams: %s", entity
+ )
+ elif data_key in data_sysParams:
+ if data_sysParams.get(data_key) is None:
+ _LOGGER.warning(
+ "%s in sysParams is null, sensor will not be created.", data_key
)
+ continue
+ entity = EconetSensor(
+ create_sensor_entity_description(data_key), coordinator, api
)
+ entities.append(entity)
_LOGGER.debug(
- "Key: %s mapped, sensor entity will be added",
+ "Created and appended sensor entity from sysParams: %s", entity
+ )
+ else:
+ _LOGGER.warning(
+ "Key: %s is not mapped in regParams or sysParams, sensor entity will not be added.",
data_key,
)
- continue
- _LOGGER.warning(
- "Key: %s is not mapped, sensor entity will not be added",
- data_key,
- )
-
+ _LOGGER.info("Total sensor entities created: %d", len(entities))
return entities
@@ -139,7 +177,7 @@ def create_mixer_sensor_entity_description(key: str) -> EconetSensorEntityDescri
translation_key=camel_to_snake(key),
icon=ENTITY_ICON.get(key, None),
native_unit_of_measurement=ENTITY_UNIT_MAP.get(key, None),
- state_class=STATE_CLASS_MAP.get(key, None),
+ state_class=STATE_CLASS_MAP.get(key, SensorStateClass.MEASUREMENT),
device_class=ENTITY_SENSOR_DEVICE_CLASS_MAP.get(key, None),
suggested_display_precision=ENTITY_PRECISION.get(key, 0),
process_val=ENTITY_VALUE_PROCESSOR.get(key, lambda x: x),
@@ -155,7 +193,6 @@ def create_mixer_sensors(
entities: list[MixerSensor] = []
for key, mixer_keys in SENSOR_MIXER_KEY.items():
-
# Check if all required mixer keys have valid (non-null) values
if any(
coordinator.data.get("regParams", {}).get(mixer_key) is None
@@ -173,6 +210,58 @@ def create_mixer_sensors(
return entities
+# Create Lambda sensor entity description and Lambda sensor
+
+
+def create_lambda_sensor_entity_description(key: str) -> EconetSensorEntityDescription:
+ """Create a sensor entity description for a Lambda."""
+ _LOGGER.debug("Creating Lambda entity sensor description for key: %s", key)
+ entity_description = EconetSensorEntityDescription(
+ key=key,
+ translation_key=camel_to_snake(key),
+ icon=ENTITY_ICON.get(key, None),
+ native_unit_of_measurement=ENTITY_UNIT_MAP.get(key, None),
+ state_class=STATE_CLASS_MAP.get(key, None),
+ device_class=ENTITY_SENSOR_DEVICE_CLASS_MAP.get(key, None),
+ suggested_display_precision=ENTITY_PRECISION.get(key, 0),
+ process_val=ENTITY_VALUE_PROCESSOR.get(key, lambda x: x / 10),
+ )
+ _LOGGER.debug("Created LambdaSensors entity description: %s", entity_description)
+ return entity_description
+
+
+def create_lambda_sensors(coordinator: EconetDataCoordinator, api: Econet300Api):
+ """Create controller sensor entities."""
+ entities: list[LambdaSensors] = []
+ sys_params = coordinator.data.get("sysParams", {})
+
+ # Check if moduleLambdaSoftVer is None
+ if sys_params.get("moduleLambdaSoftVer") is None:
+ _LOGGER.info("moduleLambdaSoftVer is None, no lambda sensors will be created")
+ return entities
+
+ coordinator_data = coordinator.data.get("regParams", {})
+
+ for data_key in SENSOR_MAP_KEY["lambda"]:
+ if data_key in coordinator_data:
+ entities.append(
+ LambdaSensors(
+ create_lambda_sensor_entity_description(data_key), coordinator, api
+ )
+ )
+ _LOGGER.debug(
+ "Key: %s mapped, lamda sensor entity will be added",
+ data_key,
+ )
+ continue
+ _LOGGER.warning(
+ "Key: %s is not mapped, lamda sensor entity will not be added",
+ data_key,
+ )
+
+ return entities
+
+
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
@@ -185,5 +274,7 @@ async def async_setup_entry(
entities: list[EconetSensor] = []
entities.extend(create_controller_sensors(coordinator, api))
entities.extend(create_mixer_sensors(coordinator, api))
+ entities.extend(create_lambda_sensors(coordinator, api))
- return async_add_entities(entities)
+ async_add_entities(entities)
+ return True
diff --git a/custom_components/econet300/strings.json b/custom_components/econet300/strings.json
index 6dd248e..f8fd89c 100644
--- a/custom_components/econet300/strings.json
+++ b/custom_components/econet300/strings.json
@@ -20,7 +20,7 @@
},
"entity": {
"binary_sensor": {
- "lighter": {
+ "lighter_works": {
"name": "Lighter"
},
"weather_control": {
@@ -38,6 +38,9 @@
"fan_works": {
"name": "Fan"
},
+ "feeder_works": {
+ "name": "Feeder"
+ },
"additional_feeder": {
"name": "Additional feeder"
},
@@ -52,12 +55,24 @@
},
"boiler_pump": {
"name": "Boiler pump"
+ },
+ "main_srv": {
+ "name": "Econet24.com server"
+ },
+ "wifi": {
+ "name": "Wi-Fi"
+ },
+ "lan": {
+ "name": "LAN"
}
},
"sensor": {
"boiler_power": {
"name": "Boiler output"
},
+ "boiler_power_kw": {
+ "name": "Boiler power"
+ },
"fuel_level": {
"name": "Fuel level"
},
@@ -97,8 +112,26 @@
"firing_up_count": {
"name": "Firing up count"
},
- "main_server": {
- "name": "Main server"
+ "soft_ver": {
+ "name": "Module ecoNET version"
+ },
+ "controller_id": {
+ "name": "Controller name"
+ },
+ "module_a_soft_ver": {
+ "name": "Module A version"
+ },
+ "module_b_soft_ver": {
+ "name": "Module B version"
+ },
+ "module_c_soft_ver": {
+ "name": "Module C version"
+ },
+ "module_lambda_soft_ver": {
+ "name": "Module Lambda version"
+ },
+ "module_panel_soft_ver": {
+ "name": "Module Panel version"
},
"mode": {
"name": "Boiler mode",
@@ -135,15 +168,15 @@
"pump_fireplace_works": {
"name": "Boiler pump"
},
- "signal": {
+ "quality": {
"name": "Signal quality"
},
+ "signal": {
+ "name": "Signal strength"
+ },
"servo_mixer1": {
"name": "Mixer 1 servo position"
},
- "status_wifi": {
- "name": "Wireless network connected"
- },
"temp_co": {
"name": "Heating temperature"
},
diff --git a/custom_components/econet300/translations/en.json b/custom_components/econet300/translations/en.json
index ae9ac0a..ef135bf 100644
--- a/custom_components/econet300/translations/en.json
+++ b/custom_components/econet300/translations/en.json
@@ -20,7 +20,7 @@
},
"entity": {
"binary_sensor": {
- "lighter": {
+ "lighter_works": {
"name": "Lighter"
},
"weather_control": {
@@ -52,12 +52,24 @@
},
"boiler_pump": {
"name": "Boiler pump"
+ },
+ "main_srv": {
+ "name": "Econet24.com server"
+ },
+ "wifi": {
+ "name": "Wi-Fi"
+ },
+ "lan": {
+ "name": "LAN"
}
},
"sensor": {
"boiler_power": {
"name": "Boiler output"
},
+ "boiler_power_kw": {
+ "name": "Boiler power"
+ },
"fuel_level": {
"name": "Fuel level"
},
@@ -82,9 +94,6 @@
"lambda_level": {
"name": "Lambda level"
},
- "main_server": {
- "name": "Main server"
- },
"work_at100": {
"name": "Work at 100%"
},
@@ -97,6 +106,9 @@
"feeder_work": {
"name": "Feeder work"
},
+ "feeder_works": {
+ "name": "Feeder"
+ },
"firing_up_count": {
"name": "Firing up count"
},
@@ -135,15 +147,36 @@
"pump_fireplace_works": {
"name": "Boiler pump"
},
- "signal": {
+ "quality": {
"name": "Signal quality"
},
+ "signal": {
+ "name": "Signal strength"
+ },
+ "soft_ver": {
+ "name": "Module ecoNET version"
+ },
+ "controller_id": {
+ "name": "Controller name"
+ },
+ "module_a_soft_ver": {
+ "name": "Module A version"
+ },
+ "module_b_soft_ver": {
+ "name": "Module B version"
+ },
+ "module_c_soft_ver": {
+ "name": "Module C version"
+ },
+ "module_lambda_soft_ver": {
+ "name": "Module Lambda version"
+ },
+ "module_panel_soft_ver": {
+ "name": "Module Panel version"
+ },
"servo_mixer1": {
"name": "Mixer 1 servo position"
},
- "status_wifi": {
- "name": "Wireless network connected"
- },
"temp_co": {
"name": "Heating temperature"
},
diff --git a/custom_components/econet300/translations/pl.json b/custom_components/econet300/translations/pl.json
index da6cb41..bc30b98 100644
--- a/custom_components/econet300/translations/pl.json
+++ b/custom_components/econet300/translations/pl.json
@@ -10,33 +10,69 @@
}
},
"error": {
- "cannot_connect": "B艂膮d po艂膮czenia",
- "invalid_auth": "B艂膮d autoryzacji",
- "unknown": "Niespodziewany b艂膮d"
+ "cannot_connect": "B艂膮d po艂膮czenia",
+ "invalid_auth": "B艂膮d autoryzacji",
+ "unknown": "Niespodziewany b艂膮d"
},
"abort": {
"already_configured": "Urz膮dzenie zosta艂o ju偶 skonfigutowane"
}
},
- "entity":{
+ "entity": {
"binary_sensor": {
- "weather_control": {"name": "Weather control the boiler"},
- "unseal": { "name": "Unseal" },
- "thermostat": { "name": "Boiler thermostat" },
- "pump_co_works": { "name": "Pump CO" },
- "fan_works": { "name": "Fan" },
- "aditional_feeder": { "name": "Aditional feeder" },
- "pump_fireplace_works": { "name": "Boiler Pump" },
- "pump_cwu_works": { "name": "Pump CWU" },
- "mixer_pump1": { "name": "Mixer 1 pump" },
- "boiler_pump": { "name": "Boiler pump" }
+ "weather_control": {
+ "name": "Weather control the boiler"
+ },
+ "unseal": {
+ "name": "Unseal"
+ },
+ "thermostat": {
+ "name": "Boiler thermostat"
+ },
+ "pump_co_works": {
+ "name": "Pump CO"
+ },
+ "fan_works": {
+ "name": "Fan"
+ },
+ "aditional_feeder": {
+ "name": "Aditional feeder"
+ },
+ "pump_fireplace_works": {
+ "name": "Boiler Pump"
+ },
+ "pump_cwu_works": {
+ "name": "Pump CWU"
+ },
+ "mixer_pump1": {
+ "name": "Mixer 1 pump"
+ },
+ "boiler_pump": {
+ "name": "Boiler pump"
+ },
+ "main_srv": {
+ "name": "Econet24.com server"
+ },
+ "wifi": {
+ "name": "Wi-Fi"
+ }
},
"sensor": {
- "boiler_power": { "name": "Moc kot艂a" },
- "burner_power": { "name": "Burner output" },
- "fuel_level": { "name": "Poziom paliwa" },
- "fan_works": { "name": "Fan" },
- "fan_power": { "name": "Moc nadmuchu" },
+ "boiler_power": {
+ "name": "Moc kot艂a"
+ },
+ "burner_power": {
+ "name": "Burner output"
+ },
+ "fuel_level": {
+ "name": "Poziom paliwa"
+ },
+ "fan_works": {
+ "name": "Fan"
+ },
+ "fan_power": {
+ "name": "Moc nadmuchu"
+ },
"lambda_status": {
"name": "Lambda status",
"state": {
@@ -46,11 +82,18 @@
"unknown": "Unknown"
}
},
- "lambda_set": { "name": "Lambda set" },
- "lambda_level": { "name": "Czujnik Lambda" },
- "mixer_temp1": { "name": "Temp. mieszacza 1" },
- "mixer_set_temp1": { "name": "Temp. zadana mieszacza 1" },
- "main_server": { "name": "G艂贸wny serwer" },
+ "lambda_set": {
+ "name": "Lambda set"
+ },
+ "lambda_level": {
+ "name": "Czujnik Lambda"
+ },
+ "mixer_temp1": {
+ "name": "Temp. mieszacza 1"
+ },
+ "mixer_set_temp1": {
+ "name": "Temp. zadana mieszacza 1"
+ },
"mode": {
"name": "Tryb pracy",
"state": {
@@ -70,23 +113,54 @@
"unknown": "Unknown"
}
},
- "pump_cwu_works": { "name": "HUW pump" },
- "pump_fireplace_works": { "name": "Boiler pump" },
- "valve_mixer1": { "name": "Zaw贸r mieszacza 1" },
- "servo_Mixer1": { "name": "Si艂ownik mieszacza 1" },
- "signal": { "name": "Si艂a sygna艂u" },
- "status_wifi": { "name": "Po艂膮czenie z sieci膮 bezprzewodow膮" },
- "temp_co_set": { "name": "Heating target temperature" },
- "temp_co": { "name": "Temperatura kot艂a" },
- "temp_cwu": { "name": "Temperatura CWU" },
- "temp_upper_buffer": { "name": "Temperatura bufora g贸rna" },
- "temp_lower_buffer": { "name": "Temperatura bufora dolna" },
- "temp_flue_gas": { "name": "Temperatura spalin" },
- "temp_external_sensor": { "name": "Temperatura zewn臋trzna" },
- "temp_feeder": {"name": "Temperatura podajnika"},
- "unseal": { "name": "Unseal" },
- "thermostat": { "name": "Thermostat" },
- "weather_control": {"name": "Weather control the boiler"}
+ "pump_cwu_works": {
+ "name": "HUW pump"
+ },
+ "pump_fireplace_works": {
+ "name": "Boiler pump"
+ },
+ "valve_mixer1": {
+ "name": "Zaw贸r mieszacza 1"
+ },
+ "servo_Mixer1": {
+ "name": "Si艂ownik mieszacza 1"
+ },
+ "signal": {
+ "name": "Si艂a sygna艂u"
+ },
+ "temp_co_set": {
+ "name": "Heating target temperature"
+ },
+ "temp_co": {
+ "name": "Temperatura kot艂a"
+ },
+ "temp_cwu": {
+ "name": "Temperatura CWU"
+ },
+ "temp_upper_buffer": {
+ "name": "Temperatura bufora g贸rna"
+ },
+ "temp_lower_buffer": {
+ "name": "Temperatura bufora dolna"
+ },
+ "temp_flue_gas": {
+ "name": "Temperatura spalin"
+ },
+ "temp_external_sensor": {
+ "name": "Temperatura zewn臋trzna"
+ },
+ "temp_feeder": {
+ "name": "Temperatura podajnika"
+ },
+ "unseal": {
+ "name": "Unseal"
+ },
+ "thermostat": {
+ "name": "Thermostat"
+ },
+ "weather_control": {
+ "name": "Weather control the boiler"
+ }
}
}
-}
+}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 1d48776..353b9cb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
colorlog==6.8.2
-homeassistant>=2024.9.2
-ruff==0.8.1
+homeassistant>=2024.10.2
+ruff==0.8.3
codespell==2.3.0
\ No newline at end of file