#!/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)