Skip to content

Commit

Permalink
smartmeter: update parameters, item updates only every x seconds
Browse files Browse the repository at this point in the history
  • Loading branch information
Morg42 committed Dec 13, 2024
1 parent 355303f commit 9789b19
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 11 deletions.
23 changes: 23 additions & 0 deletions smartmeter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import asyncio
import threading
import time
import sys

# find out if we can import serial - if not, the plugin might not start anyway
Expand Down Expand Up @@ -110,6 +111,10 @@ def __init__(self, sh):
self.async_connected = False
self.use_asyncio = False

# update items only every x seconds
self.timefilter = -1
self._last_item_update = -1

# load parameters from config
self._load_parameters()

Expand Down Expand Up @@ -297,6 +302,14 @@ def _load_parameters(self):
else:
self.logger.warning(f'async listening requested but protocol is {self.protocol} instead of SML, reverting to polling')

if self.use_asyncio:
self.timefilter = self.get_parameter_value('time_filter')
if self.timefilter == -1:
self.timefilter = self.cycle
if self.timefilter < 0:
self.timefilter = 0
self._config['timefilter'] = self.timefilter

if not self.use_asyncio and not (self.cycle or self.crontab):
self.logger.warning(f'{self.get_fullname()}: no update cycle or crontab set. The smartmeter will not be queried automatically')

Expand Down Expand Up @@ -372,12 +385,18 @@ def _update_values(self, result: dict):
# self.logger.debug(f'running _update_values with {result}')
self.obis_results.update(result)

# if "update items only every x seconds" is set:
if self.timefilter > 0 and self._last_item_update + self.timefilter > time.time():
self.logger.debug(f'timefilter active, {int(self._last_item_update + self.timefilter - time.time())} seconds remaining')
return

if 'readout' in result:
for item in self.get_items_for_mapping('readout'):
item(result['readout'], self.get_fullname())
self.logger.debug(f'set item {item} to readout {result["readout"]}')
del result['readout']

update = -1
# check all obis codes
for obis, vlist in result.items():
if not self._is_obis_code_wanted(obis):
Expand All @@ -402,11 +421,15 @@ def _update_values(self, result: dict):
itemValue = self._convert_value(val, converter)
# self.logger.debug(f'conversion yielded {itemValue} from {val} for converter "{converter}"')
item(itemValue, self.get_fullname())
if update < 0:
update = time.time()
self.logger.debug(f'set item {item} for obis code {obis}:{prop} to value {itemValue}')
except ValueError as e:
self.logger.error(f'error while converting value {val} for item {item}, obis code {obis}: {e}')
else:
self.logger.debug(f'for item {item} and obis code {obis}:{prop} no content was received')
if update > 0:
self._last_item_update = update

async def plugin_coro(self):
"""
Expand Down
38 changes: 27 additions & 11 deletions smartmeter/plugin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugin:
de: 'Unterstützung für Smartmeter, die DLMS (Device Language Message Specification, IEC 62056-21) oder SML (Smart Message Language) nutzen und OBIS Codes liefern'
en: 'Support for smartmeter using DLMS (Device Language Message Specification, IEC 62056-21) or SML (Smart Message Language) and delivering OBIS codes'
maintainer: Morg
tester: bmxp, onkelandy
tester: bmxp, onkelandy, sisamiwe
state: develop
keywords: smartmeter ehz dlms sml obis smartmeter
multi_instance: true # plugin supports multi instance
Expand Down Expand Up @@ -49,8 +49,8 @@ parameters:
type: bool
default: true
description:
de: 'Bei Beenden der Verbindung automatisch erneut verbinden (nur bei asyncio Betrieb)'
en: 'automatically reconnect on disconnect (only with asyncio operation)'
de: 'Bei Beenden der Verbindung automatisch erneut verbinden (nur bei ständigem Empfang)'
en: 'automatically reconnect on disconnect (only with continuous listening)'
timeout:
type: int
default: 2
Expand Down Expand Up @@ -80,9 +80,23 @@ parameters:
type: bool
default: true
description:
de: 'Gerät regelmäßig (cycle/crontab) abfragen statt asynchronem Empfang (nur SML)'
en: 'periodically query device (cycle/crontab) instead of asynchronous receive (SML only)'

de: 'Gerät regelmäßig abfragen (cycle/crontab) statt ständigem Empfang (nur SML)'
en: 'periodically query device (cycle/crontab) instead of continuous listen (SML only)'
time_filter:
type: int
default: 0
description:
de: 'Im "ständig empfangen"-Modus Item-Updates nur alle x Sekunden senden.'
en: 'In continuous listen mode only update items every x seconds.'
description_long:
de: >
Im "ständig empfangen"-Modus Item-Updates nur alle x Sekunden senden.
x = 0: alle Updates senden.
x = -1: den Wert von "cycle" verwenden.
en: >
In continuous listen mode only update items every x seconds.
x = 0: send all updates
x = -1: use "cycle" parameter for x
# DLMS parameters
baudrate_min:
type: int
Expand Down Expand Up @@ -131,10 +145,12 @@ parameters:
en: 'Size of read buffer. At least twice the size of maximum message length (SML only)'
device_type:
type: str
default: 'raw'
default: ''
valid_list:
- '' # needs to be edited if new corrections are added
description:
de: 'Name des Gerätes (nur SML)'
en: 'Name of Smartmeter (SML only)'
de: 'Typ des Gerätes, ggf. notwendig für spezielle Behandlung (nur SML)'
en: 'type of smartmeter, possibly necessary for quirks (SML only)'
date_offset:
type: int
default: 0
Expand Down Expand Up @@ -249,8 +265,8 @@ item_attributes:
obis_readout:
type: str
description:
de: 'Der komplette Auslesepuffer wird für eigene Untersuchungen gespeichert'
en: 'the complete readout will be saved for own examinations'
de: 'Der komplette Auslesepuffer wird für eigene Untersuchungen gespeichert (nur DLMS)'
en: 'the complete readout will be saved for own examinations (DLMS only)'

logic_parameters: NONE

Expand Down

0 comments on commit 9789b19

Please sign in to comment.