2 Commits

Author SHA1 Message Date
Hauke Petersen
3005dbe7e7 verbump to 0.0.4 2022-09-02 11:16:41 +02:00
Hauke Petersen
09a116984c verbump to 0.0.3 2022-09-02 10:19:11 +02:00
2 changed files with 66 additions and 13 deletions

View File

@@ -21,7 +21,7 @@
import setuptools
name = "steckie"
ver = "0.0.2"
ver = "0.0.4"
desc = 'Read state from Tasmota smart plugs'
setuptools.setup(

View File

@@ -20,12 +20,14 @@ import sys
import json
import pytz
import logging
import dateutil
import urllib.request
from datetime import datetime
from deichapp import Deichapp
from deichflux import Deichflux
from apscheduler.schedulers.blocking import BlockingScheduler
import dateutil
CONFIG_DEFAULT = {
"interval": 5.0,
@@ -39,6 +41,30 @@ class Steckie(Deichapp):
self.scheduler = BlockingScheduler()
self.db = Deichflux(self.cfg["db"])
logging.warning("Steckie V0.72 - loaded...")
self.counters = {}
for name in self.cfg["devs"]:
self.counters[name] = {
"last": None,
"year": 0.0,
"month": 0.0,
"day": 0.0,
}
# read latest known values from database
query = f'SELECT e_total_kwh, e_year_kwh, e_month_kwh, e_day_kwh ' \
f'FROM "{self.cfg["measurement"]}" WHERE "name"=\'{name}\' ' \
f'ORDER BY DESC LIMIT 1'
res = self.db.query(query, None)
for p in res.get_points():
self.counters[name]["last"] = dateutil.parser.isoparse(p["time"])
total = p["e_total_kwh"]
self.counters[name]["year"] = total - p["e_year_kwh"]
self.counters[name]["month"] = total - p["e_month_kwh"]
self.counters[name]["day"] = total - p["e_day_kwh"]
logging.warning(f'Found {name}: current total is {total}kWh')
def run(self):
for name, url in self.cfg["devs"].items():
self.scheduler.add_job(self.query,
@@ -48,30 +74,57 @@ class Steckie(Deichapp):
self.scheduler.start()
def query(self, name, url):
logging.warning(f'query {name} -> {url}')
cnt = self.counters[name]
now = pytz.UTC.localize(datetime.utcnow())
try:
with urllib.request.urlopen(f'{url}/cm?cmnd=Status%208') as raw:
resp = json.loads(raw.read().decode("utf-8"))
logging.warning(resp)
except Exception as e:
logging.warning(f'no response from {name} -> {e}')
logging.warning(f'{name} - no response: {e}')
return
point = [{
total = float(resp["StatusSNS"]["ENERGY"]["Total"])
# initialize values if this is the first time we read them
if cnt["last"] is None:
cnt["last"] = now
for f in ("year", "month", "day"):
cnt[f] = total
# reset values if a when new time frame starts
now_local = now.astimezone(pytz.timezone("Europe/Berlin"))
last_local = cnt["last"].astimezone(pytz.timezone("Europe/Berlin"))
if now_local.date().year != last_local.date().year:
self.cnt["year"] = total
self.cnt["month"] = total
self.cnt["day"] = total
elif now_local.date().month != last_local.date().month:
self.cnt["month"] = total
self.cnt["day"] = total
elif now_local.date().day != last_local.date().day:
self.cnt["day"] = total
cnt["last"] = now
# write data to DB
point = {
"measurement": self.cfg["measurement"],
"tags": {
"name": name,
},
"time": pytz.UTC.localize(datetime.utcnow()).isoformat(),
"time": now.isoformat(),
"fields": {
"voltage": float(resp['StatusSNS']['ENERGY']['Voltage']),
"current": float(resp['StatusSNS']['ENERGY']['Current']),
"pwr": float(resp['StatusSNS']['ENERGY']['ApparentPower']),
"pwr_r": float(resp['StatusSNS']['ENERGY']['ReactivePower']),
"factor": float(resp['StatusSNS']['ENERGY']['Factor']),
"e_daily": float(resp['StatusSNS']['ENERGY']['Today']),
"power_w": float(resp["StatusSNS"]["ENERGY"]["Power"]),
"voltage_v": float(resp["StatusSNS"]["ENERGY"]["Voltage"]),
"current_a": float(resp["StatusSNS"]["ENERGY"]["Current"]),
"factor": float(resp["StatusSNS"]["ENERGY"]["Factor"]),
"e_total_kwh": total,
"e_year_kwh": total - cnt["year"],
"e_month_kwh": total - cnt["month"],
"e_day_kwh": total - cnt["day"],
}
}]
}
logging.warning(f'{name} - power:{point["fields"]["power_w"]:.1f}W '
f'total:{point["fields"]["e_total_kwh"]}kWh')
self.db.write(point)