Extract PVOutput logic into PyPi package (#62625)

This commit is contained in:
Franck Nijhof 2021-12-22 21:17:23 +01:00 committed by GitHub
parent 51a49f3d39
commit e3f7d9a803
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 66 deletions

View File

@ -717,7 +717,7 @@ homeassistant/components/ps4/* @ktnrg45
tests/components/ps4/* @ktnrg45 tests/components/ps4/* @ktnrg45
homeassistant/components/push/* @dgomes homeassistant/components/push/* @dgomes
tests/components/push/* @dgomes tests/components/push/* @dgomes
homeassistant/components/pvoutput/* @fabaff homeassistant/components/pvoutput/* @fabaff @frenck
homeassistant/components/pvpc_hourly_pricing/* @azogue homeassistant/components/pvpc_hourly_pricing/* @azogue
tests/components/pvpc_hourly_pricing/* @azogue tests/components/pvpc_hourly_pricing/* @azogue
homeassistant/components/qbittorrent/* @geoffreylagaisse homeassistant/components/qbittorrent/* @geoffreylagaisse

View File

@ -2,7 +2,7 @@
"domain": "pvoutput", "domain": "pvoutput",
"name": "PVOutput", "name": "PVOutput",
"documentation": "https://www.home-assistant.io/integrations/pvoutput", "documentation": "https://www.home-assistant.io/integrations/pvoutput",
"after_dependencies": ["rest"], "codeowners": ["@fabaff", "@frenck"],
"codeowners": ["@fabaff"], "requirements": ["pvo==0.1.0"],
"iot_class": "cloud_polling" "iot_class": "cloud_polling"
} }

View File

@ -1,13 +1,12 @@
"""Support for getting collected information from PVOutput.""" """Support for getting collected information from PVOutput."""
from __future__ import annotations from __future__ import annotations
from collections import namedtuple
from datetime import timedelta from datetime import timedelta
import logging import logging
from pvo import PVOutput, PVOutputError
import voluptuous as vol import voluptuous as vol
from homeassistant.components.rest.data import RestData
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
PLATFORM_SCHEMA, PLATFORM_SCHEMA,
SensorDeviceClass, SensorDeviceClass,
@ -15,19 +14,15 @@ from homeassistant.components.sensor import (
SensorStateClass, SensorStateClass,
) )
from homeassistant.const import ( from homeassistant.const import (
ATTR_DATE,
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
ATTR_TIME,
ATTR_VOLTAGE, ATTR_VOLTAGE,
CONF_API_KEY, CONF_API_KEY,
CONF_NAME, CONF_NAME,
ENERGY_WATT_HOUR, ENERGY_WATT_HOUR,
) )
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
_ENDPOINT = "https://pvoutput.org/service/r2/getstatus.jsp"
ATTR_ENERGY_GENERATION = "energy_generation" ATTR_ENERGY_GENERATION = "energy_generation"
ATTR_POWER_GENERATION = "power_generation" ATTR_POWER_GENERATION = "power_generation"
@ -38,7 +33,6 @@ ATTR_EFFICIENCY = "efficiency"
CONF_SYSTEM_ID = "system_id" CONF_SYSTEM_ID = "system_id"
DEFAULT_NAME = "PVOutput" DEFAULT_NAME = "PVOutput"
DEFAULT_VERIFY_SSL = True
SCAN_INTERVAL = timedelta(minutes=2) SCAN_INTERVAL = timedelta(minutes=2)
@ -54,21 +48,19 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the PVOutput sensor.""" """Set up the PVOutput sensor."""
name = config.get(CONF_NAME) name = config.get(CONF_NAME)
api_key = config.get(CONF_API_KEY)
system_id = config.get(CONF_SYSTEM_ID)
method = "GET"
payload = auth = None
verify_ssl = DEFAULT_VERIFY_SSL
headers = {"X-Pvoutput-Apikey": api_key, "X-Pvoutput-SystemId": system_id}
rest = RestData(hass, method, _ENDPOINT, auth, headers, None, payload, verify_ssl) pvoutput = PVOutput(
await rest.async_update() api_key=config[CONF_API_KEY],
system_id=config[CONF_SYSTEM_ID],
)
if rest.data is None: try:
status = await pvoutput.status()
except PVOutputError:
_LOGGER.error("Unable to fetch data from PVOutput") _LOGGER.error("Unable to fetch data from PVOutput")
return False return False
async_add_entities([PvoutputSensor(rest, name)]) async_add_entities([PvoutputSensor(pvoutput, status, name)])
class PvoutputSensor(SensorEntity): class PvoutputSensor(SensorEntity):
@ -78,62 +70,30 @@ class PvoutputSensor(SensorEntity):
_attr_device_class = SensorDeviceClass.ENERGY _attr_device_class = SensorDeviceClass.ENERGY
_attr_native_unit_of_measurement = ENERGY_WATT_HOUR _attr_native_unit_of_measurement = ENERGY_WATT_HOUR
def __init__(self, rest, name): def __init__(self, pvoutput, status, name):
"""Initialize a PVOutput sensor.""" """Initialize a PVOutput sensor."""
self.rest = rest
self._attr_name = name self._attr_name = name
self.pvcoutput = None self.pvoutput = pvoutput
self.status = namedtuple( self.status = status
"status",
[
ATTR_DATE,
ATTR_TIME,
ATTR_ENERGY_GENERATION,
ATTR_POWER_GENERATION,
ATTR_ENERGY_CONSUMPTION,
ATTR_POWER_CONSUMPTION,
ATTR_EFFICIENCY,
ATTR_TEMPERATURE,
ATTR_VOLTAGE,
],
)
@property @property
def native_value(self): def native_value(self):
"""Return the state of the device.""" """Return the state of the device."""
if self.pvcoutput is not None: return self.status.energy_generation
return self.pvcoutput.energy_generation
return None
@property @property
def extra_state_attributes(self): def extra_state_attributes(self):
"""Return the state attributes of the monitored installation.""" """Return the state attributes of the monitored installation."""
if self.pvcoutput is not None:
return { return {
ATTR_ENERGY_GENERATION: self.pvcoutput.energy_generation, ATTR_ENERGY_GENERATION: self.status.energy_generation,
ATTR_POWER_GENERATION: self.pvcoutput.power_generation, ATTR_POWER_GENERATION: self.status.power_generation,
ATTR_ENERGY_CONSUMPTION: self.pvcoutput.energy_consumption, ATTR_ENERGY_CONSUMPTION: self.status.energy_consumption,
ATTR_POWER_CONSUMPTION: self.pvcoutput.power_consumption, ATTR_POWER_CONSUMPTION: self.status.power_consumption,
ATTR_EFFICIENCY: self.pvcoutput.efficiency, ATTR_EFFICIENCY: self.status.normalized_ouput,
ATTR_TEMPERATURE: self.pvcoutput.temperature, ATTR_TEMPERATURE: self.status.temperature,
ATTR_VOLTAGE: self.pvcoutput.voltage, ATTR_VOLTAGE: self.status.voltage,
} }
async def async_update(self): async def async_update(self):
"""Get the latest data from the PVOutput API and updates the state.""" """Get the latest data from the PVOutput API and updates the state."""
await self.rest.async_update() self.status = await self.pvoutput.status()
self._async_update_from_rest_data()
async def async_added_to_hass(self):
"""Ensure the data from the initial update is reflected in the state."""
self._async_update_from_rest_data()
@callback
def _async_update_from_rest_data(self):
"""Update state from the rest data."""
try:
# https://pvoutput.org/help/api_specification.html#get-status-service
self.pvcoutput = self.status._make(self.rest.data.split(","))
except TypeError:
self.pvcoutput = None
_LOGGER.error("Unable to fetch data from PVOutput. %s", self.rest.data)

View File

@ -1291,6 +1291,9 @@ pushbullet.py==0.11.0
# homeassistant.components.pushover # homeassistant.components.pushover
pushover_complete==1.1.1 pushover_complete==1.1.1
# homeassistant.components.pvoutput
pvo==0.1.0
# homeassistant.components.rpi_gpio_pwm # homeassistant.components.rpi_gpio_pwm
pwmled==1.6.7 pwmled==1.6.7