Zurück   KNX-User-Forum > Supportforen > openHAB
knx-user-forum - International KNX Award Winner 2010


Links
Kalender
Spende

Antwort
 
Themen-Optionen Ansicht
  #11  
Alt 11.01.2013, 15:01
Benutzer
 
Registriert seit: 14.09.2012
Ort: Oberderdingen
Beiträge: 140
mepi0011 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat von teichsta Beitrag anzeigen
Hi,



zur Info: wir haben soeben Calimero geforked (siehe: https://github.com/openhab/calimero) und unseren Code eingechecked. In den nächsten Tagen wird es auch einen DPTXlator für 14.* geben. Dann dürfte 13.* auch nicht mehr weit hin sein ...

Pull-Requests sind willkommen :-)

Gruß,

Thomas E.-E.
Das sind mal wirklich gute Nachrichten! vielen Dank an alle Beteiligten des Fork.
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #12  
Alt 11.01.2013, 20:05
Benutzer
 
Registriert seit: 14.09.2012
Ort: Oberderdingen
Beiträge: 140
mepi0011 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat von Jan0815 Beitrag anzeigen
Kannst du mir auch sagen, wie ich dann die Auswertung machen kann, bzw. wie ich mir das anzeigen lasse?
Was ist, wenn ich den Rechner, auf dem OpenHAB läuft einmal neu starten muss, oder er wegen eines Stromausfalls einmal aus ist, läuft dann der Zähler nicht wieder bei 0 los?
Wenn ja, gibt es eine Möglichkeit, den aktuellen Stand der Variablen irgendwie weg zu schreiben und beim Neustart von OpenHAB als Startwert auszulesen?

Gruß Jan
Hallo Jan,

den Betriebsstundenzähler habe ich nun etwas weiter entwickelt und deine Anmerkungen von oben implementiert (mit etwas Hilfe von Thomas E.-E. -- Danke!). Dabei bin ich wie folgt vorgeganen:

Folgendes Item habe ich angelegt:

Code:
Group Test                                         "Timer Test"
Switch Licht_UG_Esszimmer_Decke                 "Licht Esszimmer Decke"                (Test)
Switch Licht_UG_Esszimmer_Tisch                 "Licht Esszimmer Tisch"                (Test)

Number Betriebsstundenzaehler_Esszimmer_Decke "Betriebsstundenzähler Decke [%d]"    (Test)  // kann aus der Gruppe Test entfallen bzw. ausgeblendet werden
Number Betriebsstundenzaehler_Esszimmer_Tisch "Betriebsstundenzähler Tisch [%d]"    (Test)   // kann aus der Gruppe Test entfallen bzw. ausgeblendet werden

String Betriebsstunden_Esszimmer_Decke                    "Betriebsstungen Licht Decke [%s]"            (Test)
String Betriebsstunden_Esszimmer_Tisch                    "Betriebsstungen Licht Tisch [%s]"            (Test)
Die benötigten Regeln sehen wie folgt aus:

Code:
import org.openhab.core.library.types.*

rule "Initialisiere Betriebsstundenzaehler"
when
    System started
then
    // sollte noch kein Default-Wert gesetzt sein, holen wir das hier einmalig 
    // nach ... danach sollte der Wert aus db4o kommen!
    if (Betriebsstundenzaehler_Esszimmer_Decke.state == Uninitialized) {
        Betriebsstundenzaehler_Esszimmer_Decke.postUpdate(0)
    }
    if (Betriebsstundenzaehler_Esszimmer_Tisch.state == Uninitialized) {
        Betriebsstundenzaehler_Esszimmer_Tisch.postUpdate(0)
    }
end
      
rule Betriebsstundenzaehler
when
  Time cron "0/1 * * * * ?" // Abfrage alle Sekunde oder "* 0/1 * * * ?" für Minuten 
