Re: Storen nach x-Sekunden stoppen
Verfasst: 11. Aug 2023 11:50
So, hat mir jetzt keine Ruhe gelassen...
Ich habe herausgefunden, wie man nativ Millisekunden verwenden kann
das macht die Werte beim Debuggen etwas besser lesbar... Außerdem ist die Berechnung nun "ordentlich".
Weiterhin habe ich nun auch folgende Fälle abgefangen:
1. Aufwärts/Abwärts Fahrt, die nicht von Hand gestoppt wird -> openHAB sendet nach der gesetzten Maximalzeit iStoreUp bzw. iStoreDown einen Stop Befehl und setzt den Status auf 0 bzw. 100 %. Auf diese Weise sollte man nun den Store jederzeit "synchronisieren" können, einfach die Endlage anfahren lassen und warten.
2. Stop aus Stop -> Es darf keine Berechnung erfolgen, wird durch gezieltes Leeren der Startzeit erreicht.
Der Code kann eventuell noch verbessert werden, gibt es doch viele Doppelungen. Da es aber in der DSL keine Sprunganweisungen gibt, bliebe nur, Teile des Codes als Lambda abzubilden, was gewöhnlich eher komplexer als einfacher wird.
Ich habe herausgefunden, wie man nativ Millisekunden verwenden kann

Weiterhin habe ich nun auch folgende Fälle abgefangen:
1. Aufwärts/Abwärts Fahrt, die nicht von Hand gestoppt wird -> openHAB sendet nach der gesetzten Maximalzeit iStoreUp bzw. iStoreDown einen Stop Befehl und setzt den Status auf 0 bzw. 100 %. Auf diese Weise sollte man nun den Store jederzeit "synchronisieren" können, einfach die Endlage anfahren lassen und warten.
2. Stop aus Stop -> Es darf keine Berechnung erfolgen, wird durch gezieltes Leeren der Startzeit erreicht.
Code: Alles auswählen
// Globale Variablen und Konstanten immer vor der ersten Rule definieren!
val Integer iStoreUp = 29500 // 29,5 Sekunden aufwärts
val Integer iStoreDown = 27300 // 27,3 Sekunden abwärts
var Timer tStore = null // Timer für Positionsfahrt
var Long lStoreStart = null // Startzeit für UP/DOWN Fahrt
var Boolean bStoreDir = false // Richtung (false = UP)
var Integer iSoll = null // Sollposition
rule "drive store"
when
Item Proxy_Store_Essen received command
then
logDebug("store","Rule gestartet mit Befehl {}",receivedCommand)
var Integer iPos = 0 // Defaultwert 0, falls kein Wert vorhanden
if(Proxy_Store_Essen.state instanceof Number) // falls gültiger Wert
iPos = (Proxy_Store_Essen.state as Number).intValue // setze Ist-Position
logDebug("store","Aktuelle Position {}",iPos)
switch(receivedCommand) { // abhängig vom empfangenen Befehl
case UP : { // Aufwärts:
Store_WohnenEssen.sendCommand(UP) // sende UP
bStoreDir = false // Merke Fahrtrichtung
lStoreStart = now.toInstant.toEpochMilli // Merke Startzeit
logDebug("store","UP erkannt, Starte Messung ({})",lStoreStart)
tStore?.cancel // lösche Timer, falls vorhanden
tStore = createTimer(now.plus(iStoreUp,MILLIS),[ // Starte Timer für Stopp-Befehl
Store_WohnenEssen.sendCommand(STOP) // Stoppe Fahrt
Proxy_Store_Essen.postUpdate(0) // setze neue Position
lStoreStart = null // Startzeitpunkt leeren
])
}
case DOWN : { // Abwärts:
Store_WohnenEssen.sendCommand(DOWN) // sende DOWN
bStoreDir = true // Merke Fahrtrichtung
lStoreStart = now.toInstant.toEpochMilli // Merke Startzeit
logDebug("store","DOWN erkannt, Starte Messung ({})",lStoreStart)
tStore?.cancel // lösche Timer, falls vorhanden
tStore = createTimer(now.plus(iStoreDown,MILLIS),[ // Starte Timer für Stopp-Befehl
Store_WohnenEssen.sendCommand(STOP) // Stoppe Fahrt
Proxy_Store_Essen.postUpdate(100) // setze neue Position
lStoreStart = null // Startzeitpunkt leeren
])
}
case STOP : { // Stopp:
tStore?.cancel // lösche Timer, falls vorhanden
logDebug("store","STOP erkannt, Berechne {} - {}",now.toInstant.toEpochMilli, lStoreStart)
Store_WohnenEssen.sendCommand(STOP) // sende STOP
if(lStoreStart === null) // falls keine Startzeit
return; // Abbruch, da keine BErechnung möglich
val Long lDiff = now.toInstant.toEpochMilli - lStoreStart // Errechne Fahrtzeit
var Integer iPosNew
if(bStoreDir) { // Abhängig von der Fahrtrichtung
iPosNew = iPos + (lDiff/iStoreUp*100).intValue // Bestimme neue Position
} else {
iPosNew = iPos - (lDiff/iStoreDown*100).intValue // Bestimme neue Position
}
logDebug("store","Diff ohne Begrenzung: {} Pos: {} Pos neu: {}", lDiff, iPos, iPosNew)
if(iPosNew < 0) iPosNew = 0 // Bei unterschreiten auf 0 begrenzen
if(iPosNew > 100) iPosNew = 100 // Bei überschreiten auf 100 begrenzen
logDebug("store","Diff: {} Pos: {} Pos neu: {}", lDiff, iPos, iPosNew)
Proxy_Store_Essen.postUpdate(iPosNew) // Schreibe neue Position
lStoreStart = null // Startzeitpunkt leeren
}
default : { // Befehl ist eine Zahl
iSoll = (receivedCommand as Number).intValue // Bestimme Sollposition
logDebug("store","Positionsfahrt erkannt ({} %)", iSoll)
val Integer iMove = (iSoll - iPos).intValue // Bestimme Teilstrecke
var Long iTime = 0 // Initialisiere Variable
logDebug("store","aktuelle Position {} %, Fahrt {}", iPos, iMove)
if(iMove < 0) { // Teilstrecke negativ -> Aufwärts
iTime = -(iStoreUp * iMove / 100).intValue // Errechne Fahrtdauer
logDebug("store","Aufwärts Fahrt {}", iTime)
Store_WohnenEssen.sendCommand(UP) // Starte Fahrt
} else if(iMove > 0) { // Teilstrecke positiv -> Abwärts
iTime = (iStoreDown * iMove / 100).intValue // Errechne Fahrtdauer
logDebug("store","Abwärts Fahrt {}", iTime)
Store_WohnenEssen.sendCommand(DOWN) // Starte Fahrt
}
logDebug("store","Strecke von {} % nach {} % = {} % ({} mSec)", iPos, iSoll, iMove, iTime)
tStore?.cancel // lösche Timer, falls vorhanden
tStore = createTimer(now.plus(iTime,MILLIS),[ // Starte Timer für Stopp-Befehl
Store_WohnenEssen.sendCommand(STOP) // Stoppe Fahrt
Proxy_Store_Essen.postUpdate(iSoll) // setze neue Position
])
}
}
end