Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sensor component for Fronius inverters, storages, and smart meters #11446

Closed
wants to merge 23 commits into from
Closed
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
785740e
Introduced fronius component that adds ability to track Fronius devic…
gbeine Jan 2, 2018
2c78c92
Use device parameter for fetching inverter data
gbeine Jan 3, 2018
06a3f68
Fixed handling of default scope
gbeine Jan 3, 2018
937e582
Handle exceptions from yield
gbeine Jan 4, 2018
cdc06d9
Fulfill PR requirements
gbeine Jan 4, 2018
737cc59
Fixed houndci violations
gbeine Jan 4, 2018
3b5f800
Found the last hound violation
gbeine Jan 4, 2018
6ff5c0e
Fixed docstring (https://github.com/home-assistant/home-assistant/pul…
gbeine Feb 18, 2018
bf4d4ec
Fixed import order with isort (https://github.com/home-assistant/home…
gbeine Feb 18, 2018
24d2694
CONF_DEVICE is now CONF_DEVICEID (https://github.com/home-assistant/h…
gbeine Feb 18, 2018
5683589
Added docstring to class FroniusSensor (https://github.com/home-assis…
gbeine Feb 18, 2018
70d78f7
Fixed docstring for state (https://github.com/home-assistant/home-ass…
gbeine Feb 18, 2018
07b3287
Added/fixed docstrings (https://github.com/home-assistant/home-assist…
gbeine Feb 18, 2018
b177d4b
Remove redundant log entry (https://github.com/home-assistant/home-as…
gbeine Feb 18, 2018
3caca8b
Fixed error message if sensor update fails (https://github.com/home-a…
gbeine Feb 18, 2018
d368713
Fixed error log messages (https://github.com/home-assistant/home-assi…
gbeine Feb 18, 2018
d98d944
Satisfy hound
gbeine Feb 18, 2018
b78147a
Handle exceptions explicit (https://github.com/home-assistant/home-as…
gbeine Feb 18, 2018
3fa6462
Removed unnecessary call of update (https://github.com/home-assistant…
gbeine Feb 18, 2018
6cfdbc1
The point makes the difference.
gbeine Feb 18, 2018
2d268ca
Removed unrelated requirements
gbeine Feb 18, 2018
97fdcbc
Remove config logging (https://github.com/home-assistant/home-assista…
gbeine Feb 22, 2018
b1b491f
Reorder and fix imports (https://github.com/home-assistant/home-assis…
gbeine Feb 22, 2018
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -522,6 +522,7 @@ omit =
homeassistant/components/sensor/fixer.py
homeassistant/components/sensor/fritzbox_callmonitor.py
homeassistant/components/sensor/fritzbox_netmonitor.py
homeassistant/components/sensor/fronius.py
homeassistant/components/sensor/gearbest.py
homeassistant/components/sensor/geizhals.py
homeassistant/components/sensor/gitter.py
@@ -0,0 +1,151 @@
'''

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

This is a docstring, use """.

Support for Fronius devices.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/sensor.fronius/
'''
import asyncio
import logging
from datetime import timedelta
from aiohttp.client_exceptions import ServerDisconnectedError
from concurrent.futures._base import TimeoutError

import voluptuous as vol

import homeassistant.helpers.config_validation as cv
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (CONF_HOST, CONF_SCAN_INTERVAL)
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.entity import Entity

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Please keep the imports ordered. Use isort if you don't want to do it manually.


REQUIREMENTS = [ 'pyfronius==0.2' ]

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

whitespace after '['
whitespace before ']'


_LOGGER = logging.getLogger(__name__)

CONF_TYPE = 'type'
CONF_DEVICE = 'device'

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

CONF_DEVICE is already defined in const.py.

CONF_SCOPE = 'scope'

TYPE_INVERTER = 'inverter'
TYPE_STORAGE = 'storage'
TYPE_METER = 'meter'
TYPE_POWER_FLOW = 'power_flow'
SCOPE_DEVICE = 'device'
SCOPE_SYSTEM = 'system'

DEFAULT_SCOPE = SCOPE_DEVICE
DEFAULT_DEVICE = None

SENSOR_TYPES = [ TYPE_INVERTER, TYPE_STORAGE, TYPE_METER, TYPE_POWER_FLOW ]

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

whitespace after '['
whitespace before ']'

SCOPE_TYPES = [ SCOPE_DEVICE, SCOPE_SYSTEM ]

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

whitespace after '['
whitespace before ']'


PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_TYPE): vol.In(SENSOR_TYPES),
vol.Optional(CONF_SCOPE, default=DEFAULT_SCOPE): vol.All(cv.ensure_list, [vol.In(SCOPE_TYPES)]),

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

line too long (100 > 79 characters)

vol.Optional(CONF_DEVICE): cv.positive_int,
})

@asyncio.coroutine

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

expected 2 blank lines, found 1

def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up of Fronius platform."""
_LOGGER.debug("Running setup")

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

That's already logged.

_LOGGER.debug(config)

This comment has been minimized.

Copy link
@balloob

balloob Feb 18, 2018

Member

Let's remove this debug as it contains the config.

import pyfronius

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

blank line contains whitespace

session = async_get_clientsession(hass)
fronius = pyfronius.Fronius(session, config[CONF_HOST])

name = "fronius_{}_{}".format(config[CONF_TYPE], config[CONF_HOST])
if CONF_DEVICE in config.keys():
device = config[CONF_DEVICE]
name = name + "_{}".format(device)
else:
device = DEFAULT_DEVICE

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

blank line contains whitespace

sensor = FroniusSensor(fronius, name, config[CONF_TYPE], config[CONF_SCOPE], device)

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

line too long (88 > 79 characters)


This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

blank line contains whitespace

async_add_devices([sensor])

@asyncio.coroutine
def async_fronius(event):
"""Update all the fronius sensors."""
try:
yield from sensor.async_update()
except:

This comment has been minimized.

Copy link
@balloob

balloob Feb 18, 2018

Member

Bare excepts are not allowed. Specify the exceptions that you expect.

_LOGGER.error("yield failed")

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Need an update. The current message is not useful for an user.


interval = config.get(CONF_SCAN_INTERVAL) or timedelta(seconds=10)

This comment has been minimized.

Copy link
@balloob

balloob Feb 18, 2018

Member

Don't do this. The Entity Platform takes care of this.

This comment has been minimized.

Copy link
@gbeine

gbeine Feb 19, 2018

Author

Ok, is this described somewhere?
How can I access the interval?

This comment has been minimized.

Copy link
@nielstron

nielstron Feb 19, 2018

Contributor

Why would you need to access the interval time? The Entity superclass already handles calling the update method on a regular basis (based on time interval).

This comment has been minimized.

Copy link
@gbeine

gbeine Feb 19, 2018

Author

How does the Entity superclass know about the interval that is configured?
Where does this magic happen?
Can I leave the configuration parameter as it is or is there a pattern that I need to follow?

This comment has been minimized.

Copy link
@balloob
async_track_time_interval(hass, async_fronius, interval)

This comment has been minimized.

Copy link
@balloob

balloob Feb 18, 2018

Member

Remove this, entity platform will do this if should_poll returns True.

This comment has been minimized.

Copy link
@gbeine

gbeine Feb 19, 2018

Author

I'll search for this. Did this change soon?
I've got these two lines from another sensor.



class FroniusSensor(Entity):

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Docstring for the class is missing.

This comment has been minimized.

Copy link
@gbeine

gbeine Feb 18, 2018

Author

Hm... I've added a docstring as in other components, but this comment still persists...

def __init__(self, data, name, device_type, scope, device):
"""Initialize the sensor."""
self.data = data
self._name = name
self._type = device_type
self._device = device
self._scope = scope
self._state = None
self._attributes = {}

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

@property
def state(self):
"""Return the ???."""

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Needs an update.

return self._state

@property
def state_attributes(self):
"""Return the state attributes."""
return self._attributes

@asyncio.coroutine
def async_update(self):
"""Retrieve latest state."""
_LOGGER.debug("Update {}".format(self.name))

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

blank line contains whitespace

values = {}

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

blank line contains whitespace

try:
values = yield from self._update()
except ServerDisconnectedError:
_LOGGER.error("ServerDisconnectedError")

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Log message should be useful for the user.

except TimeoutError:
_LOGGER.error("TimeoutError")

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Dito


_LOGGER.debug(values)

if values:

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

trailing whitespace

self._state = values['status']['Code']
self._attributes = self._get_attributes(values)
self.async_update_ha_state()

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Is that really needed?

This comment has been minimized.

Copy link
@gbeine

gbeine Feb 3, 2018

Author

Which part of these lines do you mean?
All? Or just the update?

This comment has been minimized.

Copy link
@balloob

balloob Feb 18, 2018

Member

This is a coroutine. Just calling it like this does nothing so it can be safely removed.


@asyncio.coroutine
def _update(self):

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Docstring is missing.

if self._type == TYPE_INVERTER:
if self._scope == SCOPE_SYSTEM:
return self.data.current_system_inverter_data()

This comment has been minimized.

Copy link
@balloob

balloob Feb 18, 2018

Member

Is this doing I/O ?

This comment has been minimized.

Copy link
@gbeine

gbeine Feb 19, 2018

Author

This triggers an HTTP request, so it is I/O via network.

This comment has been minimized.

Copy link
@balloob

balloob Feb 22, 2018

Member

This function is a coroutine. You are not allowed to do I/O inside a coroutine.

This comment has been minimized.

Copy link
@balloob

balloob Feb 22, 2018

Member

Remove asyncio.coroutine and name your update method update instead of async_update

This comment has been minimized.

Copy link
@MartinHjelmare

MartinHjelmare Feb 26, 2018

Member

This call returns a coroutine object according to the source in pyfronius.

elif self._scope == SCOPE_DEVICE and self._device:
return self.data.current_inverter_data(self._device)
elif self._scope == SCOPE_DEVICE:
return self.data.current_inverter_data()
elif self._type == TYPE_STORAGE:
return self.data.current_storage_data()
elif self._type == TYPE_METER:
return self.data.current_meter_data()
elif self._type == TYPE_POWER_FLOW:
return self.data.current_power_flow()

def _get_attributes(self, values):

This comment has been minimized.

Copy link
@fabaff

fabaff Feb 2, 2018

Member

Docstring is missing.

attributes = {}
for key in values:
if 'value' in values[key]:
attributes[key] = values[key]['value'] if values[key]['value'] else 0

This comment has been minimized.

Copy link
@houndci-bot

houndci-bot Jan 4, 2018

line too long (85 > 79 characters)

return attributes
@@ -348,6 +348,9 @@ http://github.com/tgaugry/suds-passworddigest-py3/archive/86fc50e39b4d2b89974819
# homeassistant.components.remember_the_milk
httplib2==0.10.3

# homeassistant.components.xiaomi
https://github.com/Danielhiversen/PyXiaomiGateway/archive/aa9325fe6fdd62a8ef8c9ca1dce31d3292f484bb.zip#PyXiaomiGateway==0.2.0

# homeassistant.components.sensor.dht
# https://github.com/adafruit/Adafruit_Python_DHT/archive/da8cddf7fb629c1ef4f046ca44f42523c9cf2d11.zip#Adafruit_DHT==1.3.2

@@ -682,6 +685,9 @@ pyfido==1.0.1
# homeassistant.components.climate.flexit
pyflexit==0.3

# homeassistant.components.sensor.fronius
pyfronius==0.2

# homeassistant.components.ifttt
pyfttt==0.3

@@ -866,6 +872,9 @@ python-juicenet==0.0.5
# homeassistant.components.vacuum.xiaomi_miio
python-miio==0.3.2

# homeassistant.components.switch.xiaomi_vacuum
python-mirobo==0.1.2

# homeassistant.components.media_player.mpd
python-mpd2==0.5.5

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.