From 6e24b52a7eec80e55b06753efadd35d25729a0e1 Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Sun, 7 Jul 2019 10:22:21 +0100 Subject: [PATCH] Add support for aurora ABB Powerone solar photovoltaic inverter (#24809) * Add support for aurora ABB Powerone solar photovoltaic inverter * Add support for aurora ABB Powerone solar photovoltaic inverter * Update stale docstring * Fixed whitespace lint errors * Remove test code * Delete README.md Website documentation contains setup instructions. README not needed here. * Only close the serial line once. * Correct newlines between imports * Change add_devices to add_entites and remove unnecessary logging. * Use new style string formatting instead of concatenation * Directly access variables rather than via config.get * Update sensor.py --- .coveragerc | 1 + CODEOWNERS | 1 + .../aurora_abb_powerone/__init__.py | 1 + .../aurora_abb_powerone/manifest.json | 10 ++ .../components/aurora_abb_powerone/sensor.py | 98 +++++++++++++++++++ requirements_all.txt | 3 + 6 files changed, 114 insertions(+) create mode 100644 homeassistant/components/aurora_abb_powerone/__init__.py create mode 100644 homeassistant/components/aurora_abb_powerone/manifest.json create mode 100644 homeassistant/components/aurora_abb_powerone/sensor.py diff --git a/.coveragerc b/.coveragerc index 7bc58a9cec1..a81ddec0e63 100644 --- a/.coveragerc +++ b/.coveragerc @@ -49,6 +49,7 @@ omit = homeassistant/components/asterisk_mbox/* homeassistant/components/asuswrt/device_tracker.py homeassistant/components/august/* + homeassistant/components/aurora_abb_powerone/sensor.py homeassistant/components/automatic/device_tracker.py homeassistant/components/avion/light.py homeassistant/components/azure_event_hub/* diff --git a/CODEOWNERS b/CODEOWNERS index 0bf06d9945f..9777559b448 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -29,6 +29,7 @@ homeassistant/components/aprs/* @PhilRW homeassistant/components/arduino/* @fabaff homeassistant/components/arest/* @fabaff homeassistant/components/asuswrt/* @kennedyshead +homeassistant/components/aurora_abb_powerone/* @davet2001 homeassistant/components/auth/* @home-assistant/core homeassistant/components/automatic/* @armills homeassistant/components/automation/* @home-assistant/core diff --git a/homeassistant/components/aurora_abb_powerone/__init__.py b/homeassistant/components/aurora_abb_powerone/__init__.py new file mode 100644 index 00000000000..087172d1bb5 --- /dev/null +++ b/homeassistant/components/aurora_abb_powerone/__init__.py @@ -0,0 +1 @@ +"""The Aurora ABB Powerone PV inverter sensor integration.""" diff --git a/homeassistant/components/aurora_abb_powerone/manifest.json b/homeassistant/components/aurora_abb_powerone/manifest.json new file mode 100644 index 00000000000..56325dd40af --- /dev/null +++ b/homeassistant/components/aurora_abb_powerone/manifest.json @@ -0,0 +1,10 @@ +{ + "domain": "aurora_abb_powerone", + "name": "Aurora ABB Solar PV", + "documentation": "https://www.home-assistant.io/components/aurora_abb_powerone/", + "dependencies": [], + "codeowners": [ + "@davet2001" + ], + "requirements": ["aurorapy==0.2.6"] +} diff --git a/homeassistant/components/aurora_abb_powerone/sensor.py b/homeassistant/components/aurora_abb_powerone/sensor.py new file mode 100644 index 00000000000..d77fae246d7 --- /dev/null +++ b/homeassistant/components/aurora_abb_powerone/sensor.py @@ -0,0 +1,98 @@ +"""Support for Aurora ABB PowerOne Solar Photvoltaic (PV) inverter.""" + +import logging + +import voluptuous as vol +from aurorapy.client import AuroraSerialClient, AuroraError + +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_ADDRESS, CONF_DEVICE, CONF_NAME, DEVICE_CLASS_POWER, + POWER_WATT) +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entity import Entity + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_ADDRESS = 2 +DEFAULT_NAME = "Solar PV" + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_DEVICE): cv.string, + vol.Optional(CONF_ADDRESS, default=DEFAULT_ADDRESS): cv.positive_int, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, +}) + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Set up the Aurora ABB PowerOne device.""" + devices = [] + comport = config[CONF_DEVICE] + address = config[CONF_ADDRESS] + name = config[CONF_NAME] + + _LOGGER.debug("Intitialising com port=%s address=%s", comport, address) + client = AuroraSerialClient(address, comport, parity='N', timeout=1) + + devices.append(AuroraABBSolarPVMonitorSensor(client, name, 'Power')) + add_entities(devices, True) + + +class AuroraABBSolarPVMonitorSensor(Entity): + """Representation of a Sensor.""" + + def __init__(self, client, name, typename): + """Initialize the sensor.""" + self._name = "{} {}".format(name, typename) + self.client = client + self._state = None + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + @property + def unit_of_measurement(self): + """Return the unit of measurement.""" + return POWER_WATT + + @property + def device_class(self): + """Return the device class.""" + return DEVICE_CLASS_POWER + + def update(self): + """Fetch new state data for the sensor. + + This is the only method that should fetch new data for Home Assistant. + """ + try: + self.client.connect() + # read ADC channel 3 (grid power output) + power_watts = self.client.measure(3, True) + self._state = round(power_watts, 1) + # _LOGGER.debug("Got reading %fW" % self._state) + except AuroraError as error: + # aurorapy does not have different exceptions (yet) for dealing + # with timeout vs other comms errors. + # This means the (normal) situation of no response during darkness + # raises an exception. + # aurorapy (gitlab) pull request merged 29/5/2019. When >0.2.6 is + # released, this could be modified to : + # except AuroraTimeoutError as e: + # Workaround: look at the text of the exception + if "No response after" in str(error): + _LOGGER.debug("No response from inverter (could be dark)") + else: + # print("Exception!!: {}".format(str(e))) + raise error + self._state = None + finally: + if self.client.serline.isOpen(): + self.client.close() diff --git a/requirements_all.txt b/requirements_all.txt index d3eccacfd70..c91114c7683 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -211,6 +211,9 @@ asterisk_mbox==0.5.0 # homeassistant.components.upnp async-upnp-client==0.14.10 +# homeassistant.components.aurora_abb_powerone +aurorapy==0.2.6 + # homeassistant.components.stream av==6.1.2