Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
robbinjanssen committed Feb 18, 2020
1 parent c839e42 commit 3b1c526
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,57 @@
# Home Assistant Omnik Inverter
The Omnik Inverter Sensor component will retrieve data from a local Omnik inverter.
It has been tested and developed on an Omnik 4K TL2 and it is currently unknown if it works for other inverters.

The values will be presented as sensors in [Home Assistant](https://home-assistant.io/).

## Requirements

Your Omnik Inverter needs to be connected to your local network, as this custom component will utilise the web interface of the Omnik inverter to read data. All you need to know is the IP address of the Omnik inverter and you are good to go.

## How does it work?

The web interface has a javascript file that contains the actual values. This is updated (afaik) every minute. You can visit it in your browser at http://your_omnik_ip_address/js/status.js

Looking at the data it contains lots of information, but there's one part we're interested in:

```js
// ... Bunch of data
var webData="NLBN1234567A1234,iv4-V6.5-140-4,V5.2-42819,omnik4000tl2,4000,1920,429,87419,,3,";
// ... Even more data.
```

This line contains your serial number, firmware versions, hardware information _and_ the current power output (1920) in watts and the total energy generated today (429) in watts.

This custom component basically requests the URL, looks for the _webData_ part and extracts the values as two sensors.
- `sensor.solar_power_current` (Watt)
- `sensor.solar_power_today` (kWh)

For some reason my Omnik inverter reset the power today to 0.0 after 21:00, so the total power today is cached by the custom component until the 00:00 the next day.

## Installation

Create a directory called `omnik_inverter` in the `<config directory>/custom_components/` directory on your Home Assistant instance.
Install this component by copying all files in `/custom_components/omnik_inverter/` folder from this repo into the new `<config directory>/custom_components/omnik_inverter/` directory you just created.

This is how your custom_components directory should be:
```bash
custom_components
├── omnik_inverter
│ ├── __init__.py
│ ├── manifest.json
│ └── sensor.py
```

## Configuration example

To enable this sensor, add the following lines to your configuration.yaml file:

``` YAML
sensor:
- platform: omnik_inverter
host: 192.168.100.100
```
## References
Got my inspiration from: https://community.home-assistant.io/t/omink-inverter-in-home-assistant/102455/36
1 change: 1 addition & 0 deletions custom_components/omnik_inverter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""The omnik inverter sensor integration."""
8 changes: 8 additions & 0 deletions custom_components/omnik_inverter/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"domain": "omnik_inverter",
"name": "Omnik Inverter",
"documentation": "https://github.com/robbinjanssen/home-assistant-omnik-inverter/blob/master/README.md",
"dependencies": [],
"codeowners": [],
"requirements": []
}
168 changes: 168 additions & 0 deletions custom_components/omnik_inverter/sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
"""
configuration.yaml
sensor:
- platform: omnik_inverter
host: 192.168.100.100
"""
import logging
from datetime import timedelta
from datetime import datetime

import voluptuous as vol

from homeassistant.components.sensor import PLATFORM_SCHEMA
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (CONF_HOST)
from homeassistant.util import Throttle
from homeassistant.helpers.entity import Entity

from urllib.request import urlopen

import re
import pickle

VERSION = '0.0.1'

BASE_URL = 'http://{0}/js/status.js'
BASE_CACHE_NAME = '.{0}.pickle'

_LOGGER = logging.getLogger(__name__)

MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)

SENSOR_TYPES = {
'powercurrent': ['Solar Power Current', 'Watt', 'mdi:weather-sunny'],
'powertoday': ['Solar Power Today', 'kWh', 'mdi:flash'],
}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
})


def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Solar Portal sensors."""
host = config.get(CONF_HOST)

try:
data = OmnikInverterWeb(host)
except RunTimeError:
_LOGGER.error("Unable to connect fetch data from Omnik Inverter %s",
host)
return False

entities = []

for sensor_type in SENSOR_TYPES:
entities.append(OmnikInverterSensor(data, sensor_type))

add_devices(entities)


class OmnikInverterWeb(object):
"""Representation of the Omnik Inverter Web."""

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 = BASE_URL.format(self._host)
r = urlopen(dataurl).read()

"""Remove strange characters from the result."""
result = r.decode('ascii', 'ignore')

"""Find the webData."""
matches = re.search('webData="(.*),";function', result)

"""Split the values."""
self.result = matches.group(1).split(',')

_LOGGER.debug("Data = %s", self.result)


class OmnikInverterSensor(Entity):
"""Representation of a OmnikInverter sensor from the web data."""

def __init__(self, data, sensor_type):
"""Initialize the sensor."""
self.data = data
self.type = sensor_type
self._name = SENSOR_TYPES[self.type][0]
self._unit_of_measurement = SENSOR_TYPES[self.type][1]
self._icon = SENSOR_TYPES[self.type][2]
self._state = None
self.update()

@property
def name(self):
"""Return the name of the sensor."""
return self._name

@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._icon

@property
def state(self):
"""Return the state of the sensor."""
return self._state

@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._unit_of_measurement

def update(self):
"""Get the latest data and use it to update our sensor state."""
self.data.update()

"""Get the result data."""
result = self.data.result

if self.type == 'powercurrent':
"""Update the sensor state."""
self._state = int(result[5])
elif self.type == 'powertoday':
"""Define the cache name."""
cacheName = BASE_CACHE_NAME.format(self.type)

"""Prepare the next values."""
nextValue = int(result[6])
nextTime = int(datetime.now().strftime('%H%M'))

"""Fetch data from the cache."""
try:
cache = pickle.load(open(cacheName, 'rb'))
except (OSError, IOError, EOFError) as e:
cache = [0, 0]

"""Set the cache values."""
cacheValue = int(cache[0])
cacheTime = int(cache[1])

"""
If somehow the currentPowerToday is lower than the cached
version, keep the cached version.
"""
if (nextValue < cacheValue):
nextValue = cacheValue

"""
If today has passed, use the actual value from the
omnik inverter.
"""
if (cacheTime > nextTime):
nextValue = int(result[6])

"""Store new stats."""
pickle.dump([nextValue, nextTime], open(cacheName, 'wb'))

"""Update the sensor state, divide by 100 to make it kWh."""
self._state = (nextValue / 100)
Binary file added images/entities.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# 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
![Omnik Inverter Sensor Entities](https://github.com/robbinjanssen/home-assistant-omnik-inverter/blob/master/images/entities.png)

## Documentation
Find the full documentation [here](https://github.com/robbinjanssen/home-assistant-omnik-inverter/blob/master/README.md).

0 comments on commit 3b1c526

Please sign in to comment.