diff --git a/CHANGELOG.md b/CHANGELOG.md
index d9a1f42..67b152a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 1.1.0
+- New sensors based on ecojoko Measurements APIs
+- Some performance improvement and minor bug fixes
+- Bug fix [#58](https://github.com/jmcruvellier/little_monkey/issues/58)
+- Bug fix [#71](https://github.com/jmcruvellier/little_monkey/issues/71)
+
## 1.0.1
- Bug fix [#67](https://github.com/jmcruvellier/little_monkey/issues/67)
diff --git a/README.md b/README.md
index 2765213..f7ff337 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,8 @@
+[![CodeQL](https://github.com/jmcruvellier/little_monkey/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/github-code-scanning/codeql)
+[![HACS](https://github.com/jmcruvellier/little_monkey/actions/workflows/hacs.yaml/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/hacs.yaml)
+[![hassfest](https://github.com/jmcruvellier/little_monkey/actions/workflows/hassfest.yaml/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/hassfest.yaml)
+[![Validate](https://github.com/jmcruvellier/little_monkey/actions/workflows/validate.yml/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/validate.yml)
+
![](/custom_components/little_monkey/res/logo_small.png)
# Little Monkey / Petit Singe
@@ -5,24 +10,27 @@ Cette intégration vous permet de récupérer les informations collectées par v
Elle intègre dans Home Assistant les capteurs suivants:
-* Consommation Temps Réel (Puissance en W)
-* Consommation Réseau (Energie en kWh)
-* Si vous avez un contrat d'énergie HC/HP
- - Consommation HC Réseau (Energie en kWh)
- - Consommation HP Réseau (Energie en kWh)
- - Si c'est un contrat Tempo:
- - Consommation HC Bleu Réseau (Energie en kWh)
- - Consommation HP Bleu Réseau (Energie en kWh)
- - Consommation HC Blanc Réseau (Energie en kWh)
- - Consommation HP Blanc Réseau (Energie en kWh)
- - Consommation HC Rouge Réseau (Energie en kWh)
- - Consommation HP Rouge Réseau (Energie en kWh)
-* Si vous êtes producteur d'énergie grâce à des panneaux photovoltaïques et possesseur d'un capteur ecojoko ancienne génération:
- - Surplus de Production (Energie en kWh)
-* Température Intérieure (en °C)
-* Température Extérieure (en °C)
-* Humidité Intérieure (en %)
-* Humidité Extérieure (en %)
+| Version | Capteur | Type | Unité | Disponibilité | Commentaire |
+| ------- | ------- | ---- | ----- | ------------- | ----------- |
+| 1.0.0 | Consommation Temps Réel | Puissance | W | Permanent | |
+| 1.0.0 | Consommation Réseau | Energie | kWh | Permanent | |
+| 1.0.0 | Consommation HC Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie incluant les HC/HP |
+| 1.0.0 | Consommation HP Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie incluant les HC/HP |
+| 1.0.0 | Consommation HC Bleu Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HP Bleu Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HC Blanc Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HP Blanc Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HC Rouge Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HP Rouge Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Surplus de Production | Energie | kWh | Optionnel | Si vous êtes producteur d'énergie grâce à des panneaux photovoltaïques et possesseur d'un capteur ecojoko ancienne génération |
+| 1.0.0 | Température Intérieure | Température | °C | Optionnel | |
+| 1.0.0 | Température Extérieure | Température | °C | Optionnel | |
+| 1.0.0 | Humidité Intérieure | Humidité | % | Optionnel | |
+| 1.0.0 | Humidité Extérieure | Humidité | % | Optionnel | |
+| 1.1.0 | Consommation Dernière Mesure | Puissance | W | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
+| 1.1.0 | Consommation Réseau Dernière Mesure | Energie | kWh | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
+| 1.1.0 | Consommation HC Réseau Dernière Mesure | Energie | kWh | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
+| 1.1.0 | Consommation HP Réseau Dernière Mesure | Energie | kWh | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
> [!IMPORTANT]
> Si vous êtes un utilisateur régulier de l'application ecojoko©️, vous n'êtes pas sans savoir que le petit singe glisse souvent sur sa peau de banane. **Cette __intégration non-officielle__ dépend des APIs d'ecojoko©️ et n'est donc pas responsable en cas d'indisponibilité de vos donnés.**
diff --git a/custom_components/little_monkey/__init__.py b/custom_components/little_monkey/__init__.py
index 281a78e..3d8b12b 100644
--- a/custom_components/little_monkey/__init__.py
+++ b/custom_components/little_monkey/__init__.py
@@ -14,6 +14,7 @@
from .const import (
DOMAIN,
PLATFORMS,
+ CONF_USE_LAST_MEASURE_FEATURE,
CONF_USE_HCHP_FEATURE,
CONF_USE_TEMPO_FEATURE,
CONF_USE_TEMPHUM_FEATURE,
@@ -21,6 +22,15 @@
)
from .coordinator import LittleMonkeyDataUpdateCoordinator
+def get_boolean(array, index):
+ """Read the value with a default of False if the key is not found."""
+ return array.get(index, False)
+
+def get_string(array, index):
+ """Read the value with a default of empty string if the key is not found."""
+ return array.get(index, "")
+
+
# https://developers.home-assistant.io/docs/config_entries_index/#setting-up-an-entry
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up this integration using UI."""
@@ -29,12 +39,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass=hass,
entry=entry,
client=LittleMonkeyApiClient(
- username=entry.data[CONF_USERNAME],
- password=entry.data[CONF_PASSWORD],
- use_hchp=entry.data[CONF_USE_HCHP_FEATURE],
- use_tempo=entry.data[CONF_USE_TEMPO_FEATURE],
- use_temphum=entry.data[CONF_USE_TEMPHUM_FEATURE],
- use_prod=entry.data[CONF_USE_PROD_FEATURE],
+ username=get_string(entry.data, CONF_USERNAME),
+ password=get_string(entry.data, CONF_PASSWORD),
+ use_last_measure=get_boolean(entry.data, CONF_USE_LAST_MEASURE_FEATURE),
+ use_hchp=get_boolean(entry.data, CONF_USE_HCHP_FEATURE),
+ use_tempo=get_boolean(entry.data, CONF_USE_TEMPO_FEATURE),
+ use_temphum=get_boolean(entry.data, CONF_USE_TEMPHUM_FEATURE),
+ use_prod=get_boolean(entry.data, CONF_USE_PROD_FEATURE),
session=async_get_clientsession(hass),
),
)
diff --git a/custom_components/little_monkey/api.py b/custom_components/little_monkey/api.py
index 73116ea..5df194e 100644
--- a/custom_components/little_monkey/api.py
+++ b/custom_components/little_monkey/api.py
@@ -1,8 +1,7 @@
"""API Client for little_monkey."""
from __future__ import annotations
-# import traceback
-
+#import traceback
import asyncio
import datetime
import socket
@@ -27,13 +26,11 @@
class LittleMonkeyApiClientError(Exception):
"""Exception to indicate a general API error."""
-
class LittleMonkeyApiClientCommunicationError(
LittleMonkeyApiClientError
):
"""Exception to indicate a communication error."""
-
class LittleMonkeyApiClientAuthenticationError(
LittleMonkeyApiClientError
):
@@ -59,6 +56,7 @@ def __init__(
self,
username: str,
password: str,
+ use_last_measure: bool,
use_hchp: bool,
use_tempo: bool,
use_temphum: bool,
@@ -68,6 +66,7 @@ def __init__(
"""Initialize."""
self._username = username
self._password = password
+ self._use_last_measure = use_last_measure
self._use_hchp = use_hchp
self._use_tempo = use_tempo
self._use_temphum = use_temphum
@@ -81,6 +80,7 @@ def __init__(
self._temp_hum_id = None
self._current_date = None
self._local_time = None
+ self._local_date = None
self._current_pricing_details = None
self._night_pricing_details = None
self._day_pricing_details = None
@@ -91,6 +91,9 @@ def __init__(
self._kwh_hc_night = None
self._kwh_hc_ns = None
self._kwh_hp_ns = None
+ self._last_kwh = None
+ self._last_kwh_hc_ns = None
+ self._last_kwh_hp_ns = None
self._tempo_hc_blue = None
self._tempo_hp_blue = None
self._tempo_hc_white = None
@@ -102,6 +105,7 @@ def __init__(
self._outdoor_temp = None
self._indoor_hum = None
self._outdoor_hum = None
+ self._last_consumption_measure = None
#67 fix
self._status = APIStatus.INIT
@@ -115,6 +119,11 @@ def current_date(self) -> datetime.date:
"""Return the native value of the sensor."""
return self._current_date
+ @property
+ def local_date(self) -> datetime.time:
+ """Return the native value of the sensor."""
+ return self._local_date
+
@property
def local_time(self) -> datetime.time:
"""Return the native value of the sensor."""
@@ -155,6 +164,21 @@ def kwh_hp_ns(self) -> int:
"""Return the native value of the sensor."""
return self._kwh_hp_ns
+ @property
+ def last_kwh(self) -> int:
+ """Return the native value of the sensor."""
+ return self._last_kwh
+
+ @property
+ def last_kwh_hc_ns(self) -> int:
+ """Return the native value of the sensor."""
+ return self._last_kwh_hc_ns
+
+ @property
+ def last_kwh_hp_ns(self) -> int:
+ """Return the native value of the sensor."""
+ return self._last_kwh_hp_ns
+
@property
def tempo_hc_blue(self) -> int:
"""Return the native value of the sensor."""
@@ -210,6 +234,11 @@ def outdoor_hum(self) -> int:
"""Return the native value of the sensor."""
return self._outdoor_hum
+ @property
+ def last_consumption_measure(self) -> int:
+ """Return the native value of the sensor."""
+ return self._last_consumption_measure
+
def has_day_changed(self, datetime1, datetime2):
"""Compare two dates and return if day has changed."""
# Extract date components (year, month, day)
@@ -224,6 +253,7 @@ async def async_get_date_time(self) -> any:
# Get the current date
self._current_date = datetime.date.today()
paris_tz = pytz.timezone('Europe/Paris')
+ self._local_date = datetime.datetime.now(paris_tz).date()
self._local_time = datetime.datetime.now(paris_tz).time()
return
@@ -235,7 +265,7 @@ async def async_get_data(self) -> None:
if self._gateway_id is None:
await self.async_get_gatewaydata()
- previous_date = self._current_date
+ previous_local_date = self._local_date
previous_local_time = self._local_time
await self.async_get_date_time()
if self._current_pricingzone is None or (
@@ -259,7 +289,7 @@ async def async_get_data(self) -> None:
# Retrieving Night HC
night_time = datetime.time(1, 0, 0)
await self.async_get_pricing_details(is_current=False,
- specific_date=self._current_date,
+ specific_date=self._local_date,
specific_time=night_time)
self._kwh_hc_night = await self.async_get_powerstat(self._night_pricing_details)
if self._night_pricing_details == "HC Bleu":
@@ -273,7 +303,7 @@ async def async_get_data(self) -> None:
# Retrieving Day HP
day_time = datetime.time(14, 0, 0)
await self.async_get_pricing_details(is_current=False,
- specific_date=self._current_date,
+ specific_date=self._local_date,
specific_time=day_time)
kwh_hp = await self.async_get_powerstat(self._day_pricing_details)
if self._day_pricing_details == "HP Bleu":
@@ -284,8 +314,8 @@ async def async_get_data(self) -> None:
self._tempo_hp_red = kwh_hp
else:
#68 fix Tempo sensors not being reset when day changes
- date1 = datetime.datetime(previous_date.year, previous_date.month, previous_date.day, previous_local_time.hour, previous_local_time.minute, previous_local_time.second)
- date2 = datetime.datetime(self._current_date.year, self._current_date.month, self._current_date.day, self._local_time.hour, self._local_time.minute, self._local_time.second)
+ date1 = datetime.datetime(previous_local_date.year, previous_local_date.month, previous_local_date.day, previous_local_time.hour, previous_local_time.minute, previous_local_time.second)
+ date2 = datetime.datetime(self._local_date.year, self._local_date.month, self._local_date.day, self._local_time.hour, self._local_time.minute, self._local_time.second)
if self.has_day_changed(date1, date2) is True:
self._kwh_hc_night = None
self._tempo_hc_blue = None
@@ -294,9 +324,11 @@ async def async_get_data(self) -> None:
self._tempo_hp_white = None
self._tempo_hc_red = None
self._tempo_hp_red = None
-
+ await self.async_get_gatewaydata()
await self.async_get_realtime_conso()
+ if self._use_last_measure is True:
+ await self.async_get_last_measure()
await self.async_get_kwhstat()
if self._use_temphum is True:
await self.async_get_tempstat()
@@ -345,10 +377,6 @@ async def async_get_pricing_details(self,
specific_time=specific_time)
except Exception: # pylint: disable=broad-except
return
- # except Exception as exception: # pylint: disable=broad-except
- # raise LittleMonkeyApiClientError(
- # "Something really wrong happened!"
- # ) from exception
async def async_get_realtime_conso(self) -> any:
"""Get Ecojoko realtime consumption."""
@@ -365,10 +393,22 @@ async def async_get_realtime_conso(self) -> any:
return await self._realtimeconso_wrapper()
except Exception: # pylint: disable=broad-except
return
- # except Exception as exception: # pylint: disable=broad-except
- # raise LittleMonkeyApiClientError(
- # "Something really wrong happened!"
- # ) from exception
+
+ async def async_get_last_measure(self) -> any:
+ """Get Ecojoko last measure."""
+ try:
+ if self._cookies is None:
+ LOGGER.debug("Pas de cookies")
+ # raise exception
+ if self._gateway_id is None:
+ LOGGER.debug("Pas de gateway")
+ # TOTO raise exception
+ if self._power_meter_id is None:
+ LOGGER.debug("Pas de power meter")
+ # TOTO raise exception
+ return await self._last_measure_wrapper()
+ except Exception: # pylint: disable=broad-except
+ return
async def async_get_kwhstat(self) -> any:
"""Get Ecojoko kwhstat."""
@@ -385,10 +425,6 @@ async def async_get_kwhstat(self) -> any:
return await self._kwhstat_wrapper()
except Exception: # pylint: disable=broad-except
return
- # except Exception as exception: # pylint: disable=broad-except
- # raise LittleMonkeyApiClientError(
- # "Something really wrong happened!"
- # ) from exception
async def async_get_tempstat(self) -> any:
"""Get Ecojoko tempstat."""
@@ -405,10 +441,6 @@ async def async_get_tempstat(self) -> any:
return await self._tempstat_wrapper()
except Exception: # pylint: disable=broad-except
return
- # except Exception as exception: # pylint: disable=broad-except
- # raise LittleMonkeyApiClientError(
- # "Something really wrong happened!"
- # ) from exception
async def async_get_humstat(self) -> any:
"""Get Ecojoko humstat."""
@@ -425,10 +457,6 @@ async def async_get_humstat(self) -> any:
return await self._humstat_wrapper()
except Exception: # pylint: disable=broad-except
return
- # except Exception as exception: # pylint: disable=broad-except
- # raise LittleMonkeyApiClientError(
- # "Something really wrong happened!"
- # ) from exception
async def async_get_powerstat(self, pricing_details) -> any:
"""Get Ecojoko powerstat."""
@@ -445,10 +473,6 @@ async def async_get_powerstat(self, pricing_details) -> any:
return await self._powerstat_wrapper(pricing_details)
except Exception: # pylint: disable=broad-except
return
- # except Exception as exception: # pylint: disable=broad-except
- # raise LittleMonkeyApiClientError(
- # "Something really wrong happened!"
- # ) from exception
async def _cookiesapi_wrapper(
self,
@@ -463,12 +487,14 @@ async def _cookiesapi_wrapper(
data=data
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
self._cookies = response.cookies
- response.raise_for_status()
- return await response.json()
+ #response.raise_for_status()
+ return
except asyncio.TimeoutError as exception:
LOGGER.error("API Cookies timeout error")
@@ -496,6 +522,8 @@ async def _gatewayapi_wrapper(self) -> any:
cookies=self._cookies,
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
@@ -519,8 +547,8 @@ async def _gatewayapi_wrapper(self) -> any:
if item["device_type"] == "POWER_METER":
self._power_meter_id = item["device_id"]
- response.raise_for_status()
- return await response.json()
+ #response.raise_for_status()
+ return
except asyncio.TimeoutError as exception:
LOGGER.error("API Gateway timeout error")
@@ -548,7 +576,7 @@ async def _pricing_details_wrapper(self,
# Retrieve current Tempo pricing
# Format the date as 'YYYY-MM-DD'
if specific_date is None:
- formatted_date = self._current_date.strftime('%Y-%m-%d')
+ formatted_date = self._local_date.strftime('%Y-%m-%d')
else:
#67 fix
formatted_date = specific_date.strftime('%Y-%m-%d')
@@ -560,7 +588,6 @@ async def _pricing_details_wrapper(self,
local_time = specific_time
formatted_date = formatted_date + specific_time.strftime('%H:%M')
url = ECOJOKO_GATEWAY_URL + f"/{self._gateway_id}/device/{self._power_meter_id}/powerstat/h/{formatted_date}"
- #LOGGER.debug("URL: %s", url)
async with async_timeout.timeout(CONF_API_TIMEOUT):
response = await self._session.get(
url=url,
@@ -568,6 +595,8 @@ async def _pricing_details_wrapper(self,
cookies=self._cookies,
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
@@ -592,11 +621,11 @@ async def _pricing_details_wrapper(self,
self._evening_pricing_details = pricing_details
else:
LOGGER.debug("PAS DE PRICING DETAILS")
- response.raise_for_status()
- return await response.json()
+ #response.raise_for_status()
+ return
except asyncio.TimeoutError as exception:
- LOGGER.error("API Pricing Details timeout error: %s")
+ LOGGER.error("API Pricing Details timeout error")
raise LittleMonkeyApiClientCommunicationError(
"Timeout error fetching information",
) from exception
@@ -623,14 +652,16 @@ async def _realtimeconso_wrapper(self) -> any:
cookies=self._cookies,
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
if "application/json" in response.headers.get("Content-Type", ""):
value_json = await response.json()
self._realtime_conso = value_json['real_time']['value']
- response.raise_for_status()
- return await response.json()
+ #response.raise_for_status()
+ return
except asyncio.TimeoutError as exception:
LOGGER.error("API Realtime timeout error")
@@ -648,6 +679,106 @@ async def _realtimeconso_wrapper(self) -> any:
"Something really wrong happened!"
) from exception
+ async def _last_measure_wrapper(self) -> any:
+ """Get last measure from the API."""
+ try:
+ # Format the date as 'YYYY-MM-DD'
+ formatted_date = self._local_date.strftime('%Y-%m-%d')
+ url = ECOJOKO_GATEWAY_URL + f"/{self._gateway_id}/device/{self._power_meter_id}/powerstat/d4/{formatted_date}"
+ # formatted_date = formatted_date + self._local_time.strftime('%H:%M')
+ # url = ECOJOKO_GATEWAY_URL + f"/{self._gateway_id}/device/{self._power_meter_id}/powerstat/h/{formatted_date}"
+ async with async_timeout.timeout(CONF_API_TIMEOUT):
+ response = await self._session.get(
+ url=url,
+ headers=self._headers,
+ cookies=self._cookies,
+ )
+ if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
+ raise LittleMonkeyApiClientAuthenticationError(
+ "Invalid credentials",
+ )
+ if "application/json" in response.headers.get("Content-Type", ""):
+ value_json = await response.json()
+ if "data" in value_json['stat']:
+ if len(value_json['stat']['data']) > 1:
+ self._last_consumption_measure = value_json['stat']['data'][-1]['value']
+ else:
+ # LOGGER.debug("UNE SEULE VALEUR: %s", value_json)
+ self._last_consumption_measure = value_json['stat']['data']['value']
+
+ if "period" in value_json['stat']:
+ self._last_kwh = value_json['stat']['period']['kwh']
+ # LOGGER.warning("REPONSE ECOJOKO: %s", value_json)
+ if self._use_hchp is True:
+ self._last_kwh_hp_ns = value_json['stat']['period']['kwh_hp_ns']
+ self._last_kwh_hc_ns = value_json['stat']['period']['kwh_hc_ns']
+ else:
+ LOGGER.debug("NE RETOURNE PAS DE HC/HP")
+
+ #response.raise_for_status()
+ return #await response.json()
+
+ except asyncio.TimeoutError as exception:
+ LOGGER.error("API Last Measure timeout error")
+ raise LittleMonkeyApiClientCommunicationError(
+ "Timeout error fetching information",
+ ) from exception
+ except (aiohttp.ClientError, socket.gaierror) as exception:
+ LOGGER.error("API Last Measure client error: %s", exception)
+ raise LittleMonkeyApiClientCommunicationError(
+ "Error fetching information",
+ ) from exception
+ except Exception as exception: # pylint: disable=broad-except
+ LOGGER.error("API Last Measure other error: %s", exception)
+ #traceback.print_exc()
+ raise LittleMonkeyApiClientError(
+ "Something really wrong happened!"
+ ) from exception
+
+ async def Tempo(self) -> any:
+ """Tempo data analysis."""
+ if self._current_pricing_details == "HC Bleu":
+ if self.current_pricingzone == PricingZone.HC_EVENING:
+ if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
+ if (self._kwh_hc_ns - self._kwh_hc_night) >= 0:
+ self._tempo_hc_blue = self._kwh_hc_ns - self._kwh_hc_night
+ elif self._current_pricing_details == self._night_pricing_details:
+ if self._kwh_hc_ns >= 0:
+ self._tempo_hc_blue = self._kwh_hc_ns
+ else:
+ self._tempo_hc_blue = self._kwh_hc_ns
+ self._kwh_hc_night = self._kwh_hc_ns
+ elif self._current_pricing_details == "HP Bleu":
+ self._tempo_hp_blue = self._kwh_hp_ns
+ elif self._current_pricing_details == "HC Blanc":
+ if self.current_pricingzone == PricingZone.HC_EVENING:
+ if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
+ if (self._kwh_hc_ns - self._kwh_hc_night) >= 0:
+ self._tempo_hc_white = self._kwh_hc_ns - self._kwh_hc_night
+ elif self._current_pricing_details == self._night_pricing_details:
+ if self._kwh_hc_ns >= 0:
+ self._tempo_hc_white = self._kwh_hc_ns
+ else:
+ self._tempo_hc_white = self._kwh_hc_ns
+ self._kwh_hc_night = self._kwh_hc_ns
+ elif self._current_pricing_details == "HP Blanc":
+ self._tempo_hp_white = self._kwh_hp_ns
+ elif self._current_pricing_details == "HC Rouge":
+ if self.current_pricingzone == PricingZone.HC_EVENING:
+ if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
+ if (self._kwh_hc_ns - self._kwh_hc_night) >= 0:
+ self._tempo_hc_red = self._kwh_hc_ns - self._kwh_hc_night
+ elif self._current_pricing_details == self._night_pricing_details:
+ if self._kwh_hc_ns >= 0:
+ self._tempo_hc_red = self._kwh_hc_ns
+ else:
+ self._tempo_hc_red = self._kwh_hc_ns
+ self._kwh_hc_night = self._kwh_hc_ns
+ elif self._current_pricing_details == "HP Rouge":
+ self._tempo_hp_red = self._kwh_hp_ns
+
async def _kwhstat_wrapper(self) -> any:
"""Get kwhstat from the API."""
try:
@@ -659,67 +790,70 @@ async def _kwhstat_wrapper(self) -> any:
cookies=self._cookies,
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
if "application/json" in response.headers.get("Content-Type", ""):
value_json = await response.json()
- self._kwh = value_json['stat']['period']['kwh']
- # LOGGER.warning("REPONSE ECOJOKO: %s", value_json)
- if self._use_hchp is True:
- self._kwh_hp_ns = value_json['stat']['period']['kwh_hp_ns']
- self._kwh_hc_ns = value_json['stat']['period']['kwh_hc_ns']
- else:
- LOGGER.debug("NE RETOURNE PAS DE HC/HP")
- if self._use_tempo is True:
- self._kwh_hp_ns = value_json['stat']['period']['kwh_hp_ns']
- self._kwh_hc_ns = value_json['stat']['period']['kwh_hc_ns']
- #63
- if self._current_pricing_details == "HC Bleu":
- if self.current_pricingzone == PricingZone.HC_EVENING:
- if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
- self._tempo_hc_blue = self._kwh_hc_ns - self._kwh_hc_night
- elif self._current_pricing_details == self._night_pricing_details:
- self._tempo_hc_blue = self._kwh_hc_ns
- # else:
- # self._tempo_hc_blue = self._kwh_hc_ns
- else:
- self._tempo_hc_blue = self._kwh_hc_ns
- self._kwh_hc_night = self._kwh_hc_ns
- elif self._current_pricing_details == "HP Bleu":
- self._tempo_hp_blue = self._kwh_hp_ns
- elif self._current_pricing_details == "HC Blanc":
- if self.current_pricingzone == PricingZone.HC_EVENING:
- if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
- self._tempo_hc_white = self._kwh_hc_ns - self._kwh_hc_night
- elif self._current_pricing_details == self._night_pricing_details:
- self._tempo_hc_white = self._kwh_hc_ns
- # else:
- # self._tempo_hc_white = self._kwh_hc_ns
- else:
- self._tempo_hc_white = self._kwh_hc_ns
- self._kwh_hc_night = self._kwh_hc_ns
- elif self._current_pricing_details == "HP Blanc":
- self._tempo_hp_white = self._kwh_hp_ns
- elif self._current_pricing_details == "HC Rouge":
- if self.current_pricingzone == PricingZone.HC_EVENING:
- if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
- self._tempo_hc_red = self._kwh_hc_ns - self._kwh_hc_night
- elif self._current_pricing_details == self._night_pricing_details:
- self._tempo_hc_red = self._kwh_hc_ns
- # else:
- # self._tempo_hc_red = self._kwh_hc_ns
- else:
- self._tempo_hc_red = self._kwh_hc_ns
- self._kwh_hc_night = self._kwh_hc_ns
- elif self._current_pricing_details == "HP Rouge":
- self._tempo_hp_red = self._kwh_hp_ns
- if self._use_prod is True:
- self._kwh_prod = -float(value_json['stat']['period']['kwh_prod'])
- else:
- LOGGER.debug("NE RETOURNE PAS DE PROD")
- response.raise_for_status()
- return await response.json()
+ if "period" in value_json['stat']:
+ self._kwh = value_json['stat']['period']['kwh']
+ if self._use_hchp is True:
+ self._kwh_hp_ns = value_json['stat']['period']['kwh_hp_ns']
+ self._kwh_hc_ns = value_json['stat']['period']['kwh_hc_ns']
+ # else:
+ # LOGGER.debug("NE RETOURNE PAS DE HC/HP")
+ if self._use_tempo is True:
+ self._kwh_hp_ns = value_json['stat']['period']['kwh_hp_ns']
+ self._kwh_hc_ns = value_json['stat']['period']['kwh_hc_ns']
+ #63
+ await self.Tempo()
+ # if self._current_pricing_details == "HC Bleu":
+ # if self.current_pricingzone == PricingZone.HC_EVENING:
+ # if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
+ # if (self._kwh_hc_ns - self._kwh_hc_night) >= 0:
+ # self._tempo_hc_blue = self._kwh_hc_ns - self._kwh_hc_night
+ # elif self._current_pricing_details == self._night_pricing_details:
+ # if self._kwh_hc_ns >= 0:
+ # self._tempo_hc_blue = self._kwh_hc_ns
+ # else:
+ # self._tempo_hc_blue = self._kwh_hc_ns
+ # self._kwh_hc_night = self._kwh_hc_ns
+ # elif self._current_pricing_details == "HP Bleu":
+ # self._tempo_hp_blue = self._kwh_hp_ns
+ # elif self._current_pricing_details == "HC Blanc":
+ # if self.current_pricingzone == PricingZone.HC_EVENING:
+ # if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
+ # if (self._kwh_hc_ns - self._kwh_hc_night) >= 0:
+ # self._tempo_hc_white = self._kwh_hc_ns - self._kwh_hc_night
+ # elif self._current_pricing_details == self._night_pricing_details:
+ # if self._kwh_hc_ns >= 0:
+ # self._tempo_hc_white = self._kwh_hc_ns
+ # else:
+ # self._tempo_hc_white = self._kwh_hc_ns
+ # self._kwh_hc_night = self._kwh_hc_ns
+ # elif self._current_pricing_details == "HP Blanc":
+ # self._tempo_hp_white = self._kwh_hp_ns
+ # elif self._current_pricing_details == "HC Rouge":
+ # if self.current_pricingzone == PricingZone.HC_EVENING:
+ # if self._kwh_hc_night is not None and self._current_pricing_details != self._night_pricing_details:
+ # if (self._kwh_hc_ns - self._kwh_hc_night) >= 0:
+ # self._tempo_hc_red = self._kwh_hc_ns - self._kwh_hc_night
+ # elif self._current_pricing_details == self._night_pricing_details:
+ # if self._kwh_hc_ns >= 0:
+ # self._tempo_hc_red = self._kwh_hc_ns
+ # else:
+ # self._tempo_hc_red = self._kwh_hc_ns
+ # self._kwh_hc_night = self._kwh_hc_ns
+ # elif self._current_pricing_details == "HP Rouge":
+ # self._tempo_hp_red = self._kwh_hp_ns
+ if self._use_prod is True:
+ self._kwh_prod = -float(value_json['stat']['period']['kwh_prod'])
+ # else:
+ # LOGGER.debug("NE RETOURNE PAS DE PROD")
+ #response.raise_for_status()
+ return
except asyncio.TimeoutError as exception:
LOGGER.error("API KWHSTAT timeout error")
@@ -741,11 +875,8 @@ async def _kwhstat_wrapper(self) -> any:
async def _tempstat_wrapper(self) -> any:
"""Get tempstat from the API."""
try:
- #59 bug fix
- # Get the current date
- current_date = datetime.date.today()
# Format the date as 'YYYY-MM-DD'
- formatted_date = current_date.strftime('%Y-%m-%d')
+ formatted_date = self._local_date.strftime('%Y-%m-%d')
url = ECOJOKO_GATEWAY_URL + f"/{self._gateway_id}/device/{self._temp_hum_id}/tempstat/d4/{formatted_date}"
async with async_timeout.timeout(CONF_API_TIMEOUT):
response = await self._session.get(
@@ -754,20 +885,23 @@ async def _tempstat_wrapper(self) -> any:
cookies=self._cookies,
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
if "application/json" in response.headers.get("Content-Type", ""):
value_json = await response.json()
- if len(value_json['stat']['data']) > 1:
- self._indoor_temp = value_json['stat']['data'][-1]['value']
- self._outdoor_temp = value_json['stat']['data'][-1]['ext_value']
- else:
- # LOGGER.debug("TEMP UNE SEULE VALEUR: %s", value_json)
- self._indoor_temp = value_json['stat']['data']['value']
- self._outdoor_temp = value_json['stat']['data']['ext_value']
- response.raise_for_status()
- return await response.json()
+ if "data" in value_json['stat']:
+ if len(value_json['stat']['data']) > 1:
+ self._indoor_temp = value_json['stat']['data'][-1]['value']
+ self._outdoor_temp = value_json['stat']['data'][-1]['ext_value']
+ else:
+ # LOGGER.debug("TEMP UNE SEULE VALEUR: %s", value_json)
+ self._indoor_temp = value_json['stat']['data']['value']
+ self._outdoor_temp = value_json['stat']['data']['ext_value']
+ #response.raise_for_status()
+ return
except asyncio.TimeoutError as exception:
LOGGER.error("API TEMPSTAT timeout error")
@@ -788,11 +922,8 @@ async def _tempstat_wrapper(self) -> any:
async def _humstat_wrapper(self) -> any:
"""Get humstat from the API."""
try:
- #59 bug fix
- # Get the current date
- current_date = datetime.date.today()
# Format the date as 'YYYY-MM-DD'
- formatted_date = current_date.strftime('%Y-%m-%d')
+ formatted_date = self._local_date.strftime('%Y-%m-%d')
url = ECOJOKO_GATEWAY_URL + f"/{self._gateway_id}/device/{self._temp_hum_id}/humstat/d4/{formatted_date}"
async with async_timeout.timeout(CONF_API_TIMEOUT):
response = await self._session.get(
@@ -801,20 +932,23 @@ async def _humstat_wrapper(self) -> any:
cookies=self._cookies,
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
if "application/json" in response.headers.get("Content-Type", ""):
value_json = await response.json()
- if len(value_json['stat']['data']) > 1:
- self._indoor_hum = value_json['stat']['data'][-1]['value']
- self._outdoor_hum = value_json['stat']['data'][-1]['ext_value']
- else:
- # LOGGER.debug("HUM UNE SEULE VALEUR: %s", value_json)
- self._indoor_hum = value_json['stat']['data']['value']
- self._outdoor_hum = value_json['stat']['data']['ext_value']
- response.raise_for_status()
- return await response.json()
+ if "data" in value_json['stat']:
+ if len(value_json['stat']['data']) > 1:
+ self._indoor_hum = value_json['stat']['data'][-1]['value']
+ self._outdoor_hum = value_json['stat']['data'][-1]['ext_value']
+ else:
+ # LOGGER.debug("HUM UNE SEULE VALEUR: %s", value_json)
+ self._indoor_hum = value_json['stat']['data']['value']
+ self._outdoor_hum = value_json['stat']['data']['ext_value']
+ #response.raise_for_status()
+ return
except asyncio.TimeoutError as exception:
LOGGER.error("API HUMSTAT timeout error")
@@ -836,10 +970,8 @@ async def _powerstat_wrapper(self, pricing_details) -> any:
"""Get powerstat from the API."""
try:
result = None
- # Get the current date
- current_date = datetime.date.today()
# Format the date as 'YYYY-MM-DD'
- formatted_date = current_date.strftime('%Y-%m-%d')
+ formatted_date = self._local_date.strftime('%Y-%m-%d')
url = ECOJOKO_GATEWAY_URL + f"/{self._gateway_id}/device/{self._power_meter_id}/powerstat/w/{formatted_date}"
async with async_timeout.timeout(CONF_API_TIMEOUT):
response = await self._session.get(
@@ -848,18 +980,22 @@ async def _powerstat_wrapper(self, pricing_details) -> any:
cookies=self._cookies,
)
if response.status in (401, 403):
+ #71 bug fix
+ self._cookies = None
raise LittleMonkeyApiClientAuthenticationError(
"Invalid credentials",
)
+ result = None
if "application/json" in response.headers.get("Content-Type", ""):
value_json = await response.json()
- week_day = self._current_date.weekday()
- if len(value_json['stat']['data']) > week_day:
- for subconscomption in value_json['stat']['data'][week_day]['subconsumption']:
- if subconscomption['label'] == pricing_details:
- result = subconscomption['kwh']
- break
- return result
+ if "data" in value_json['stat']:
+ week_day = self._local_date.weekday()
+ if len(value_json['stat']['data']) > week_day:
+ for subconscomption in value_json['stat']['data'][week_day]['subconsumption']:
+ if subconscomption['label'] == pricing_details:
+ result = subconscomption['kwh']
+ break
+ return result
except asyncio.TimeoutError as exception:
LOGGER.error("API HUMSTAT timeout error")
diff --git a/custom_components/little_monkey/config_flow.py b/custom_components/little_monkey/config_flow.py
index fbe1304..38cacd9 100644
--- a/custom_components/little_monkey/config_flow.py
+++ b/custom_components/little_monkey/config_flow.py
@@ -22,6 +22,7 @@
DOMAIN,
POLL_INTERVAL,
DEFAULT_POLL_INTERVAL,
+ CONF_USE_LAST_MEASURE_FEATURE,
CONF_USE_HCHP_FEATURE,
CONF_USE_TEMPO_FEATURE,
CONF_USE_TEMPHUM_FEATURE,
@@ -48,6 +49,9 @@ def _get_data_schema(config_entry: config_entries.ConfigEntry | None = None) ->
type=selector.TextSelectorType.PASSWORD
),
),
+ vol.Optional(
+ CONF_USE_LAST_MEASURE_FEATURE, default=False,
+ ): cv.boolean,
vol.Optional(
CONF_USE_HCHP_FEATURE, default=False,
): cv.boolean,
@@ -97,6 +101,9 @@ def _get_data_schema(config_entry: config_entries.ConfigEntry | None = None) ->
type=selector.TextSelectorType.PASSWORD
),
),
+ vol.Optional(
+ CONF_USE_LAST_MEASURE_FEATURE, default=config_entry.data.get(CONF_USE_LAST_MEASURE_FEATURE),
+ ): cv.boolean,
vol.Optional(
CONF_USE_HCHP_FEATURE, default=config_entry.data.get(CONF_USE_HCHP_FEATURE),
): cv.boolean,
@@ -151,6 +158,7 @@ async def async_step_user(
await self._get_cookies(
username=user_input[CONF_USERNAME],
password=user_input[CONF_PASSWORD],
+ use_last_measure=user_input[CONF_USE_LAST_MEASURE_FEATURE],
use_hchp=user_input[CONF_USE_HCHP_FEATURE],
use_tempo=user_input[CONF_USE_TEMPO_FEATURE],
use_temphum=user_input[CONF_USE_TEMPHUM_FEATURE],
@@ -178,10 +186,11 @@ async def async_step_user(
errors=_errors,
)
- async def _get_cookies(self, username: str, password: str, use_hchp: bool, use_temphum: bool, use_tempo: bool, use_prod: bool) -> None:
+ async def _get_cookies(self, username: str, password: str, use_last_measure: bool, use_hchp: bool, use_temphum: bool, use_tempo: bool, use_prod: bool) -> None:
client = LittleMonkeyApiClient(
username=username,
password=password,
+ use_last_measure=use_last_measure,
use_hchp=use_hchp,
use_tempo=use_tempo,
use_temphum=use_temphum,
@@ -223,6 +232,7 @@ async def async_step_init(
client = await self._get_cookies(
username=user_input[CONF_USERNAME],
password=user_input[CONF_PASSWORD],
+ use_last_measure=user_input[CONF_USE_LAST_MEASURE_FEATURE],
use_hchp=user_input[CONF_USE_HCHP_FEATURE],
use_tempo=user_input[CONF_USE_TEMPO_FEATURE],
use_temphum=user_input[CONF_USE_TEMPHUM_FEATURE],
@@ -246,10 +256,11 @@ async def async_step_init(
errors=self._errors,
)
- async def _get_cookies(self, username: str, password: str, use_hchp: bool, use_tempo: bool, use_temphum: bool, use_prod: bool) -> LittleMonkeyApiClient:
+ async def _get_cookies(self, username: str, password: str, use_last_measure: bool, use_hchp: bool, use_tempo: bool, use_temphum: bool, use_prod: bool) -> LittleMonkeyApiClient:
client = LittleMonkeyApiClient(
username=username,
password=password,
+ use_last_measure=use_last_measure,
use_hchp=use_hchp,
use_tempo=use_tempo,
use_temphum=use_temphum,
diff --git a/custom_components/little_monkey/const.py b/custom_components/little_monkey/const.py
index 50a689a..9f89845 100644
--- a/custom_components/little_monkey/const.py
+++ b/custom_components/little_monkey/const.py
@@ -7,7 +7,7 @@
DOMAIN = "little_monkey"
MANUFACTURER = "Jean-Marc Cruvellier"
MODEL = "Ecojoko"
-VERSION = "1.0.1"
+VERSION = "1.1.0"
ATTRIBUTION = "Data provided by https://service.ecojoko.com//"
POLL_INTERVAL = "poll_interval"
DEFAULT_POLL_INTERVAL = "5"
@@ -17,6 +17,7 @@
CONF_USE_TEMPO_FEATURE = "use_tempo_feature"
CONF_USE_TEMPHUM_FEATURE = "use_temphum_feature"
CONF_USE_PROD_FEATURE = "use_prod_feature"
+CONF_USE_LAST_MEASURE_FEATURE = "use_last_measure_feature"
CONF_LANG = 'lang'
DEFAULT_LANG = 'fr-FR'
# Language Supported Codes
diff --git a/custom_components/little_monkey/coordinator.py b/custom_components/little_monkey/coordinator.py
index 2d5e7e4..f49ac4d 100644
--- a/custom_components/little_monkey/coordinator.py
+++ b/custom_components/little_monkey/coordinator.py
@@ -79,6 +79,10 @@ async def _async_update_data(self):
"grid_consumption": self.client.kwh,
"hc_grid_consumption": self.client.kwh_hc_ns,
"hp_grid_consumption": self.client.kwh_hp_ns,
+ "last_consumption_measure": self.client.last_consumption_measure,
+ "last_grid_consumption_measure": self.client.last_kwh,
+ "last_hc_grid_consumption_measure": self.client.last_kwh_hc_ns,
+ "last_hp_grid_consumption_measure": self.client.last_kwh_hp_ns,
"blue_hc_grid_consumption": self.client.tempo_hc_blue,
"blue_hp_grid_consumption": self.client.tempo_hp_blue,
"white_hc_grid_consumption": self.client.tempo_hc_white,
diff --git a/custom_components/little_monkey/little_monkey_translations/en.json b/custom_components/little_monkey/little_monkey_translations/en.json
index 6f1ee2f..32f9f1a 100644
--- a/custom_components/little_monkey/little_monkey_translations/en.json
+++ b/custom_components/little_monkey/little_monkey_translations/en.json
@@ -13,5 +13,9 @@
"indoor_temp": "Indoor Temperature",
"outdoor_temp": "Outdoor Temperature",
"indoor_hum": "Indoor Humidity",
- "outdoor_hum": "Outdoor Humidity"
+ "outdoor_hum": "Outdoor Humidity",
+ "last_consumption_measure": "Last Consumption Measure",
+ "last_grid_consumption_measure": "Last Grid Consumption Measure",
+ "last_hc_grid_consumption_measure": "Last HC Grid Consumption Measure",
+ "last_hp_grid_consumption_measure": "Last HP Grid Consumption Measure"
}
\ No newline at end of file
diff --git a/custom_components/little_monkey/little_monkey_translations/fr.json b/custom_components/little_monkey/little_monkey_translations/fr.json
index e7274b3..d62b693 100644
--- a/custom_components/little_monkey/little_monkey_translations/fr.json
+++ b/custom_components/little_monkey/little_monkey_translations/fr.json
@@ -13,5 +13,9 @@
"indoor_temp": "Température Intérieure",
"outdoor_temp": "Température Extérieure",
"indoor_hum": "Humidité Intérieure",
- "outdoor_hum": "Humidité Extérieure"
+ "outdoor_hum": "Humidité Extérieure",
+ "last_consumption_measure": "Consommation Dernière Mesure",
+ "last_grid_consumption_measure": "Consommation Réseau Dernière Mesure",
+ "last_hc_grid_consumption_measure": "Consommation HC Réseau Dernière Mesure",
+ "last_hp_grid_consumption_measure": "Consommation HP Réseau Dernière Mesure"
}
\ No newline at end of file
diff --git a/custom_components/little_monkey/manifest.json b/custom_components/little_monkey/manifest.json
index 72f6a3d..7b0b6ec 100644
--- a/custom_components/little_monkey/manifest.json
+++ b/custom_components/little_monkey/manifest.json
@@ -5,9 +5,9 @@
"@jmcruvellier"
],
"config_flow": true,
- "documentation": "https://github.com/jmcruvellier/little_monkey/blob/v0.1.1/README.md",
+ "documentation": "https://github.com/jmcruvellier/little_monkey/blob/v1.1.0/README.md",
"integration_type": "device",
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/jmcruvellier/little_monkey/issues",
- "version": "1.0.1"
+ "version": "1.1.0"
}
\ No newline at end of file
diff --git a/custom_components/little_monkey/sensor.py b/custom_components/little_monkey/sensor.py
index c62b5cb..230d067 100644
--- a/custom_components/little_monkey/sensor.py
+++ b/custom_components/little_monkey/sensor.py
@@ -13,7 +13,8 @@
CONF_USE_HCHP_FEATURE,
CONF_USE_TEMPO_FEATURE,
CONF_USE_TEMPHUM_FEATURE,
- CONF_USE_PROD_FEATURE
+ CONF_USE_PROD_FEATURE,
+ CONF_USE_LAST_MEASURE_FEATURE
)
async def async_setup_entry(hass, config_entry, async_add_entities):
@@ -148,4 +149,30 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
PERCENTAGE,
"mdi:water"))
+ # Last Consumption Measure sensor
+ if config_entry.data.get(CONF_USE_LAST_MEASURE_FEATURE) is True:
+ main_device.add_child_entity(EcojokoSensor(
+ main_device,
+ "last_consumption_measure",
+ SensorStateClass.MEASUREMENT,
+ SensorDeviceClass.POWER,
+ UnitOfPower.WATT,
+ "mdi:flash"))
+ # Last HC/HP grid consumption measure sensors
+ if config_entry.data.get(CONF_USE_HCHP_FEATURE) is True:
+ main_device.add_child_entity(EcojokoSensor(
+ main_device,
+ "last_hc_grid_consumption_measure",
+ SensorStateClass.TOTAL_INCREASING,
+ SensorDeviceClass.ENERGY,
+ UnitOfEnergy.KILO_WATT_HOUR,
+ "mdi:lightning-bolt"))
+ main_device.add_child_entity(EcojokoSensor(
+ main_device,
+ "last_hp_grid_consumption_measure",
+ SensorStateClass.TOTAL_INCREASING,
+ SensorDeviceClass.ENERGY,
+ UnitOfEnergy.KILO_WATT_HOUR,
+ "mdi:lightning-bolt"))
+
async_add_entities([main_device] + main_device.child_entities)
diff --git a/custom_components/little_monkey/translations/en.json b/custom_components/little_monkey/translations/en.json
index 5b2df8b..ddfab7a 100644
--- a/custom_components/little_monkey/translations/en.json
+++ b/custom_components/little_monkey/translations/en.json
@@ -8,6 +8,7 @@
"name": "Name",
"username": "Username",
"password": "Password",
+ "use_last_measure_feature": "Last measure sensors",
"use_hchp_feature": "HP/HC sensors",
"use_tempo_feature": "Tempo Blue/White/Red sensors",
"use_temphum_feature": "Humidity and temperature sensors",
@@ -30,6 +31,7 @@
"name": "Name",
"username": "Username",
"password": "Password",
+ "use_last_measure_feature": "Last measure sensors",
"use_hchp_feature": "HP/HC sensors",
"use_tempo_feature": "Tempo Blue/White/Red sensors",
"use_temphum_feature": "Humidity and temperature sensors",
diff --git a/custom_components/little_monkey/translations/fr.json b/custom_components/little_monkey/translations/fr.json
index 7b79f08..3d0b9b4 100644
--- a/custom_components/little_monkey/translations/fr.json
+++ b/custom_components/little_monkey/translations/fr.json
@@ -8,6 +8,7 @@
"name": "Nom",
"username": "Nom d'utilisateur",
"password": "Mot de passe",
+ "use_last_measure_feature": "Capteurs de dernières mesures",
"use_hchp_feature": "Capteurs HP/HC",
"use_tempo_feature": "Capteurs Tempo Bleu/Blanc/Rouge",
"use_temphum_feature": "Capteurs d'humidité et de température",
@@ -30,6 +31,7 @@
"name": "Nom",
"username": "Nom d'utilisateur",
"password": "Mot de passe",
+ "use_last_measure_feature": "Capteurs de dernières mesures",
"use_hchp_feature": "Capteurs HP/HC",
"use_tempo_feature": "Capteurs Tempo Bleu/Blanc/Rouge",
"use_temphum_feature": "Capteurs d'humidité et de température",
diff --git a/info.md b/info.md
index 353918c..4df1f27 100644
--- a/info.md
+++ b/info.md
@@ -1,3 +1,8 @@
+[![CodeQL](https://github.com/jmcruvellier/little_monkey/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/github-code-scanning/codeql)
+[![HACS](https://github.com/jmcruvellier/little_monkey/actions/workflows/hacs.yaml/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/hacs.yaml)
+[![hassfest](https://github.com/jmcruvellier/little_monkey/actions/workflows/hassfest.yaml/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/hassfest.yaml)
+[![Validate](https://github.com/jmcruvellier/little_monkey/actions/workflows/validate.yml/badge.svg)](https://github.com/jmcruvellier/little_monkey/actions/workflows/validate.yml)
+
![](/custom_components/little_monkey/res/logo_small.png)
# Little Monkey / Petit Singe
@@ -5,24 +10,27 @@ Cette intégration vous permet de récupérer les informations collectées par v
Elle intègre dans Home Assistant les capteurs suivants:
-* Consommation Temps Réel (Puissance en W)
-* Consommation Réseau (Energie en kWh)
-* Si vous avez un contrat d'énergie HC/HP
- - Consommation HC Réseau (Energie en kWh)
- - Consommation HP Réseau (Energie en kWh)
- - Si c'est un contrat Tempo:
- - Consommation HC Bleu Réseau (Energie en kWh)
- - Consommation HP Bleu Réseau (Energie en kWh)
- - Consommation HC Blanc Réseau (Energie en kWh)
- - Consommation HP Blanc Réseau (Energie en kWh)
- - Consommation HC Rouge Réseau (Energie en kWh)
- - Consommation HP Rouge Réseau (Energie en kWh)
-* Si vous êtes producteur d'énergie grâce à des panneaux photovoltaïques et possesseur d'un capteur ecojoko ancienne génération:
- - Surplus de Production (Energie en kWh)
-* Température Intérieure (en °C)
-* Température Extérieure (en °C)
-* Humidité Intérieure (en %)
-* Humidité Extérieure (en %)
+| Version | Capteur | Type | Unité | Disponibilité | Commentaire |
+| ------- | ------- | ---- | ----- | ------------- | ----------- |
+| 1.0.0 | Consommation Temps Réel | Puissance | W | Permanent | |
+| 1.0.0 | Consommation Réseau | Energie | kWh | Permanent | |
+| 1.0.0 | Consommation HC Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie incluant les HC/HP |
+| 1.0.0 | Consommation HP Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie incluant les HC/HP |
+| 1.0.0 | Consommation HC Bleu Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HP Bleu Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HC Blanc Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HP Blanc Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HC Rouge Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Consommation HP Rouge Réseau | Energie | kWh | Optionnel | Si vous avez un contrat d'énergie Tempo |
+| 1.0.0 | Surplus de Production | Energie | kWh | Optionnel | Si vous êtes producteur d'énergie grâce à des panneaux photovoltaïques et possesseur d'un capteur ecojoko ancienne génération |
+| 1.0.0 | Température Intérieure | Température | °C | Optionnel | |
+| 1.0.0 | Température Extérieure | Température | °C | Optionnel | |
+| 1.0.0 | Humidité Intérieure | Humidité | % | Optionnel | |
+| 1.0.0 | Humidité Extérieure | Humidité | % | Optionnel | |
+| 1.1.0 | Consommation Dernière Mesure | Puissance | W | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
+| 1.1.0 | Consommation Réseau Dernière Mesure | Energie | kWh | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
+| 1.1.0 | Consommation HC Réseau Dernière Mesure | Energie | kWh | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
+| 1.1.0 | Consommation HP Réseau Dernière Mesure | Energie | kWh | Optionnel | Dernière valeur retournée dans la section Mesures de l'application ecojoko |
> [!IMPORTANT]
> Si vous êtes un utilisateur régulier de l'application ecojoko©️, vous n'êtes pas sans savoir que le petit singe glisse souvent sur sa peau de banane. **Cette __intégration non-officielle__ dépend des APIs d'ecojoko©️ et n'est donc pas responsable en cas d'indisponibilité de vos donnés.**