Hallo,
Thomas hat mir letzte Woche ein exzelentes Stück Code "mitgegeben", das ich nun erweitert habe.
Ich habe Rollladenaktoren die nicht in der Lage sind eine Position anzufahren (zB. 80% aka "Offene Schlitze). Das hab ich Thomas erzählt, da hat er mir per Mail eine Rule geschickt die zumindest schon mal "mitloggt" wo der Behang gerade ist, damit das in der Visu dargestellt werden kann.
Programmieren from Scratch kann ich nicht,-). Bin eher so ein Copy&Paste Programmierer.
Ihr findet anbei ein Stück Code mit dem ich jetzt in der Lage bin meine Rolläden auch aus OH mit Prozentwerten auf exakte Positionen anzufahren.
Das Item File:
Das Rule File
Funktoniert soweit. Wichtig ist, dass man die Gesamtfahrzeit entsprechend setzt. Die Rule loggt mit wie lange der Behang in welche Richtung gefahren ist und hat dadurch immer die aktuelle Position.
Meine Fragen für die Profies:
Wer sonst noch Anmerkungen hat, gerne. Wenn Thomas zustimmt kann das auch gerne in die Rule Sammlung mit aufgenommen werden.
Wie findet man die Laufzeit des Behangs möglichst genau raus?
Einfach stoppen und diese Zahl eingeben. Dann einmal aus der oberen Endlage in die 50% Position fahren. Mit einem PosIT auf der Scheibe markieren. Ein weiteres mal aus der unteren Endlage auf die 50% Position fahren. Fährt der Behang von unten höher als das geklebte Posit ist die Fahrzeit zu lang, andernfalls zu kurz. Ein bischen spielen (Zentel Sekunden sind möglich) ujd man hat das recht gut raus.
Viele Grüße
Ralf
Thomas hat mir letzte Woche ein exzelentes Stück Code "mitgegeben", das ich nun erweitert habe.
Ich habe Rollladenaktoren die nicht in der Lage sind eine Position anzufahren (zB. 80% aka "Offene Schlitze). Das hab ich Thomas erzählt, da hat er mir per Mail eine Rule geschickt die zumindest schon mal "mitloggt" wo der Behang gerade ist, damit das in der Visu dargestellt werden kann.
Programmieren from Scratch kann ich nicht,-). Bin eher so ein Copy&Paste Programmierer.
Ihr findet anbei ein Stück Code mit dem ich jetzt in der Lage bin meine Rolläden auch aus OH mit Prozentwerten auf exakte Positionen anzufahren.
Das Item File:
Code:
/* */ Rollershutter Shutter_GF_Arbeiten "Arbeiten" <bblind> (GF_Arbeiten, Shutters, PresenceSimulationGroup) { knx="1/3/2, 1/3/1, 1/3/7" } //Rollershutter Shutter_GF_Test "Test" <bblind> (GF_Arbeiten) Rollershutter Shutter_GF_Test "Arbeiten" <bblind> (GF_Arbeiten, Shutters, PresenceSimulationGroup) { knx="1/3/2, 1/3/1, 1/3/7" } Group Duration Number Blind_SunHeight_Threshold "Sunlight Threshold" <none> Number Blind_GF_Test_Duration "Duration Arbeiten" <none> (Duration) Switch Mode_Calculate_Blinds_Pos "Calculate Positions" <none>
Code:
import org.openhab.core.types.Command import org.openhab.core.library.types.DecimalType import org.openhab.model.script.actions.Timer var long movementStartTime_Test = 0 var long currentPosition_Test = 0 var Command direction_Test = null var Timer timer_Test = null rule "Initialize Blind Calculation BaseValues" when System started then // Laufzeit des Behangs in zentel Sekunden (122 sind 12.2 Sekunden) Blind_GF_Test_Duration.postUpdate(122) if (Blind_SunHeight_Threshold == Uninitialized) { Blind_SunHeight_Threshold.postUpdate(8) } if (Mode_Calculate_Blinds_Pos == Uninitialized) { Blind_SunHeight_Threshold.postUpdate(ON) } if (Shutter_GF_Test == Uninitialized) { Shutter_GF_Test.postUpdate(0) currentPosition_Test = 0 } end rule "Calculate Blind Arbeiten - GF" when Item Shutter_GF_Test received command then // Berechnung ist deaktiviert! if (Mode_Calculate_Blinds_Pos == OFF) { return } logDebug("Blinds.rules", "blind Arbeiten ------- schnipp ------") logDebug("Blinds.rules", "blind Arbeiten - receivedCommand: " + receivedCommand) logDebug("Blinds.rules", "blind Arbeiten - currentPosition: " + currentPosition_Test) logDebug("Blinds.rules", "blind Arbeiten - Shutter_GF_Test: " + (Shutter_GF_Test.state as DecimalType)) var long duration = ((Blind_GF_Test_Duration.state as DecimalType) * 100).longValue var long lastPosition = currentPosition_Test var long durationLeft = 0 // UP oder DOWN oder STOP if (receivedCommand == UP ||receivedCommand == DOWN || receivedCommand == STOP) { logDebug("Blinds.rules", "blind Arbeiten - duration: " + duration) logDebug("Blinds.rules", "blind Arbeiten - directionArbeiten is currently: " + direction_Test) // letzter Command war stop, heisst jetzt gehts auf oder ab if ((direction_Test == null) || (direction_Test == STOP)) { if ((receivedCommand == UP) || (receivedCommand == DOWN)) { movementStartTime_Test = now.millis logDebug("Blinds.rules", "blind Arbeiten - movementStartTime_Test: " + movementStartTime_Test) direction_Test = receivedCommand logDebug("Blinds.rules", "blind Arbeiten - directionArbeiten set to: " + direction_Test) if (receivedCommand == UP) { durationLeft = currentPosition_Test + 2000 } if (receivedCommand == DOWN) { durationLeft = duration - currentPosition_Test + 2000 } if (durationLeft > 0) { timer_Test = createTimer(now.plusMillis(durationLeft.intValue)) [| Shutter_GF_Test.sendCommand(STOP) ] } } logDebug("Blinds.rules", "blind Arbeiten - durationLeft: " + durationLeft) logDebug("Blinds.rules", "blind Arbeiten - currentPosition: " + currentPosition_Test) } else { // Zwei mal der gleiche Command hintereinander if (receivedCommand == direction_Test) { // Nix machen logDebug("Blinds.rules", "blind Arbeiten - Received Command twice") return } if (receivedCommand == STOP) { logDebug("Blinds.rules", "blind Arbeiten - direction Arbeiten was: " + direction_Test) // Stop gedrückt if (timer_Test != null) { timer_Test.cancel timer_Test = null } var movementStopTime = now.millis logDebug("Blinds.rules", "blind Arbeiten - movementStopTime_Test: " + movementStopTime) var movementRunTime = movementStopTime - movementStartTime_Test logDebug("Blinds.rules", "blind Arbeiten - movementRunTime: " + movementRunTime) var long newPosition = 0 if (direction_Test == UP) { newPosition = (lastPosition - movementRunTime) } if (direction_Test == DOWN) { newPosition = (lastPosition + movementRunTime) } logDebug("Blinds.rules", "blind Arbeiten - newPosition: " + newPosition) direction_Test = receivedCommand logDebug("Blinds.rules", "blind Arbeiten - directionArbeiten set to: " + direction_Test) if (newPosition < 0) { newPosition = 0 } if (newPosition > duration) { newPosition = duration.longValue } logDebug("Blinds.rules", "blind Arbeiten - newPosition: " + newPosition) currentPosition_Test = newPosition logDebug("Blinds.rules", "blind Arbeiten - currentPosition_Test: " + currentPosition_Test) var positionInPercent = (newPosition * 100 / duration) logDebug("Blinds.rules", "blind Arbeiten - newPosition in percent: " + positionInPercent) Shutter_GF_Test.postUpdate(positionInPercent.intValue) } } } else { // Direkte Position anfahren durationLeft = (receivedCommand as DecimalType).longValue * duration.longValue / 100 - currentPosition_Test logDebug("Blinds.rules", "blind Arbeiten - durationLeft: " + durationLeft) if (durationLeft > 0) { durationLeft = durationLeft - 10 Shutter_GF_Test.sendCommand(DOWN) timer_Test = createTimer(now.plusMillis(durationLeft.intValue)) [| Shutter_GF_Test.sendCommand(STOP) ] } else if (durationLeft < 0) { durationLeft = - durationLeft - 10 Shutter_GF_Test.sendCommand(UP) timer_Test = createTimer(now.plusMillis(durationLeft.intValue)) [| Shutter_GF_Test.sendCommand(STOP) ] } } end
Meine Fragen für die Profies:
- Wie verhindere ich, das OH beim setzen des Rollershutter Items auf DOWN die Position automatsich auf 100% setzt (dito UP = 0%). Würde das gerne sogar "mitführen", dass man während der Fahrt schon die Aktualisierung in der Visu sieht.
- Wie bekomme ich die Behangposition (% Wert) über Persistence so eingesteuert, dass sich OH die Position des Behangs merkt beim Restart. Aktuell meint OH der Behang ist auf 0% nach einem Restart
Wer sonst noch Anmerkungen hat, gerne. Wenn Thomas zustimmt kann das auch gerne in die Rule Sammlung mit aufgenommen werden.
Wie findet man die Laufzeit des Behangs möglichst genau raus?
Einfach stoppen und diese Zahl eingeben. Dann einmal aus der oberen Endlage in die 50% Position fahren. Mit einem PosIT auf der Scheibe markieren. Ein weiteres mal aus der unteren Endlage auf die 50% Position fahren. Fährt der Behang von unten höher als das geklebte Posit ist die Fahrzeit zu lang, andernfalls zu kurz. Ein bischen spielen (Zentel Sekunden sind möglich) ujd man hat das recht gut raus.
Viele Grüße
Ralf
Kommentar