Compare commits
5 Commits
1563945858
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8fb9fcadb | ||
|
|
a22b344028 | ||
|
|
cb3e651983 | ||
|
|
3005dbe7e7 | ||
|
|
09a116984c |
2
setup.py
2
setup.py
@@ -21,7 +21,7 @@
|
||||
import setuptools
|
||||
|
||||
name = "steckie"
|
||||
ver = "0.0.2"
|
||||
ver = "0.0.7"
|
||||
desc = 'Read state from Tasmota smart plugs'
|
||||
|
||||
setuptools.setup(
|
||||
|
||||
@@ -20,13 +20,13 @@ import sys
|
||||
import json
|
||||
import pytz
|
||||
import logging
|
||||
import urllib.request
|
||||
import dateutil
|
||||
import urllib
|
||||
from datetime import datetime
|
||||
from deichapp import Deichapp
|
||||
from deichflux import Deichflux
|
||||
from deichfluxx import Deichfluxx
|
||||
from apscheduler.schedulers.blocking import BlockingScheduler
|
||||
|
||||
|
||||
CONFIG_DEFAULT = {
|
||||
"interval": 5.0,
|
||||
}
|
||||
@@ -37,7 +37,31 @@ class Steckie(Deichapp):
|
||||
super().__init__(cfg_file, CONFIG_DEFAULT)
|
||||
|
||||
self.scheduler = BlockingScheduler()
|
||||
self.db = Deichflux(self.cfg["db"])
|
||||
self.db = Deichfluxx.init(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():
|
||||
@@ -48,30 +72,58 @@ 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:
|
||||
with urllib.request.urlopen(f'{url}/cm?cmnd=Status%208',
|
||||
timeout=self.cfg["timeout"]) 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:
|
||||
cnt["year"] = total
|
||||
cnt["month"] = total
|
||||
cnt["day"] = total
|
||||
elif now_local.date().month != last_local.date().month:
|
||||
cnt["month"] = total
|
||||
cnt["day"] = total
|
||||
elif now_local.date().day != last_local.date().day:
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user