then
  if (Licht_UG_Esszimmer_Decke.state == ON) {
      //var int Zaehler_Esszimmer2 = (Betriebsstundenzaehler_esszimmer.state as DecimalType).intValue
      var Number Zaehler = Betriebsstundenzaehler_Esszimmer_Decke.state as DecimalType
        Zaehler = Zaehler + 1 
      Betriebsstundenzaehler_Esszimmer_Decke.postUpdate(Zaehler)
  }
  if (Licht_UG_Esszimmer_Tisch.state == ON) {
      //var int Zaehler_Esszimmer2 = (Betriebsstundenzaehler_esszimmer.state as DecimalType).intValue
      var Number Zaehler = Betriebsstundenzaehler_Esszimmer_Tisch.state as DecimalType
        Zaehler = Zaehler + 1 
      Betriebsstundenzaehler_Esszimmer_Tisch.postUpdate(Zaehler)
  } 
end

rule Aktualisiere_Betriebsstunden_Anzeige
when
    Time cron "0 * * * * ?"  // Update nach einer Minute
then
    var String h
    var Number H
    var String m
    var Number M
    var String s
    var Number S
    /*berechne Stunden */
    S = Betriebsstundenzaehler_Esszimmer_Decke.state as DecimalType
    H = (S/3600).intValue
    h = H.toString
    S = S-H*3600        
    /* berechne Minuten */
    M = (S/60).intValue
    if (M <=9) m = "0" + M.toString
    else m = M.toString
    
    /* berechne sehunden */
    S = S-M*60
    if (S <=9) s = "0" + S.toString
    else s = S.toString  
    Betriebsstunden_Esszimmer_Decke.postUpdate(h+":"+m+":"+s)

    /* Tisch */
    /*berechne Stunden */
    S = Betriebsstundenzaehler_Esszimmer_Tisch.state as DecimalType
    H = (S/3600).intValue
    h = H.toString
    S = S-H*3600       
    /* berechne Minuten */
    M = (S/60).intValue
    if (M <=9) m = "0" + M.toString
    else m = M.toString
    
    /* berechne sehunden */
    S = S-M*60
    if (S <=9) s = "0" + S.toString
    else s = S.toString  
    Betriebsstunden_Esszimmer_Tisch.postUpdate(h+":"+m+":"+s)
end
Nun noch das persistence.db4o Binding in das Verzeichnis addons kopieren und die Datei db4o.persist im Verzeichnis configurations/persistence mit folgendem Inhalt anlegen, dadurch werden die Daten dauerhaft gespeichern.

Code:
// persistence strategies have a name and a definition and are referred to in the "Items" section
Strategies {
        everyHour : "0 0 * * * ?"
        everyDay  : "0 0 0 * * ?"

        // if no strategy is specified for an item entry below, the default list will be used
        default = everyChange
}

/* 
 * Each line in this section defines for which item(s) which strategy(ies) should be applied.
 * You can list single items, use "*" for all items or "groupitem*" for all members of a group
 * item (excl. the group item itself).
 */
Items {
        // persist all items once a day and on every change and restore them from the db at startup
        Betriebsstundenzaehler_Esszimmer_Decke : strategy = everyHour, everyDay, restoreOnStartup
        Betriebsstundenzaehler_Esszimmer_Tisch : strategy = everyHour, everyDay, restoreOnStartup
        
        // additionally, persist all temperature and weather values every hour
}
Bei einem Neustart werden die Daten wieder hergestellt, mit der Einschränkung dass bei einem Stromausfall evtl. die letzte Stunde fehlen könnte.

Sollte etwas unklar sein, dann einfach melden.

Gruß
mepi

PS: Die Regel zum umwandeln der Zahl in einen String geht bestimmt auch einfacher. Anregungen hierzu sind gerne willkommen.
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #13  
Alt 14.01.2013, 10:09
Benutzer
 
Registriert seit: 22.08.2012
Ort: Heppenheim
Beiträge: 58
Jan0815 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Hi Mepi,

danke für den Code.
Ich hab gestern auch noch etwas herum experimentiert und wollte gerade fragen, wie ich die Daten in ein Item schreibe, damit ich es mir anzeigen lassen kann, als ich gesehen habe, dass du schon geschrieben hast.
Da ich programmiertechnisch nicht so ganz auf der Höhe bin, bin ich für jeden Codeschnipsel dankbar.
Ich probiere es heute Abend gleich aus.

Gruß Jan
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #14  
Alt 15.01.2013, 08:57
Benutzer
 
