- smart-home/HEIZUNG.md: komplette Doku zur Ölbrenner-Erkennung (brennerstarts.py), Schwellwerte, Rekonstruktion, Dashboard-Panels, Troubleshooting - smart-home/STATE.md: klare Tabelle mit allen Dienst-URLs (public+intern) und Logins — Grafana/ioBroker/InfluxDB laufen ALLE in CT 143 auf pve-mu-3 - homelab.conf: CT_143_MU3 Beschreibung korrigiert (war "Raspi-Broker"), neue Variablen GRAFANA_URL_*/IOBROKER_URL_*/INFLUX_URL_INTERN + User/Pass (=PW_DEFAULT) damit beim nächsten Mal keine Fragen aufkommen - smart-home/scripts/: alle relevanten Skripte ins Repo: grafana_shot.js (Puppeteer-Login mit admin/astral66) add_month_panel.py (idempotente Monatskacheln im Heizung-Dashboard) brenner_rekonstruktion.py + cleanup_reconstruct.py + check_april.py patch_brenner.sh (Anpassung der Schwellwerte nach Regelkurven-Änderung) - MASTER_INDEX.md: Verweis auf HEIZUNG.md Made-with: Cursor
114 lines
3.6 KiB
Python
114 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Fuegt 'Ölverbrauch je Heizmonat' Panel am unteren Dashboard-Rand hinzu (idempotent)."""
|
|
import json, subprocess, string
|
|
from datetime import date
|
|
|
|
BASE='http://100.66.78.56:3000'
|
|
PANEL_TITLE='Ölverbrauch je Heizmonat (Liter)'
|
|
PANEL_ID=900
|
|
|
|
def curl(path, method='GET', body=None):
|
|
cmd=['curl','-s','--socks5-hostname','127.0.0.1:1055','-u','admin:astral66',
|
|
'-X',method,f'{BASE}{path}']
|
|
if body is not None:
|
|
cmd+=['-H','Content-Type: application/json','-d',json.dumps(body)]
|
|
r=subprocess.run(cmd,capture_output=True,text=True,timeout=30)
|
|
return json.loads(r.stdout) if r.stdout.startswith(('[','{')) else r.stdout
|
|
|
|
# Welche Monate? Alle Kalendermonate ab erstem Monat mit Daten (Jan 2026) bis heute.
|
|
# Damit wir nicht manuell nachpflegen muessen, generieren wir alle Monate von Jan 2026 bis today.month+1
|
|
START_Y, START_M = 2026, 1
|
|
today = date.today()
|
|
months = []
|
|
y, m = START_Y, START_M
|
|
while (y, m) <= (today.year, today.month):
|
|
months.append((y, m))
|
|
y, m = (y+1, 1) if m == 12 else (y, m+1)
|
|
|
|
print('Monate:', months)
|
|
|
|
def alphabet(i):
|
|
# A,B,...,Z,AA,AB,...
|
|
if i < 26:
|
|
return string.ascii_uppercase[i]
|
|
return string.ascii_uppercase[i//26 - 1] + string.ascii_uppercase[i % 26]
|
|
|
|
MON_DE = ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez']
|
|
|
|
targets = []
|
|
overrides = []
|
|
for i, (y, m) in enumerate(months):
|
|
ref = alphabet(i)
|
|
ny, nm = (y+1, 1) if m == 12 else (y, m+1)
|
|
q = (f"SELECT sum(\"value\") / 3600 * 1.89 FROM \"brennerlaufzeit\" "
|
|
f"WHERE time >= '{y}-{m:02d}-01T00:00:00Z' AND time < '{ny}-{nm:02d}-01T00:00:00Z'")
|
|
targets.append({'query': q, 'rawQuery': True, 'refId': ref})
|
|
overrides.append({
|
|
'matcher': {'id': 'byFrameRefID', 'options': ref},
|
|
'properties': [
|
|
{'id': 'displayName', 'value': f'{MON_DE[m-1]} {y}'},
|
|
]
|
|
})
|
|
|
|
# Get current dashboard
|
|
d = curl('/api/dashboards/uid/heizung')
|
|
dash = d['dashboard']
|
|
|
|
# Max y+h
|
|
max_y = 0
|
|
for p in dash['panels']:
|
|
gp = p.get('gridPos', {})
|
|
max_y = max(max_y, gp.get('y', 0) + gp.get('h', 0))
|
|
|
|
# Remove existing panel with same title (idempotent)
|
|
dash['panels'] = [p for p in dash['panels']
|
|
if p.get('title') not in (PANEL_TITLE, 'Ölverbrauch je Heizmonat')
|
|
and p.get('id') != PANEL_ID]
|
|
|
|
new_panel = {
|
|
'id': PANEL_ID,
|
|
'type': 'stat',
|
|
'title': PANEL_TITLE,
|
|
'datasource': 'InfluxDB',
|
|
'gridPos': {'x': 0, 'y': max_y, 'w': 24, 'h': 5},
|
|
'fieldConfig': {
|
|
'defaults': {
|
|
'decimals': 1,
|
|
'unit': 'none',
|
|
'color': {'mode': 'thresholds'},
|
|
'thresholds': {'mode': 'absolute', 'steps': [
|
|
{'value': None, 'color': 'green'},
|
|
{'value': 100, 'color': 'orange'},
|
|
{'value': 250, 'color': 'red'},
|
|
]},
|
|
},
|
|
'overrides': overrides,
|
|
},
|
|
'options': {
|
|
'colorMode': 'background_solid',
|
|
'graphMode': 'none',
|
|
'justifyMode': 'center',
|
|
'reduceOptions': {
|
|
'calcs': ['lastNotNull'],
|
|
'fields': '',
|
|
'values': False,
|
|
},
|
|
'textMode': 'value_and_name',
|
|
'orientation': 'vertical',
|
|
'text': {
|
|
'titleSize': 14,
|
|
'valueSize': 32,
|
|
},
|
|
'wideLayout': True,
|
|
'percentChangeColorMode': 'standard',
|
|
},
|
|
'targets': targets,
|
|
}
|
|
dash['panels'].append(new_panel)
|
|
|
|
resp = curl('/api/dashboards/db', 'POST', {
|
|
'dashboard': dash,
|
|
'overwrite': True,
|
|
'message': f'add monthly oil consumption tiles ({len(months)} months)',
|
|
})
|
|
print(resp)
|