Man sollte sich aber überlegen ob man das wirklich braucht.
Da es (erstmal) keine Systemvariablen für die Daten gibt kann man diese nur über die WebUI sehen bzw. per Script auslesen.
(da wir eine CCU/RM haben ließe sich das natürlich ändern)
Pro IP-Messaktor wir ein zusätzliches Programm angelegt was (per default) immer um 00:00 ausgeführt wird. Ich bin da kein Freund von x-Programme samt Script "zeitgleich" zu triggern. Auch das kann man natürlich ändern indem man Trigger-Zeitpunkt oder Script-Verzögerung variiert.
(oder man packt alle "Mitternachts-Berechnungs-Scripte" in ein Programm)
Durchführung Teil 1:
- A: man geht in seine Geräteliste (> Einstellungen > Geräte), sucht sich den Messaktor, klappt die Kanäle über das + aus und kopiert den Namen des "Messwertkanals" (Statusmeldung Messwertkanal) in eine Zwischenablage
- B: man kopiert folgendes Script und fügt es in das "Script testen" Fenster (> Programme und Verknüpfungen > Programme --> Button "Script testen" in der unteren Leiste) ein.
- C: man holt den Namen des Messwertkanals aus der Zwischenablage und fügt ihn in Zeile 10 bei "string NameMesswertkanal" innerhalb der einfachen Anführungszeichen ein
Script:Code: Alles auswählen
!- HmIP Messaktoren FSM/PSM/BSM usw. !- Hinzufügen von Verbrauchszähleranzeige Heute / Gestern / vergangene 7 Tage / vergangene 30 Tage zur WebUI !- Hinzufügen des 00:00 WebUI-Programms 'prgSetEnergyValuesAtMidnight' für die Berechnungen !- v1.1 by Baxxy / 08.12.23 !- Forum-Link: https://homematic-forum.de/forum/viewtopic.php?f=60&t=80952&start=10#p788494 !- ab CCU3/RM-Firmware 3.73.9, ältere Versionen können die Verbrauchszähleranzeigen nicht anzeigen !- Name des Messwertkanals wie in der WebUI vergeben einfügen! string NameMesswertkanal = 'Beleuchtung Balkon PSM DCD:6 - Messwertkanal'; !- Ab hier bitte die Finger weg !!! !- ---------------------------- object oChnPM = channels.Get (NameMesswertkanal); if (oChnPM) { if (oChnPM.HssType() == "ENERGIE_METER_TRANSMITTER") { integer iChnID = oChnPM.ID(); WriteLine("Kanal-ID: --> "#iChnID); string meta0_key = "energy0"; var meta0_val = 0; string meta1_key = "energy1"; var meta1_val = 0; string meta2_key = "energy30"; var meta2_val = 0; string meta3_key = "energy7"; var meta3_val = 0; string meta4_key = "energyCounter30Days"; var meta4_val = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"; oChnPM.AddMetaData (meta0_key,meta0_val); oChnPM.AddMetaData (meta1_key,meta1_val); oChnPM.AddMetaData (meta2_key,meta2_val); oChnPM.AddMetaData (meta3_key,meta3_val); oChnPM.AddMetaData (meta4_key,meta4_val); WriteLine ("Metadaten angelegt!"); string sPRGName= "prgSetEnergyValuesAtMidnight_"#iChnID; WriteLine ("Backup/Restore CCU Programme by Black 2023"); WriteLine ("Backup erstellt vom SDV V5.03.01D-HF1 LCL am 08.12.2023 15:45:45"); WriteLine ("CCU ProgrammName: \"" # sPRGName # "\""); WriteLine ("----------------------------"); object oPRG= dom.GetObject (ID_PROGRAMS).Get (sPRGName); if (oPRG) {WriteLine ("Programm existiert schon mit dem Namen \"" # oPRG.Name () # "\" --> Abbruch"); quit;} oPRG= dom.CreateObject (OT_PROGRAM,sPRGName); if (!oPRG) {WriteLine ("Programm konnte nicht angelegt werden. --> Abbruch"); quit; } dom.GetObject (ID_PROGRAMS).Add (oPRG.ID () ); oPRG.PrgInfo ("Mitternachtsberechnungen für: "#NameMesswertkanal); oPRG.Active (false); oPRG.Enabled (true); oPRG.Visible (true); oPRG.Internal (true); object oCND; object oSCND; object oDST; object oSDST; object oOBJ; string sScript; !-------- MainCondition oCND= oPRG.MainCondition(); oCND.CndOperatorType (1); object oRULE= oPRG.Rule (); !-------- Rule 0 oRULE.RuleOperatorType (0); oRULE.ElseIfFlag (true); oCND=oRULE.RuleAddCondition(); !- Condition 0 oCND.CndOperatorType (0); oSCND=oCND.CndAddSingle (); !- Single Condition 0 string sVal=^0^; if (!oSCND.AddMetaData("SDV_OperatorType",sVal)){oSCND.MetaData("SDV_OperatorType",sVal);} oSCND.ConditionType(3); oSCND.ConditionType2(13); oSCND.OperatorType(0); oSCND.NegateCondition(false); oSCND.ConditionChannel(65535); oSCND.LeftValType(24); oSCND.LeftVal(@2023-12-08 14:45:45@); oSCND.RightVal1ValType(18); oSCND.RightVal2ValType(0); oOBJ= dom.CreateObject (OT_CALENDARDP,"Zeitmodul"); dom.GetObject(ID_CALENDARDPS).Add(oOBJ); oOBJ.TimerType(9); oOBJ.Time(@2000-01-01 00:00:00@); oOBJ.CalDuration(0); oOBJ.TimeSeconds(946681200); oOBJ.CalRepeatTime(@1970-01-01 01:00:00@); oOBJ.Weekdays(0); oOBJ.Period(0); oOBJ.Begin(@2000-01-01 00:00:00@); oOBJ.End(@1970-01-01 01:00:00@); oOBJ.CalRepetitionCount(0); oOBJ.CalRepetitionValue(0); oOBJ.SunOffsetType(0); oSCND.RightVal1 (oOBJ.ID () ); !-------- Rule Destination oDST=oRULE.RuleDestination(); oDST.BreakOnRestart (true); oSDST=oDST.DestAddSingle (); !- Single Destination 0 oSDST.DestinationParam(20); oSDST.DestinationValueType(20); oSDST.DestinationChannel(65535); oSDST.DestinationDP(65535); oSDST.DestinationValueParamType(0); sScript = "integer loop = 0;\nstring last30Days = '';\nstring val;\nreal energy7 = 0.0;\nreal energy30 = 0.0;\nobject chn = dom.GetObject('"#iChnID#"');\n! Retrieve energyCounter30Days\nstring energyCounter30Days = chn.MetaData('energyCounter30Days');\n! Retrieve todays value\nreal energy0 = chn.MetaData('energy0').ToFloat();\n! Move the values of the array energyCounter30Days one position to the right\nforeach (val, energyCounter30Days.Split(',')) {\nif (loop <= 28 ) {\nlast30Days = last30Days + val + ',';\n} else {\nif (loop == 29) {\nlast30Days = last30Days + val;\n}\n}\nloop = loop + 1;\n}\n! Set the first position of the array energyCounter30Days to todays value.\nlast30Days = energy0.ToString(1) + ',' + last30Days;\n!Store energyCounter30Days as meta data\nchn.MetaData('energyCounter30Days', last30Days);\n! Set the meta data of energy1 (yesterday), energy7 (week) and energy30 (months)\nloop = 0;\nforeach (val, last30Days.Split(',')) {\nval = val.ToFloat();\nif (loop == 0) {chn.MetaData('energy1', val);}\nif (loop <= 6) {\nenergy7 = energy7 + val;\n}\nenergy30 = energy30 + val;\nloop = loop +1;\n}\nchn.MetaData('energy7', energy7);\nchn.MetaData('energy30', energy30);\n! Reset energy0 (today) - a new day begins\nchn.MetaData('energy0', 0.0);\n"; oSDST.DestinationValue(sScript); oPRG.Active (true); dom.RTUpdate (0); WriteLine ("Restore Programm von Program \"" # sPRGName # "\" erfolgreich durchgelaufen"); } else {WriteLine("Kanal gefunden, aber es ist kein Energiezähler-Messwertkanal!\nHss-Typ vom Kanal ist: '"#oChnPM.HssType()#"'");} } else {WriteLine("Kanal mit Namen: '"#NameMesswertkanal#"' nicht gefunden!");}
- D: nun drückt man "Ausführen" und kopiert idealerweise die Scriptausgabe wieder in eine Zwischenablage. Die angezeigte Kanal-ID ist gleich noch hilfreich.
Beispielausgabe:Code: Alles auswählen
Kanal-ID: --> 3171 Metadaten angelegt! Backup/Restore CCU Programme by Black 2023 Backup erstellt vom SDV V5.03.01D-HF1 LCL am 08.12.2023 15:45:45 CCU ProgrammName: "prgSetEnergyValuesAtMidnight_3171" ---------------------------- Restore Programm von Program "prgSetEnergyValuesAtMidnight_3171" erfolgreich durchgelaufen
Durchführung Teil 2:
- E: ihr geht in eure Programm-Übersicht (> Programme und Verknüpfungen > Programme) und klickt in der unteren Leiste auf "Systeminterne Programme einblenden"
- F: ihr geht in der Spalte "Name" auf "Filter" und gebt die ID aus der Scriptausgabe ein, dann sollten nur noch 2 Programme aufgelistet werden.
das "Neue": 'prgSetEnergyValuesAtMidnight_xxxx* und das "Alte": 'prgEnergyCounter_xxxx_SN_DES_AKTORS:KANALNUMMER' - G: ihr bearbeitet das "Alte" Programm und darin das einzige Script. Hier müssen effektiv 2 Codezeilen und eine optionale Kommentarzeile hinzugefügt werden.
- G1: 1. Stelle, aus...
Code: Alles auswählen
integer tmp_oldDevVal = (oldDevVal.ToString().ToFloat() * 1000).ToInteger(); if (overFlowFlag == false) {
- G2: ...wird:
Code: Alles auswählen
integer tmp_oldDevVal = (oldDevVal.ToString().ToFloat() * 1000).ToInteger(); real energy0 = chn.MetaData('energy0').ToFloat(); if (overFlowFlag == false) {
- G3: 2. Stelle, aus...
G4: ...wird:
Code: Alles auswählen
if (tmp_devVal != 0) {oSysVarEnergyCounterOldVal.State(devVal); oSysVarEnergyCounter.State(sysVarVal + diffVal); }
Code: Alles auswählen
if (tmp_devVal != 0) {oSysVarEnergyCounterOldVal.State(devVal); oSysVarEnergyCounter.State(sysVarVal + diffVal); ! Save todays energy consumption chn.MetaData('energy0',energy0 + diffVal); }
- H: nun das geänderte Script mit "OK" speichern, dann noch das Programm mit "OK" speichern
- I: Fertig...
PS:
Ohne den SDV von @Black wären solche "One-Klick-Restore-Scripte" quasi unmöglich.
Danke Micha...