Registriert seit: 22.08.2012
Ort: Heppenheim
Beiträge: 58
Jan0815 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Hi Mepi,

ich hab es gestern ausprobiert und zum Laufen bekommen. Es funktioniert!
Allerdings habe ich das Problem, dass nach einem Neustart ständig der KNX-Link verloren geht. Nach langem hin und her hat sich dann herausgestellt, dass das Problem behoben ist, wenn ich die db4o.persist wieder lösche und anschließend neu starte. Dann sind aber verständlicherweise die gespeicherten Werte wieder verloren.
Hat jemand eine Ahnung, wieso die KNX-Verbindung im Zusammenspiel mit der db4o.persist solche Probleme macht?

Gruß Jan
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #15  
Alt 15.01.2013, 20:12
Erfahrener Benutzer
 
Registriert seit: 02.06.2008
Ort: Krefeld
Beiträge: 958
teichsta ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Am besten startest Du mit start_debug.sh/bat und hängst uns mal die openhab.log an?
__________________
Visualisierung, Rule/Logic-Engine, Integrationsplattform mit openhab (Supportforum)
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #16  
Alt 16.01.2013, 07:58
Benutzerbild von RaK
RaK RaK ist offline
Benutzer
 
Registriert seit: 02.06.2007
Beiträge: 418
RaK wird schon bald berühmt werden
Standard

Warum macht ihr das mit einer Regel die alle Sekunde aufgerufen wird? Hat das einen Vorteil?

Ne Regel die beim Einschalten den Zeitstempel nimmt und beim Ausschalten wieder. Die Differenz ist die Zeit die die Lampe eingeschaltet war. Die Differenz wird beim Ausschalten in einen Summenzähler addiert.

Spart Last auf OH und spart damit Strom ,-).
__________________
VisuIcons für Homeautomation
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #17  
Alt 16.01.2013, 09:18
Benutzer
 
Registriert seit: 14.09.2012
Ort: Oberderdingen
Beiträge: 140
mepi0011 ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat von RaK Beitrag anzeigen
Warum macht ihr das mit einer Regel die alle Sekunde aufgerufen wird? Hat das einen Vorteil?

Ne Regel die beim Einschalten den Zeitstempel nimmt und beim Ausschalten wieder. Die Differenz ist die Zeit die die Lampe eingeschaltet war. Die Differenz wird beim Ausschalten in einen Summenzähler addiert.

Spart Last auf OH und spart damit Strom ,-).
Hallo RaK,

keine Frage deine Einwände sind alle berechtigt. Die Regel muss nicht zwingend alle Sekunde aufgerufen werden, es würde auch genüge diese jede Minute aufzurufen. --> Reduzierung der Systemlast.

Jan0815 und Ich sind keine Programmierer. Ich habe den für mich "einfachsten Weg" gewählt., mit einfachen Zahlen und String kann ich umgehen.

Vorteil meiner Lösung ist, dass ich Sekunden/Minutengenau den aktuellen Status habe wenn z.B. Ein Lampe mehrere Stunden an ist. Bei deiner Lösung wird erst beim Ausschalten aktualisiert.

Bitte nicht Falsch verstehen, ich möchte dein Lösungsvorschlag nicht schlecht machen, im Gegenteil ich finde ihn interessant da ich auf einem Raspberry arbeite und Ressourcen schonend arbeiten muss.

Kannst du uns zeigen wie das mit den zeitstempeln funktioniert?

Jede Hilfe und Code-Beispiele sind jederzeit Herzlich willkommen!

Danke!

Gruß
mepi
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #18  
Alt 20.01.2013, 00:23
Erfahrener Benutzer
 
Registriert seit: 28.10.2009
Ort: NRW
Beiträge: 536
Jockel ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Ne Regel die beim Einschalten den Zeitstempel nimmt und beim Ausschalten wieder. Die Differenz ist die Zeit die die Lampe eingeschaltet war. Die Differenz wird beim Ausschalten in einen Summenzähler addiert.
Das hab ich jetzt mal in einer ersten Version umgesetzt, ist aber ganz sicher noch deutlich verbesserungswürdig. Hier mal exemplarisch für eine Steckdose:

