From f71ce5344d765f59246b01dd1e286d60779fe3ab Mon Sep 17 00:00:00 2001 From: cddu33 <59371705+cddu33@users.noreply.github.com> Date: Wed, 16 Aug 2023 16:33:13 +0200 Subject: [PATCH 1/8] add import and export index from ivp/meters/readings --- .../enphase_envoy_custom/__init__.py | 8 ++ .../enphase_envoy_custom/const.py | 56 +++++++++++++ .../enphase_envoy_custom/envoy_reader.py | 79 ++++++++++++++++++- .../enphase_envoy_custom/translations/fr.json | 15 +++- 4 files changed, 154 insertions(+), 4 deletions(-) diff --git a/custom_components/enphase_envoy_custom/__init__.py b/custom_components/enphase_envoy_custom/__init__.py index 5bea10b..a47da0e 100644 --- a/custom_components/enphase_envoy_custom/__init__.py +++ b/custom_components/enphase_envoy_custom/__init__.py @@ -113,6 +113,14 @@ async def async_update_data(): data[ description.key ] = await envoy_reader.lifetime_consumption_phase(description.key) + elif description.key.startswith("import_index_"): + data[ + description.key + ] = await envoy_reader.import_index_phase(description.key) + elif description.key.startswith("export_index_"): + data[ + description.key + ] = await envoy_reader.export_index_phase(description.key) data["grid_status"] = await envoy_reader.grid_status() data["envoy_info"] = await envoy_reader.envoy_info() diff --git a/custom_components/enphase_envoy_custom/const.py b/custom_components/enphase_envoy_custom/const.py index 9a691f2..baabc12 100644 --- a/custom_components/enphase_envoy_custom/const.py +++ b/custom_components/enphase_envoy_custom/const.py @@ -112,6 +112,20 @@ state_class=SensorStateClass.TOTAL, device_class=SensorDeviceClass.ENERGY ), + SensorEntityDescription( + key="import_index", + name="Index Import", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), + SensorEntityDescription( + key="export_index", + name="Index Export", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), ) BINARY_SENSORS = ( @@ -243,6 +257,48 @@ state_class=SensorStateClass.TOTAL_INCREASING, device_class=SensorDeviceClass.ENERGY, ), + SensorEntityDescription( + key="import_index_l1", + name="Index Import L1", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), + SensorEntityDescription( + key="export_index_l1", + name="Index Export L1", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), + SensorEntityDescription( + key="import_index_l2", + name="Index Import L2", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), + SensorEntityDescription( + key="export_index_l2", + name="Index Export L2", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), + SensorEntityDescription( + key="import_index_l3", + name="Index Import L3", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), + SensorEntityDescription( + key="export_index_l3", + name="Index Export L3", + native_unit_of_measurement=UnitOfEnergy.WATT_HOUR, + state_class=SensorStateClass.TOTAL_INCREASING, + device_class=SensorDeviceClass.ENERGY, + ), ) BATTERY_ENERGY_DISCHARGED_SENSOR = SensorEntityDescription( diff --git a/custom_components/enphase_envoy_custom/envoy_reader.py b/custom_components/enphase_envoy_custom/envoy_reader.py index 39f6d8e..5117322 100644 --- a/custom_components/enphase_envoy_custom/envoy_reader.py +++ b/custom_components/enphase_envoy_custom/envoy_reader.py @@ -34,6 +34,7 @@ ENDPOINT_URL_ENSEMBLE_INVENTORY = "http{}://{}/ivp/ensemble/inventory" ENDPOINT_URL_HOME_JSON = "http{}://{}/home.json" ENDPOINT_URL_INFO_XML = "http{}://{}/info" +ENDPOINT_URL_METERS = "http{}://{}/ivp/meters/readings" # pylint: disable=pointless-string-statement @@ -119,6 +120,7 @@ def __init__( # pylint: disable=too-many-arguments self.endpoint_production_json_results = None self.endpoint_production_v1_results = None self.endpoint_production_inverters = None + self.endpoint_meters_json_results = None self.endpoint_production_results = None self.endpoint_ensemble_json_results = None self.endpoint_home_json_results = None @@ -196,6 +198,9 @@ async def _update_from_pc_endpoint(self): await self._update_endpoint( "endpoint_ensemble_json_results", ENDPOINT_URL_ENSEMBLE_INVENTORY ) + await self._update_endpoint( + "endpoint_meters_json_results", ENDPOINT_URL_METERS + ) if self.has_grid_status: await self._update_endpoint( "endpoint_home_json_results", ENDPOINT_URL_HOME_JSON @@ -902,6 +907,70 @@ async def battery_storage(self): return raw_json["storage"][0] + async def import_index(self): + """import index""" + """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" + """so that this method will only read data from stored variables""" + + if self.endpoint_type == ENVOY_MODEL_S: + raw_json = self.endpoint_meters_json_results.json() + index_imp = raw_json[1]["actEnergyDlvd"] + return int(index_imp) + else: + raise RuntimeError("No match for import index, check REGEX " + text) + return None + + + async def import_index_phase(self, phase): + """import index""" + """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" + """so that this method will only read data from stored variables""" + phase_map = {"import_index_l1": 0, "import_index_l2": 1, "import_index_l3": 2} + + if self.endpoint_type == ENVOY_MODEL_S: + raw_json = self.endpoint_meters_json_results.json() + try: + return int( + raw_json[1]["channels"][phase_map[phase]]["actEnergyDlvd"] + ) + except (KeyError, IndexError): + return None + + return None + + async def export_index(self): + """import export""" + """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" + """so that this method will only read data from stored variables""" + + if self.endpoint_type == ENVOY_MODEL_S: + raw_json = self.endpoint_meters_json_results.json() + index_exp = raw_json[1]['actEnergyRcvd'] + return int(index_exp) + + else: + raise RuntimeError("No match for export index, check REGEX " + text) + return None + + + async def export_index_phase(self, phase): + """import export""" + """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" + """so that this method will only read data from stored variables""" + phase_map = {"export_index_l1": 0, "export_index_l2": 1, "export_index_l3": 2} + + if self.endpoint_type == ENVOY_MODEL_S: + raw_json = self.endpoint_meters_json_results.json() + try: + return int( + raw_json[1]["channels"][phase_map[phase]]["actEnergyRcvd"] + ) + except (KeyError, IndexError): + return None + + return None + + async def grid_status(self): """Return grid status reported by Envoy""" if self.has_grid_status and self.endpoint_home_json_results is not None: @@ -998,6 +1067,8 @@ def run_in_console(self): self.seven_days_consumption(), self.lifetime_production(), self.lifetime_consumption(), + self.import_index(), + self.export_index(), self.inverters_production(), self.battery_storage(), return_exceptions=False, @@ -1012,17 +1083,19 @@ def run_in_console(self): print(f"seven_days_consumption: {results[5]}") print(f"lifetime_production: {results[6]}") print(f"lifetime_consumption: {results[7]}") + print(f"index_import: {results[8]}") + print(f"index_export: {results[9]}") if "401" in str(data_results): print( "inverters_production: Unable to retrieve inverter data - Authentication failure" ) - elif results[8] is None: + elif results[10] is None: print( "inverters_production: Inverter data not available for your Envoy device." ) else: - print(f"inverters_production: {results[8]}") - print(f"battery_storage: {results[9]}") + print(f"inverters_production: {results[10]}") + print(f"battery_storage: {results[11]}") if __name__ == "__main__": diff --git a/custom_components/enphase_envoy_custom/translations/fr.json b/custom_components/enphase_envoy_custom/translations/fr.json index e9a7803..1ce8bf0 100644 --- a/custom_components/enphase_envoy_custom/translations/fr.json +++ b/custom_components/enphase_envoy_custom/translations/fr.json @@ -21,5 +21,18 @@ } } } - } + }, + "options": { + "step": { + "user": { + "title": "Options Envoy", + "data": { + "data_interval": "Temps entre 2 rafraichissement [s]" + }, + "data_description": { + "data_interval": "Temps entre 2 rafraichissement, minimum 5 sec. Relancer apres un changement" + } + } + } + } } \ No newline at end of file From f300afe4183a434d9773563a09f5200ad1bf03db Mon Sep 17 00:00:00 2001 From: cddu33 <59371705+cddu33@users.noreply.github.com> Date: Wed, 16 Aug 2023 23:23:57 +0200 Subject: [PATCH 2/8] Only support Import Export Index for ENVOY Metered Deactivate import export for model s and legacy --- .../enphase_envoy_custom/envoy_reader.py | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/custom_components/enphase_envoy_custom/envoy_reader.py b/custom_components/enphase_envoy_custom/envoy_reader.py index 5117322..8375d45 100644 --- a/custom_components/enphase_envoy_custom/envoy_reader.py +++ b/custom_components/enphase_envoy_custom/envoy_reader.py @@ -76,6 +76,10 @@ class EnvoyReader: # pylint: disable=too-many-instance-attributes message_battery_not_available = ( "Battery storage data not available for your Envoy device." ) + + message_import_export_not_available = ( + "Import Export data not available for your Envoy device." + ) message_consumption_not_available = ( "Consumption data not available for your Envoy device." @@ -911,30 +915,28 @@ async def import_index(self): """import index""" """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" """so that this method will only read data from stored variables""" - - if self.endpoint_type == ENVOY_MODEL_S: - raw_json = self.endpoint_meters_json_results.json() - index_imp = raw_json[1]["actEnergyDlvd"] - return int(index_imp) - else: - raise RuntimeError("No match for import index, check REGEX " + text) - return None - + if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: + return self.message_import_export_not_available + + raw_json = self.endpoint_meters_json_results.json() + index_imp = raw_json[1]["actEnergyDlvd"] + return int(index_imp) async def import_index_phase(self, phase): """import index""" """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" """so that this method will only read data from stored variables""" phase_map = {"import_index_l1": 0, "import_index_l2": 1, "import_index_l3": 2} - - if self.endpoint_type == ENVOY_MODEL_S: - raw_json = self.endpoint_meters_json_results.json() - try: - return int( - raw_json[1]["channels"][phase_map[phase]]["actEnergyDlvd"] - ) - except (KeyError, IndexError): - return None + if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: + return self.message_import_export_not_available + + raw_json = self.endpoint_meters_json_results.json() + try: + return int( + raw_json[1]["channels"][phase_map[phase]]["actEnergyDlvd"] + ) + except (KeyError, IndexError): + return None return None @@ -942,34 +944,32 @@ async def export_index(self): """import export""" """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" """so that this method will only read data from stored variables""" - - if self.endpoint_type == ENVOY_MODEL_S: - raw_json = self.endpoint_meters_json_results.json() - index_exp = raw_json[1]['actEnergyRcvd'] - return int(index_exp) - - else: - raise RuntimeError("No match for export index, check REGEX " + text) - return None - + + if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: + return self.message_import_export_not_available + + raw_json = self.endpoint_meters_json_results.json() + index_exp = raw_json[1]['actEnergyRcvd'] + return int(index_exp) async def export_index_phase(self, phase): """import export""" """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" """so that this method will only read data from stored variables""" phase_map = {"export_index_l1": 0, "export_index_l2": 1, "export_index_l3": 2} + + if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: + return self.message_import_export_not_available + + raw_json = self.endpoint_meters_json_results.json() + try: + return int( + raw_json[1]["channels"][phase_map[phase]]["actEnergyRcvd"] + ) + except (KeyError, IndexError): + return None - if self.endpoint_type == ENVOY_MODEL_S: - raw_json = self.endpoint_meters_json_results.json() - try: - return int( - raw_json[1]["channels"][phase_map[phase]]["actEnergyRcvd"] - ) - except (KeyError, IndexError): - return None - - return None - + return None async def grid_status(self): """Return grid status reported by Envoy""" From e9cbe0648bf56d44528c33b10cb3492b957cc9e3 Mon Sep 17 00:00:00 2001 From: cddu33 <59371705+cddu33@users.noreply.github.com> Date: Wed, 16 Aug 2023 23:30:32 +0200 Subject: [PATCH 3/8] Fix indentation in Export Index phase 931 return --- custom_components/enphase_envoy_custom/envoy_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/enphase_envoy_custom/envoy_reader.py b/custom_components/enphase_envoy_custom/envoy_reader.py index 8375d45..ef87791 100644 --- a/custom_components/enphase_envoy_custom/envoy_reader.py +++ b/custom_components/enphase_envoy_custom/envoy_reader.py @@ -969,7 +969,7 @@ async def export_index_phase(self, phase): except (KeyError, IndexError): return None - return None + return None async def grid_status(self): """Return grid status reported by Envoy""" From 11e807305b7223e67a220e598ec0277518502026 Mon Sep 17 00:00:00 2001 From: cddu33 <59371705+cddu33@users.noreply.github.com> Date: Thu, 17 Aug 2023 13:26:56 +0200 Subject: [PATCH 4/8] return none for import export for C and Legacy, or if voltage < 50 --- .../enphase_envoy_custom/envoy_reader.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/custom_components/enphase_envoy_custom/envoy_reader.py b/custom_components/enphase_envoy_custom/envoy_reader.py index ef87791..2aebe69 100644 --- a/custom_components/enphase_envoy_custom/envoy_reader.py +++ b/custom_components/enphase_envoy_custom/envoy_reader.py @@ -76,10 +76,6 @@ class EnvoyReader: # pylint: disable=too-many-instance-attributes message_battery_not_available = ( "Battery storage data not available for your Envoy device." ) - - message_import_export_not_available = ( - "Import Export data not available for your Envoy device." - ) message_consumption_not_available = ( "Consumption data not available for your Envoy device." @@ -916,7 +912,7 @@ async def import_index(self): """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" """so that this method will only read data from stored variables""" if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: - return self.message_import_export_not_available + return None raw_json = self.endpoint_meters_json_results.json() index_imp = raw_json[1]["actEnergyDlvd"] @@ -928,8 +924,9 @@ async def import_index_phase(self, phase): """so that this method will only read data from stored variables""" phase_map = {"import_index_l1": 0, "import_index_l2": 1, "import_index_l3": 2} if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: - return self.message_import_export_not_available - + return None + if raw_json[1]["channels"][1]["voltage"] < 50: + return None raw_json = self.endpoint_meters_json_results.json() try: return int( @@ -946,7 +943,7 @@ async def export_index(self): """so that this method will only read data from stored variables""" if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: - return self.message_import_export_not_available + return None raw_json = self.endpoint_meters_json_results.json() index_exp = raw_json[1]['actEnergyRcvd'] @@ -959,7 +956,9 @@ async def export_index_phase(self, phase): phase_map = {"export_index_l1": 0, "export_index_l2": 1, "export_index_l3": 2} if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: - return self.message_import_export_not_available + return None + if raw_json[1]["channels"][1]["voltage"] < 50: + return None raw_json = self.endpoint_meters_json_results.json() try: From 445f83f0f2ea0615282671c2a6a581662245ddb3 Mon Sep 17 00:00:00 2001 From: cddu33 <59371705+cddu33@users.noreply.github.com> Date: Thu, 17 Aug 2023 13:35:01 +0200 Subject: [PATCH 5/8] Fix accessing raw json for Import Export Index --- custom_components/enphase_envoy_custom/envoy_reader.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_components/enphase_envoy_custom/envoy_reader.py b/custom_components/enphase_envoy_custom/envoy_reader.py index 2aebe69..3231a03 100644 --- a/custom_components/enphase_envoy_custom/envoy_reader.py +++ b/custom_components/enphase_envoy_custom/envoy_reader.py @@ -925,9 +925,10 @@ async def import_index_phase(self, phase): phase_map = {"import_index_l1": 0, "import_index_l2": 1, "import_index_l3": 2} if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: return None + + raw_json = self.endpoint_meters_json_results.json() if raw_json[1]["channels"][1]["voltage"] < 50: return None - raw_json = self.endpoint_meters_json_results.json() try: return int( raw_json[1]["channels"][phase_map[phase]]["actEnergyDlvd"] @@ -957,10 +958,11 @@ async def export_index_phase(self, phase): if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: return None + + raw_json = self.endpoint_meters_json_results.json() if raw_json[1]["channels"][1]["voltage"] < 50: return None - raw_json = self.endpoint_meters_json_results.json() try: return int( raw_json[1]["channels"][phase_map[phase]]["actEnergyRcvd"] From ed49389a5573216f813067f45fbf5a4fa17bf4f5 Mon Sep 17 00:00:00 2001 From: Arie Catsman Date: Tue, 22 Aug 2023 18:24:54 +0200 Subject: [PATCH 6/8] Return not available for overall import export. add meters endpoint to diagnostics --- .../enphase_envoy_custom/envoy_reader.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/custom_components/enphase_envoy_custom/envoy_reader.py b/custom_components/enphase_envoy_custom/envoy_reader.py index 3231a03..a9b39fc 100644 --- a/custom_components/enphase_envoy_custom/envoy_reader.py +++ b/custom_components/enphase_envoy_custom/envoy_reader.py @@ -85,6 +85,10 @@ class EnvoyReader: # pylint: disable=too-many-instance-attributes "Grid status not available for your Envoy device." ) + message_import_export_not_available = ( + "Import Export data not available for your Envoy device." + ) + def __init__( # pylint: disable=too-many-arguments self, host, @@ -912,7 +916,7 @@ async def import_index(self): """Running getData() beforehand will set self.enpoint_type and self.isDataRetrieved""" """so that this method will only read data from stored variables""" if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: - return None + return self.message_import_export_not_available raw_json = self.endpoint_meters_json_results.json() index_imp = raw_json[1]["actEnergyDlvd"] @@ -944,7 +948,7 @@ async def export_index(self): """so that this method will only read data from stored variables""" if self.endpoint_type in [ENVOY_MODEL_C,ENVOY_MODEL_LEGACY]: - return None + return self.message_import_export_not_available raw_json = self.endpoint_meters_json_results.json() index_exp = raw_json[1]['actEnergyRcvd'] @@ -1024,6 +1028,10 @@ async def envoy_info(self): device_data["Endpoint-production"] = self.endpoint_production_results.text else: device_data["Endpoint-production"] = self.endpoint_production_results + if self.endpoint_meters_json_results: + device_data["Endpoint-meters"] = self.endpoint_meters_json_results.text + else: + device_data["Endpoint-meters"] = self.endpoint_meters_json_results if self.endpoint_production_inverters: device_data[ "Endpoint-production_inverters" From 16d39f41c19e2dcb2c2f6dd25485af60cb05c310 Mon Sep 17 00:00:00 2001 From: Arie Catsman Date: Tue, 22 Aug 2023 18:40:00 +0200 Subject: [PATCH 7/8] Add Import Export Index to documentation --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 0db5f2a..785d773 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ What data is available depends on how many current transformer clamps (CT) are i - Current power production and consumption, today's, last 7 days and lifetime energy production and consumption over all phases. - Current power production and consumption, today's, last 7 days and lifetime energy production and consumption for each individual phase named L1, L2 and L3. - Current power production for each connected inverter. +- Energy Import and Export Index over all phases and for each phase individually from meters readings **Note** If you have CT clamps on a single phase / breaker circuit only, the L1 production and consumption phase sensors will show same data as the over all phases sensors. @@ -136,6 +137,10 @@ Envoy \ Current Power Production L\|sensor.Envoy_\ Today's Energy Consumption L\|sensor.Envoy_\_todays_energy_consumption_L\|4,5| |Envoy \ Last Seven Days Energy Consumption L\|sensor.Envoy_\_last_seven_days_energy_production L\|4,5| |Envoy \ Lifetime Energy Consumption L\|sensor.Envoy_\_lifetime_energy_consumption_L\|4,5| +|Index Import|sensor.Envoy_\_index_import|4,5| +|Index Export|sensor.Envoy_\_index_export|4,5| +|Index Import L\|sensor.Envoy_\_index_import_L\|4,5| +|Index Export L\|sensor.Envoy_\_index_export_L\|4,5| 1 always zero for Envoy Metered without meters. 2 reportedly resets to zero when reaching ~1.92MWh for Envoy Metered without meters. From ce8c819894c41d633b7596b079935f04e15c78d4 Mon Sep 17 00:00:00 2001 From: Arie Catsman Date: Mon, 28 Aug 2023 14:00:07 +0200 Subject: [PATCH 8/8] Publish import/export index by @cddu33 in v0.0.17 --- README.md | 8 ++++---- custom_components/enphase_envoy_custom/manifest.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d393170..ae3051b 100644 --- a/README.md +++ b/README.md @@ -137,10 +137,10 @@ A device `Envoy ` is created with sensor entities for accessible d |Envoy \ Today's Energy Consumption L\|sensor.Envoy_\_todays_energy_consumption_L\|Wh|4,5,6| |Envoy \ Last Seven Days Energy Consumption L\|sensor.Envoy_\_last_seven_days_energy_consumption L\|Wh|4,5,6| |Envoy \ Lifetime Energy Consumption L\|sensor.Envoy_\_lifetime_energy_consumption_L\|Wh|4,5,6| -|Index Import|sensor.Envoy_\_index_import|4,5| -|Index Export|sensor.Envoy_\_index_export|4,5| -|Index Import L\|sensor.Envoy_\_index_import_L\|4,5| -|Index Export L\|sensor.Envoy_\_index_export_L\|4,5| +|Index Import|sensor.Envoy_\_index_import|Wh|4,5| +|Index Export|sensor.Envoy_\_index_export|Wh|4,5| +|Index Import L\|sensor.Envoy_\_index_import_L\|Wh|4,5| +|Index Export L\|sensor.Envoy_\_index_export_L\|Wh|4,5| 1 Always zero for Envoy Metered without meters. 2 Reportedly resets to zero when reaching ~1.92MWh for Envoy Metered without meters. diff --git a/custom_components/enphase_envoy_custom/manifest.json b/custom_components/enphase_envoy_custom/manifest.json index b3d3c6a..d012e04 100644 --- a/custom_components/enphase_envoy_custom/manifest.json +++ b/custom_components/enphase_envoy_custom/manifest.json @@ -6,5 +6,5 @@ "codeowners": ["@briancmpbll"], "config_flow": true, "iot_class": "local_polling", - "version": "0.0.16" + "version": "0.0.17" }