Dsmr reader (#28701)

* Added DSMR Reader platform

- Added DSMR Reader platform
- Updated codeowners for other components I added earlier

* Move sensor definitions to new file

* Sensor definitions in new file

* Add energy prices from MQTT

* lint fixes

* Black formatted some files

* Update .coveragerc

* Support transform methods on definitions

* Manifest mangled by Black, fixed

* Visual studio code reformatting dictionary error

* Fix issues with code, remove unrelated manifest changes

* Update CODEOWNERS
This commit is contained in:
Wim Haanstra 2019-11-28 20:30:24 +01:00 committed by Fabian Affolter
parent b847d55077
commit daed314585
6 changed files with 345 additions and 0 deletions

View File

@ -163,6 +163,7 @@ omit =
homeassistant/components/doorbird/*
homeassistant/components/dovado/*
homeassistant/components/downloader/*
homeassistant/components/dsmr_reader/*
homeassistant/components/dte_energy_bridge/sensor.py
homeassistant/components/dublin_bus_transport/sensor.py
homeassistant/components/duke_energy/sensor.py

View File

@ -78,6 +78,7 @@ homeassistant/components/device_automation/* @home-assistant/core
homeassistant/components/digital_ocean/* @fabaff
homeassistant/components/discogs/* @thibmaek
homeassistant/components/doorbird/* @oblogic7
homeassistant/components/dsmr_reader/* @depl0y
homeassistant/components/dweet/* @fabaff
homeassistant/components/ecobee/* @marthoc
homeassistant/components/ecovacs/* @OverloadUT

View File

@ -0,0 +1 @@
"""The DSMR Reader component."""

View File

@ -0,0 +1,243 @@
"""Definitions for DSMR Reader sensors added to MQTT."""
def dsmr_transform(value):
"""Transform DSMR version value to right format."""
return float(value) / 10
def tariff_transform(value):
"""Transform tariff from number to description."""
if value == "1":
return "low"
return "high"
DEFINITIONS = {
"dsmr/reading/electricity_delivered_1": {
"name": "Low tariff usage",
"icon": "mdi:flash",
"unit": "kWh",
},
"dsmr/reading/electricity_returned_1": {
"name": "Low tariff returned",
"icon": "mdi:flash-outline",
"unit": "kWh",
},
"dsmr/reading/electricity_delivered_2": {
"name": "High tariff usage",
"icon": "mdi:flash",
"unit": "kWh",
},
"dsmr/reading/electricity_returned_2": {
"name": "High tariff returned",
"icon": "mdi:flash-outline",
"unit": "kWh",
},
"dsmr/reading/electricity_currently_delivered": {
"name": "Current power usage",
"icon": "mdi:flash",
"unit": "kW",
},
"dsmr/reading/electricity_currently_returned": {
"name": "Current power return",
"icon": "mdi:flash-outline",
"unit": "kW",
},
"dsmr/reading/phase_currently_delivered_l1": {
"name": "Current power usage L1",
"icon": "mdi:flash",
"unit": "kW",
},
"dsmr/reading/phase_currently_delivered_l2": {
"name": "Current power usage L2",
"icon": "mdi:flash",
"unit": "kW",
},
"dsmr/reading/phase_currently_delivered_l3": {
"name": "Current power usage L3",
"icon": "mdi:flash",
"unit": "kW",
},
"dsmr/reading/phase_currently_returned_l1": {
"name": "Current power return L1",
"icon": "mdi:flash-outline",
"unit": "kW",
},
"dsmr/reading/phase_currently_returned_l2": {
"name": "Current power return L2",
"icon": "mdi:flash-outline",
"unit": "kW",
},
"dsmr/reading/phase_currently_returned_l3": {
"name": "Current power return L3",
"icon": "mdi:flash-outline",
"unit": "kW",
},
"dsmr/reading/extra_device_delivered": {
"name": "Gas meter usage",
"icon": "mdi:fire",
"unit": "m3",
},
"dsmr/reading/phase_voltage_l1": {
"name": "Current voltage L1",
"icon": "mdi:flash",
"unit": "V",
},
"dsmr/reading/phase_voltage_l2": {
"name": "Current voltage L2",
"icon": "mdi:flash",
"unit": "V",
},
"dsmr/reading/phase_voltage_l3": {
"name": "Current voltage L3",
"icon": "mdi:flash",
"unit": "V",
},
"dsmr/consumption/gas/delivered": {
"name": "Gas usage",
"icon": "mdi:fire",
"unit": "m3",
},
"dsmr/consumption/gas/currently_delivered": {
"name": "Current gas usage",
"icon": "mdi:fire",
"unit": "m3",
},
"dsmr/consumption/gas/read_at": {
"name": "Gas meter read",
"icon": "mdi:clock",
"unit": "",
},
"dsmr/day-consumption/electricity1": {
"name": "Low tariff usage",
"icon": "mdi:counter",
"unit": "kWh",
},
"dsmr/day-consumption/electricity2": {
"name": "High tariff usage",
"icon": "mdi:counter",
"unit": "kWh",
},
"dsmr/day-consumption/electricity1_returned": {
"name": "Low tariff return",
"icon": "mdi:counter",
"unit": "kWh",
},
"dsmr/day-consumption/electricity2_returned": {
"name": "High tariff return",
"icon": "mdi:counter",
"unit": "kWh",
},
"dsmr/day-consumption/electricity_merged": {
"name": "Power usage total",
"icon": "mdi:counter",
"unit": "kWh",
},
"dsmr/day-consumption/electricity_returned_merged": {
"name": "Power return total",
"icon": "mdi:counter",
"unit": "kWh",
},
"dsmr/day-consumption/electricity1_cost": {
"name": "Low tariff cost",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/electricity2_cost": {
"name": "High tariff cost",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/electricity_cost_merged": {
"name": "Power total cost",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/gas": {
"name": "Gas usage",
"icon": "mdi:counter",
"unit": "m3",
},
"dsmr/day-consumption/gas_cost": {
"name": "Gas cost",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/total_cost": {
"name": "Total cost",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/energy_supplier_price_electricity_delivered_1": {
"name": "Low tariff delivered price",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/energy_supplier_price_electricity_delivered_2": {
"name": "High tariff delivered price",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/energy_supplier_price_electricity_returned_1": {
"name": "Low tariff returned price",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/energy_supplier_price_electricity_returned_2": {
"name": "High tariff returned price",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/day-consumption/energy_supplier_price_gas": {
"name": "Gas price",
"icon": "mdi:currency-eur",
"unit": "",
},
"dsmr/meter-stats/dsmr_version": {
"name": "DSMR version",
"icon": "mdi:alert-circle",
"transform": dsmr_transform,
},
"dsmr/meter-stats/electricity_tariff": {
"name": "Electricity tariff",
"icon": "mdi:flash",
"transform": tariff_transform,
},
"dsmr/meter-stats/power_failure_count": {
"name": "Power failure count",
"icon": "mdi:flash",
},
"dsmr/meter-stats/long_power_failure_count": {
"name": "Long power failure count",
"icon": "mdi:flash",
},
"dsmr/meter-stats/voltage_sag_count_l1": {
"name": "Voltage sag L1",
"icon": "mdi:flash",
},
"dsmr/meter-stats/voltage_sag_count_l2": {
"name": "Voltage sag L2",
"icon": "mdi:flash",
},
"dsmr/meter-stats/voltage_sag_count_l3": {
"name": "Voltage sag L3",
"icon": "mdi:flash",
},
"dsmr/meter-stats/voltage_swell_count_l1": {
"name": "Voltage swell L1",
"icon": "mdi:flash",
},
"dsmr/meter-stats/voltage_swell_count_l2": {
"name": "Voltage swell L2",
"icon": "mdi:flash",
},
"dsmr/meter-stats/voltage_swell_count_l3": {
"name": "Voltage swell L3",
"icon": "mdi:flash",
},
"dsmr/meter-stats/rejected_telegrams": {
"name": "Rejected telegrams",
"icon": "mdi:flash",
},
}

View File

@ -0,0 +1,12 @@
{
"domain": "dsmr_reader",
"name": "DSMR Reader",
"documentation": "https://www.home-assistant.io/components/dsmr_reader",
"requirements": [],
"dependencies": [
"mqtt"
],
"codeowners": [
"@depl0y"
]
}

View File

@ -0,0 +1,87 @@
"""Support for DSMR Reader through MQTT."""
import logging
from homeassistant.components import mqtt
from homeassistant.core import callback
from homeassistant.helpers.entity import Entity
from homeassistant.util import slugify
from .definitions import DEFINITIONS
_LOGGER = logging.getLogger(__name__)
DOMAIN = "dsmr_reader"
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up DSMR Reader sensors."""
sensors = []
for topic in DEFINITIONS:
sensors.append(DSMRSensor(topic))
async_add_entities(sensors)
class DSMRSensor(Entity):
"""Representation of a DSMR sensor that is updated via MQTT."""
def __init__(self, topic):
"""Initialize the sensor."""
self._definition = DEFINITIONS[topic]
self._entity_id = slugify(topic.replace("/", "_"))
self._topic = topic
self._name = self._definition["name"]
self._unit_of_measurement = (
self._definition["unit"] if "unit" in self._definition else ""
)
self._icon = self._definition["icon"] if "icon" in self._definition else None
self._transform = (
self._definition["transform"] if "transform" in self._definition else None
)
self._state = None
async def async_added_to_hass(self):
"""Subscribe to MQTT events."""
@callback
def message_received(message):
"""Handle new MQTT messages."""
if self._transform is not None:
self._state = self._transform(message.payload)
else:
self._state = message.payload
self.async_schedule_update_ha_state()
return await mqtt.async_subscribe(self.hass, self._topic, message_received, 1)
@property
def name(self):
"""Return the name of the sensor supplied in constructor."""
return self._name
@property
def entity_id(self):
"""Return the entity ID for this sensor."""
return f"sensor.{self._entity_id}"
@property
def state(self):
"""Return the current state of the entity."""
return self._state
@property
def unit_of_measurement(self):
"""Return the unit_of_measurement of this sensor."""
return self._unit_of_measurement
@property
def icon(self):
"""Return the icon of this sensor."""
return self._icon