Items:
Code:
Number Steckdosen_Wohnen_Heizung_links_Zaehler "Steckdose Heizung li. [%d]"    (gOperatingHours)  
String Steckdosen_Wohnen_Heizung_links_Betriebsstunden "Steckdose Heizung li. [%s]"    (gOperatingHoursFormated)
Die beiden Gruppen nutze ich vor allem um mir die Einträge in der db4o.persist zu vereinfachen.

Dazu eine Regel, die beim Ausschalten die Zeitdifferenz zum Zähler addiert:

Code:
import org.openhab.core.library.types.*
import java.util.Calendar
import java.util.Date
import java.util.TimeZone

var Calendar Steckdosen_Wohnen_Heizung_links_OnTime

rule "Aktualisiere Betriebsstunden Steckdosen_Wohnen_Heizung_links_Schalten"
when
    Item Steckdosen_Wohnen_Heizung_links_Schalten changed
then
    if (Steckdosen_Wohnen_Heizung_links_Schalten.state == ON) {
        Steckdosen_Wohnen_Heizung_links_OnTime = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))  
    } else if (Steckdosen_Wohnen_Heizung_links_Schalten.state == OFF) {
        var Calendar now   = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin")) 
        var Number Diff    =  (now.getTimeInMillis() - Steckdosen_Wohnen_Heizung_links_OnTime.getTimeInMillis()) / 1000
        var Number Zaehler = (Steckdosen_Wohnen_Heizung_links_Zaehler.state as DecimalType) + Diff
        Steckdosen_Wohnen_Heizung_links_Zaehler.postUpdate(Zaehler)
        
        var Number h = (Zaehler/3600).intValue
        var Number m = ((Zaehler-h*3600)/60).intValue
        var Number s = ((Zaehler-h*3600 - m*60)).intValue
        var String TimeString = h + ":" 
        if (m < 10) {TimeString = TimeString + "0" + m.toString + ":"} else {TimeString = TimeString + m.toString + ":"}
        if (s < 10) {TimeString = TimeString + "0" + s.toString      } else {TimeString = TimeString + s.toString      } 
       	
        Steckdosen_Wohnen_Heizung_links_Betriebsstunden.postUpdate(TimeString)
		
        logInfo("operating hours rules", "Updated operating counter for Steckdosen_Wohnen_Heizung_links_Schalten: " + Zaehler)
    }
end

Initialisierung beim Start:
Code:
rule "Initialisiere Betriebsstundenzaehler"
when
    System started
then
    Steckdosen_Wohnen_Heizung_links_OnTime = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))   
    
    if (Steckdosen_Wohnen_Heizung_links_Zaehler.state == Uninitialized) {
        Steckdosen_Wohnen_Heizung_links_Zaehler.postUpdate(0)
    }
end
Zusätzlich kann man bei lang laufenden Verbrauchern den Zähler auch periodisch, dann aber mit langem Intervall aktualisieren:

Code:
rule Betriebsstundenzaehler
when
  Time cron "* 0/30 * * * ?" // Abfrage alle 30min 
then
    var Number Diff
    var Number Zaehler
    var Calendar now   = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin")) 

    if (Steckdosen_Wohnen_Heizung_links_Schalten.state == ON) {
        Diff    =  (now.getTimeInMillis() - Steckdosen_Wohnen_Heizung_links_OnTime.getTimeInMillis()) / 1000
        Zaehler = (Steckdosen_Wohnen_Heizung_links_Zaehler.state as DecimalType) + Diff
        Steckdosen_Wohnen_Heizung_links_Zaehler.postUpdate(Zaehler)
        Steckdosen_Wohnen_Heizung_links_OnTime = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))  
        
        var Number h = (Zaehler/3600).intValue
        var Number m = ((Zaehler-h*3600)/60).intValue
        var Number s = ((Zaehler-h*3600 - m*60)).intValue
        var String TimeString = h + ":" 
        if (m < 10) {TimeString = TimeString + "0" + m.toString + ":"} else {TimeString = TimeString + m.toString + ":"}
        if (s < 10) {TimeString = TimeString + "0" + s.toString      } else {TimeString = TimeString + s.toString      } 
       	
       Steckdosen_Wohnen_Heizung_links_Betriebsstunden.postUpdate(TimeString)
    }
