From f1793428b423ec1532638eeb9fd924046be95c2d Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Mon, 4 May 2020 09:37:46 +0200 Subject: [PATCH 01/12] Increate update time Inverter only updates the js file once every 5 minutes --- custom_components/omnik_inverter/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index 5be600c..8351c23 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -32,7 +32,7 @@ _LOGGER = logging.getLogger(__name__) -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=500) SENSOR_TYPES = { 'powercurrent': ['Solar Power Current', POWER_WATT, 'mdi:weather-sunny'], From affd6401b1a361539e9f6def284b33fb9c7c9599 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Mon, 4 May 2020 09:37:53 +0200 Subject: [PATCH 02/12] Properly close the urlopen --- custom_components/omnik_inverter/sensor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index 8351c23..3c8f300 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -78,7 +78,9 @@ def update(self): """Update the data from the omnik inverter.""" dataurl = BASE_URL.format(self._host) try: - r = urlopen(dataurl).read() + fp = urlopen(dataurl) + r = fp.read() + fp.close() except OSError: _LOGGER.error("Unable to fetch data from Omnik Inverter %s", self._host) return False From e2fbb4f52bca1c7517a2001868bb4f0a076012f4 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Mon, 4 May 2020 09:38:01 +0200 Subject: [PATCH 03/12] If no data was returned, return false --- custom_components/omnik_inverter/sensor.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index 3c8f300..bb5d50c 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -150,6 +150,10 @@ def update(self): # Get the result data result = self.data.result + if result is None: + _LOGGER.debug("No data found for %s", self.type) + return False + if self.type == 'powercurrent': # Update the sensor state self._state = int(result[5]) From f49183aecf978b2f92bc871fc9c97e4f6c5c40a5 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Mon, 4 May 2020 09:38:05 +0200 Subject: [PATCH 04/12] Bump version --- custom_components/omnik_inverter/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index bb5d50c..675f6e6 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -23,7 +23,7 @@ import re import pickle -VERSION = '1.2.2' +VERSION = '1.3.0' CONF_CACHE_POWER_TODAY = 'cache_power_today' From 9a41ceec90c3c46c4b6784975461b2d2437dfce9 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Mon, 4 May 2020 09:39:55 +0200 Subject: [PATCH 05/12] Update README.md --- README.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 49c76f0..5e6e94e 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,7 @@ Your Omnik Inverter needs to be connected to your local network, as this custom ## HACS installation -Add this component using HACS by adding this repository as a custom repository in your settings. -- URL: https://github.com/robbinjanssen/home-assistant-omnik-inverter -- Category: Integration +Add this component using HACS, search for the `Omnik Inverter` integration. ## Manual installation @@ -51,7 +49,8 @@ sensor: ## How does it work? -The web interface has a javascript file that contains the actual values. This is updated every minute (afaik). Check it out in your browser at `http:///js/status.js` +The web interface has a javascript file that contains the actual values. This is updated every +5 minutes. Check it out in your browser at `http:///js/status.js` The result contains a lot of information, but there is one part we're interested in: ```js @@ -62,16 +61,21 @@ var myDeviceArray=new Array(); myDeviceArray[0]="AANN3020,V5.04Build230,V4.13Bui // ... Even more data ``` -This variable declaration contains your serial number, firmware versions, hardware information, the current power output: 1920, the energy generated today: 429 and the total energy generated: 87419. +This variable declaration contains your serial number, firmware versions, hardware information, the +current power output: 1920, the energy generated today: 429 and the total energy generated: 87419. -This custom component basically requests the URL, looks for the _webData_ part and extracts the values as the following sensors: +This custom component basically requests the URL, looks for the _webData_ part and extracts the +values as the following sensors: - `sensor.solar_power_current` (Watt) - `sensor.solar_power_today` (kWh) - `sensor.solar_power_total` (kWh) -### Caching power today. +### Caching "power today". -In a few cases the Omnik inverter resets the `solar_power_today` to 0.0 after for example 21:00. By setting the `cache_power_today` config attribute to `true` (default) this component will cache the the value and only resets to 0.0 after midnight. If you do not experience this, then disable the cache by setting the config variable to `false`. +In a few cases the Omnik inverter resets the `solar_power_today` to 0.0 after for example 21:00. By +setting the `cache_power_today` config attribute to `true` (default) this component will cache the +value and only resets to 0.0 after midnight. If you do not experience this, then disable the +cache by setting the config variable to `false`. ## References From 459ab2e9ba76e7e539384fb2862f286e3a4770ae Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Wed, 6 May 2020 19:20:49 +0200 Subject: [PATCH 06/12] Add support for use_json --- custom_components/omnik_inverter/sensor.py | 66 ++++++++++++++++++---- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index 675f6e6..5508157 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -6,7 +6,9 @@ host: 192.168.100.100 cache_power_today: true """ +import json import logging +from random import random from datetime import timedelta from datetime import datetime @@ -26,9 +28,11 @@ VERSION = '1.3.0' CONF_CACHE_POWER_TODAY = 'cache_power_today' +CONF_USE_JSON = 'use_json' -BASE_URL = 'http://{0}/js/status.js' -BASE_CACHE_NAME = '.{0}.pickle' +JS_URL = 'http://{0}/js/status.js' +JSON_URL = 'http://{0}/status.json?CMD=inv_query&rand={1}' +CACHE_NAME = '.{0}.pickle' _LOGGER = logging.getLogger(__name__) @@ -43,6 +47,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_HOST): cv.string, vol.Optional(CONF_CACHE_POWER_TODAY, default=True): cv.boolean + vol.Optional(CONF_USE_JSON, default=False): cv.boolean }) @@ -50,9 +55,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Solar Portal sensors.""" host = config.get(CONF_HOST) cache = config.get(CONF_CACHE_POWER_TODAY) + use_json = config.get(CONF_USE_JSON) try: - data = OmnikInverterWeb(host) + if use_json is False: + data = OmnikInverterWeb(host) + else: + data = OmnikInverterJson(host) except RuntimeError: _LOGGER.error("Unable to fetch data from Omnik Inverter %s", host) return False @@ -75,8 +84,8 @@ def __init__(self, host): @Throttle(MIN_TIME_BETWEEN_UPDATES) def update(self): - """Update the data from the omnik inverter.""" - dataurl = BASE_URL.format(self._host) + """Update the data from the Omnik Inverter.""" + dataurl = JS_URL.format(self._host) try: fp = urlopen(dataurl) r = fp.read() @@ -96,7 +105,44 @@ def update(self): # Split the values if matches is not None: - self.result = matches.group(0).split(',') + data = matches.group(0).split(',') + self.result = [ + int(data[5]), + int(data[6]), + int(data[7]) + ] + else: + _LOGGER.error("Empty data from Omnik Inverter %s", self._host) + + _LOGGER.debug("Data = %s", self.result) + +class OmnikInverterJson(object): + """Representation of the Omnik Inverter Json.""" + + def __init__(self, host): + """Initialize the inverter.""" + self._host = host + self.result = None + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """Update the data from the Omnik Inverter.""" + dataurl = JSON_URL.format(self._host, random()) + try: + fp = urlopen(dataurl) + data = json.load(fp) + fp.close() + except (OSError, JSONDecodeError): + _LOGGER.error("Unable to fetch data from Omnik Inverter %s", self._host) + return False + + # Split the values + if data is not None: + self.result = [ + int(data["i_pow_n"]), + int(float(data["i_eday"]) * 100), + int(float(data["i_eall"]) * 10) + ] else: _LOGGER.error("Empty data from Omnik Inverter %s", self._host) @@ -156,13 +202,13 @@ def update(self): if self.type == 'powercurrent': # Update the sensor state - self._state = int(result[5]) + self._state = result[0] elif self.type == 'powertoday': # Define the cache name - cacheName = BASE_CACHE_NAME.format(self.type) + cacheName = CACHE_NAME.format(self.type) # Prepare the current actual values - currentValue = int(result[6]) + currentValue = result[1] currentDay = int(datetime.now().strftime('%Y%m%d')) # Check if caching is enabled @@ -211,4 +257,4 @@ def update(self): self._state = (currentValue / 100) elif self.type == 'powertotal': # Update the sensor state, divide by 10 to make it kWh - self._state = (int(result[7]) / 10) + self._state = (int(result[2]) / 10) From d115e997f709f438964942fa0620bed56a116a22 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Wed, 6 May 2020 19:25:13 +0200 Subject: [PATCH 07/12] Formatting and update readme --- README.md | 18 ++++++++++++++++-- custom_components/omnik_inverter/sensor.py | 7 ++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5e6e94e..89bbc1b 100644 --- a/README.md +++ b/README.md @@ -61,15 +61,29 @@ var myDeviceArray=new Array(); myDeviceArray[0]="AANN3020,V5.04Build230,V4.13Bui // ... Even more data ``` -This variable declaration contains your serial number, firmware versions, hardware information, the +This output contains your serial number, firmware versions, hardware information, the current power output: 1920, the energy generated today: 429 and the total energy generated: 87419. -This custom component basically requests the URL, looks for the _webData_ part and extracts the +The custom component basically requests the URL, looks for the _webData_ part and extracts the values as the following sensors: - `sensor.solar_power_current` (Watt) - `sensor.solar_power_today` (kWh) - `sensor.solar_power_total` (kWh) +### My inverter doesn't show any output when I go to the URL. + +Some inverters use a JSON status file to output the values. Check if your +inverter outputs JSON data by navigating to: `http:///status.json?CMD=inv_query&rand=0.1234567`. + +If so, then use the `use_json` config boolean to make the component use the URL above. + +``` YAML +sensor: + - platform: omnik_inverter + host: 192.168.100.100 + use_json: true +``` + ### Caching "power today". In a few cases the Omnik inverter resets the `solar_power_today` to 0.0 after for example 21:00. By diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index 5508157..5685df5 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -116,6 +116,7 @@ def update(self): _LOGGER.debug("Data = %s", self.result) + class OmnikInverterJson(object): """Representation of the Omnik Inverter Json.""" @@ -197,8 +198,8 @@ def update(self): result = self.data.result if result is None: - _LOGGER.debug("No data found for %s", self.type) - return False + _LOGGER.debug("No data found for %s", self.type) + return False if self.type == 'powercurrent': # Update the sensor state @@ -257,4 +258,4 @@ def update(self): self._state = (currentValue / 100) elif self.type == 'powertotal': # Update the sensor state, divide by 10 to make it kWh - self._state = (int(result[2]) / 10) + self._state = (result[2]) / 10) From c998858f83c6dd947214b0d5a8508aa85b764306 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Wed, 6 May 2020 19:25:33 +0200 Subject: [PATCH 08/12] Add missing example --- custom_components/omnik_inverter/sensor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index 5685df5..3f4d108 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -5,6 +5,7 @@ - platform: omnik_inverter host: 192.168.100.100 cache_power_today: true + use_json: false """ import json import logging From 624f49c134115beaaf405ff347513c11c3fd94a7 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Wed, 6 May 2020 19:27:58 +0200 Subject: [PATCH 09/12] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 89bbc1b..850bbe7 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,13 @@ setting the `cache_power_today` config attribute to `true` (default) this compon value and only resets to 0.0 after midnight. If you do not experience this, then disable the cache by setting the config variable to `false`. +``` YAML +sensor: + - platform: omnik_inverter + host: 192.168.100.100 + cache_power_today: false +``` + ## References - https://community.home-assistant.io/t/omink-inverter-in-home-assistant/102455/36 From 852cd43b0b8a05118a49388060c14fb724616370 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Wed, 6 May 2020 22:36:44 +0200 Subject: [PATCH 10/12] Fix formatting --- custom_components/omnik_inverter/sensor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/omnik_inverter/sensor.py b/custom_components/omnik_inverter/sensor.py index 3f4d108..d71a984 100644 --- a/custom_components/omnik_inverter/sensor.py +++ b/custom_components/omnik_inverter/sensor.py @@ -47,7 +47,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_HOST): cv.string, - vol.Optional(CONF_CACHE_POWER_TODAY, default=True): cv.boolean + vol.Optional(CONF_CACHE_POWER_TODAY, default=True): cv.boolean, vol.Optional(CONF_USE_JSON, default=False): cv.boolean }) @@ -259,4 +259,4 @@ def update(self): self._state = (currentValue / 100) elif self.type == 'powertotal': # Update the sensor state, divide by 10 to make it kWh - self._state = (result[2]) / 10) + self._state = (result[2] / 10) From d83360ed3fb924e441033b1509964386da7007f3 Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Wed, 6 May 2020 23:06:33 +0200 Subject: [PATCH 11/12] Update info and readme --- README.md | 4 +++- info.md | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a4b8fc9..e65ffeb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Home Assistant Omnik Inverter The Omnik Inverter Sensor component will retrieve data from an Omnik inverter connected to your local network. -It has been tested and developed on an Omnik 4K TL2 and it might work for other inverters as well. +It has been tested and developed on an Omnik 4k TL2, 2k TL2 and it might work for other inverters as well. The values will be presented as sensors in [Home Assistant](https://home-assistant.io/). @@ -72,6 +72,8 @@ values as the following sensors: ### My inverter doesn't show any output when I go to the URL. +> Use this if you have an Omnik Inverter 2k TL2. + Some inverters use a JSON status file to output the values. Check if your inverter outputs JSON data by navigating to: `http:///status.json?CMD=inv_query&rand=0.1234567`. diff --git a/info.md b/info.md index d6b787f..0c0c667 100644 --- a/info.md +++ b/info.md @@ -1,17 +1,26 @@ -# Omnik Inverter Sensor Component for Home Assistant. +## Omnik Inverter Sensor Component for Home Assistant. The Omnik solar sensor component will retrieve data from an Omnik solar inverter. The values will be presented as sensors (or attributes of sensors) in Home Assistant. -## Example +## Configuration + +``` YAML +sensor: + - platform: omnik_inverter + host: 192.168.100.100 +``` + +### Entities -Entities: - `sensor.solar_power_current` (Watt) - `sensor.solar_power_today` (kWh) - `sensor.solar_power_total` (kWh) +### Example + ![Omnik Inverter Sensor Entities](https://github.com/robbinjanssen/home-assistant-omnik-inverter/blob/master/images/entities.png) -## Documentation +### Documentation -Find the full documentation [here](https://github.com/robbinjanssen/home-assistant-omnik-inverter/blob/master/README.md). \ No newline at end of file +Find the full documentation [here](https://github.com/robbinjanssen/home-assistant-omnik-inverter). \ No newline at end of file From a118dfc64bfe1108e802574dfbaff1cbcb3b286f Mon Sep 17 00:00:00 2001 From: Robbin Janssen Date: Thu, 7 May 2020 09:31:33 +0200 Subject: [PATCH 12/12] Update hacs.json --- hacs.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hacs.json b/hacs.json index f33d088..3c10cb4 100644 --- a/hacs.json +++ b/hacs.json @@ -1,6 +1,6 @@ { - "name": "Omnik Inverter", + "name": "Omnik Inverter Solar Sensor (No Cloud)", "country": "NL", "domains": ["sensor"], "homeassistant": "0.109.0" -} \ No newline at end of file +}