end
Ich bin noch beim Testen, Fehler sind also durchaus noch wahrscheinlich.

Natürlich ist das eine Sache bei der man sich, gerade bei vielen Verbrauchern, Funktionen in den Regeln wünscht...

Was mir überhaupt nicht gefällt ist die umständliche Formatierung des Strings zur Anzeige, eigentlich sogar schon nicht die Tatsache zwei Items zu benötigen. Wenn ich es richtig sehe, kennt das String Item aber keinen Format Operator mit dem man zumindest das Zusammensetzen des Strings etwas schöner umsetzen könnte. Vielleicht habe ich da aber auch andere Möglichkeiten übersehen.

Ein weiterer Schwachpunkt ist, dass der String erst beim Ausschalten des Verbrauchers (oder ggf. periodisch) aktualisiert wird. Deshalb hab ich in mit in die Persistence-Datenbank aufgenommen, damit er nach dem Start korrekt angezeigt wird. Alternativ könnte man ihn auch grundsätzlich peridisch aktualisieren oder Regeln erstellen, die auf das Ändern des Zählers triggern. Das sind mir dann aber doch deutlich zu viele Regeln. Bei meiner aktuellen Version mit 41 Verbrauchern reagiert der Designer beim Bearbeiten der Regel-Datei schon deutlich behäbig.

Als Kompromiss wäre auch eine Regel denkbar, die auf das Ändern aller Zähler triggert und dann jedes mal alle Strings aktualisiert. So etwas ist natürlich beim Start blöd.

Vielleicht habt ihr da ja noch Vorschläge?

P.S.: Warum der Browser das End im letzten Codeblock schluckt ist mir nicht klar, in meinem Posting ist es enthalten...

Geändert von Jockel (20.01.2013 um 00:25 Uhr)
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #19  
Alt 21.01.2013, 00:11
Erfahrener Benutzer
 
Registriert seit: 28.10.2009
Ort: NRW
Beiträge: 536
Jockel ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Noch ein Hinweis: Die Initalisierung der Variablen zum Speichern der letzten Startzeit kommt anstatt in die Startup-Regel besser direkt hinter die Variablendeklaration also

Code:
var Steckdosen_Wohnen_Heizung_links_OnTime = java::util::Calendar::getInstance(TimeZone::getTimeZone("Europe/Berlin"))
Mit der ersten Variante ergibt sich das Problem, dass die Variable beim erneuten Einlesen der Regeldatei (z.B. nach dem Ändern) neu deklariert wird. Damit ist sie dann aber undefiniert, da die Startup-Regel nur beim Start ausgeführt wird. Das gibt dann beim Ersten Aufruf der periodischen Überwachung bei schon eingeschaltetem Verbraucher eine Null-Pointer Exception.

Gibt es eigentlich auch einen Trigger der beim erneuten Einlesen wirksam wird?
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
  #20  
Alt 23.01.2013, 16:30
Erfahrener Benutzer
 
Registriert seit: 02.06.2008
Ort: Krefeld
Beiträge: 958
teichsta ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat von Jockel Beitrag anzeigen
Gibt es eigentlich auch einen Trigger der beim erneuten Einlesen wirksam wird?
hmm ... bin jetzt nicht ganz sicher, aber eigentlich werden beim Einlesen die Rules mit dem Trigger "System started" ausgeführt.

Hast Du das schon probiert?
__________________
Visualisierung, Rule/Logic-Engine, Integrationsplattform mit openhab (Supportforum)
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Antwort

Stichworte
auswertung, stromverbrauch, verbrauch aufzeichnen

Themen-Optionen
Ansicht

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[DALI] Vorschaltgerät + Lampen Empfehlung gesucht walter12 KNX EIB Forum 0 04.04.2012 12:05
KORREKTE Raffstore Laufzeit ermitteln? JMA KNX EIB Forum 4 02.09.2010 08:26


Alle Zeitangaben in WEZ +2. Es ist jetzt 07:40 Uhr.



SEO by vBSEO