Morgens von langsam aufdimmenden Licht geweckt zu werden, unterstützt deinen Prozess in den Tag zu starten. Mit einer Smart-Blub wie Phillips Hue lässt sich das leicht bewerkstelligen. Ich steuere dieses Ereignis darüber hinaus mit meinem Google Kalender um sich verändernde Verhältnisse einfach abzubilden.
Kalender-Item
Den Kalender richte ich mittels des OpenHAB ical-Moduls ein. Die zugehörigen Items sehen so aus:
Group:Switch:COUNT(ON) igCalWaking "Weckprofil" (sgBedroom)["WebService"]
Switch KalenderWecken_CurrentEventPresence "Current Event Presence" (igCalWaking) { channel="icalendar:calendar:Wecken:current_presence" }
String KalenderWecken_CurrentEventTitle "Current Event Title" (igCalWaking) { channel="icalendar:calendar:Wecken:current_title" }
DateTime KalenderWecken_CurrentEventStart "Current Event Start" (igCalWaking) { channel="icalendar:calendar:Wecken:current_start" }
DateTime KalenderWecken_CurrentEventEnd "Current Event End" (igCalWaking) { channel="icalendar:calendar:Wecken:current_end" }
Smart-Bulb-Item
In meinem Fall verwende ich Phillips Hue zusammen mit zigbee2mqtt.
// Schlafzimmer
Group igSchlafzimmerLight "Schlafzimmer" (sgBedroom)["Lightbulb", "Group"]
Color SchlafzimmerRoom_Farbe "Farbe" <ColorLight> (igSchlafzimmerLight,sgBedroom,tgLSchange)["Control", "Light"] { autoupdate="false", channel="mqtt:topic:myMosquitto:HueBulbBedRoom:color", alexa="Color" }
Dimmer SchlafzimmerRoom_Farbtemperatur "Farbtemperatur" <ColorLight> (igSchlafzimmerLight,tgLSinterrupt,sgBedroom)["Control", "ColorTemperature"] { autoupdate="false", channel="mqtt:topic:myMosquitto:HueBulbBedRoom:color_temperature", alexa="ColorTemperature" }
Dimmer SchlafzimmerRoom_Helligkeit "Licht" <DimmableLight> (igSchlafzimmerLight,tgLSinterrupt,sgBedroom)["Control", "Brightness"] { autoupdate="false", channel="mqtt:topic:myMosquitto:HueBulbBedRoom:brightness", alexa="Brightness,PowerState" }
String SchlafzimmerRoom_Lightshow "Lightshow" (igSchlafzimmerLight,tgLightshow,sgBedroom)["Control", "DynamicScene"] { alexa="Mode" [capabilityNames="@Setting.Mode",supportedModes="Normal,Kerzenlicht,Polarlicht,Farbwechsel,Zufallsfarben,Gewitter,TV-Simulation"] }
Dimmer SchlafzimmerRoom_LightshowSpeed "Geschwindigkeit" (igSchlafzimmerLight,sgBedroom)["Control", "DynamicSpeed"] { alexa="RangeValue" [capabilityNames="Geschwindigkeit,Speed", supportedRange="0:100:10", presets="10=@Value.Low:@Value.Minimum,50=@Value.Medium:Normal,100=@Value.High:@Value.Maximum"] }
String SchlafzimmerRoom_Interface "Interface" (igSchlafzimmerLight)["Control", "Interface"] { channel="mqtt:topic:myMosquitto:HueBulbBedRoom:interface" }
Sonnenaufgang-Rule
Die Folgende Regel vollführt den Trick. Dabei greife ich auf eine mathematische Lösung zurück. Das Licht wird über einen bestimmten Zeitraum bis zu einem maximalen Wert aufgedimmt. Alle Schritte dazwischen werden berechnet. Wenn der aktuelle Status zu weit von dem durch dieses System berechneten Status abweicht, wird nicht weiter damit fortgefahren. Dadurch kann der Vorgang manuell durch Ein- oder Ausschalten abgebrochen werden.
/etc/openhab/rules/bedroom-wakeup-light.rules
val int stepTime = 2 //minutes
val int sunriseTime = 30 //minutes
val int maxValue = 60 //%
rule "Wochenprofile ein math"
when
Time cron "0 0/2 * * * ?"
then {
if(KalenderWecken_CurrentEventStart.state != UNDEF){
val eventStarted = (KalenderWecken_CurrentEventStart.state as DateTimeType).getZonedDateTime()
var double diffSec = (now.toInstant().toEpochMilli() - eventStarted.toInstant().toEpochMilli())/1000
var double diffMin = diffSec/60
var double stepPerMin = maxValue/sunriseTime
//Soll-Wert zu dem Zeitpunk
var double setpoint = diffMin * stepPerMin
if(setpoint > maxValue){
setpoint = maxValue
}
//Untergrenze des Sollwertes
var double setpointLow = (diffMin - stepTime) * stepPerMin
if(setpointLow < 0){
setpointLow = 0
}
var e = SchlafzimmerBg_Helligkeit
var actualValue = (e.state as DecimalType).intValue
if(
actualValue >= setpointLow &&
actualValue < setpoint
){
e.sendCommand(setpoint)
}
}
}
end
rule "Wochenprofile aus"
when
Item KalenderWecken_CurrentEventPresence changed to OFF
then {
SchlafzimmerRoom_Helligkeit.sendCommand(0)
}
end/**
* Weekly Profiles / Wake-up Light Automation
*/
const { rules, triggers, items, time } = require("openhab");
// Configuration
const STEP_TIME = 2; // Minutes (Tolerance window for manual intervention)
const SUNRISE_TIME = 30; // Minutes (Total duration of the fade-in process)
const MAX_VALUE = 60; // % (Maximum brightness target)
rules.JSRule({
name: "Weekly Profile Sunrise Math",
description: "Calculates brightness based on calendar event (sunrise simulation)",
triggers: [triggers.GenericCronTrigger("0 0/2 * * * ?")], // Every 2 minutes
execute: (event) => {
const startItem = items.getItem("KalenderWecken_CurrentEventStart");
// Check if a valid start time is set
if (startItem.state === "NULL" || startItem.state === "UNDEF") {
return;
}
// Time Calculation
// time.toZDT() automatically uses the system timezone and parses the item state string
const now = time.toZDT();
const eventStarted = time.toZDT(startItem.state);
// Calculate time difference
// Using epoch milliseconds to determine the elapsed time since the event started
const diffMillis = now.toInstant().toEpochMilli() - eventStarted.toInstant().toEpochMilli();
const diffSec = diffMillis / 1000.0;
const diffMin = diffSec / 60.0;
// Calculate the slope (dimming rate)
const stepPerMin = MAX_VALUE / SUNRISE_TIME;
// Calculate the target setpoint
let setpoint = diffMin * stepPerMin;
if (setpoint > MAX_VALUE) {
setpoint = MAX_VALUE;
}
// Calculate the lower bound (tolerance threshold)
let setpointLow = (diffMin - STEP_TIME) * stepPerMin;
if (setpointLow < 0) {
setpointLow = 0;
}
// Get current light status
const lightItem = items.getItem("SchlafzimmerRoom_Helligkeit");
let actualValue = parseFloat(lightItem.state);
// Default to 0 if the light is off or the state is unknown
if (isNaN(actualValue)) {
actualValue = 0;
}
// Logic Check
// Only send a command if the current brightness is below the calculated setpoint
// but still above the lower threshold. This prevents the automation from
// dimming the light back down if it was manually set to a higher value (e.g., 100%).
if (actualValue >= setpointLow && actualValue < setpoint) {
// Use Math.round for clean integer values when sending the command
lightItem.sendCommand(Math.round(setpoint).toString());
}
}
});
rules.JSRule({
name: "Weekly Profile Off",
description: "Turns off the light when the calendar event ends",
triggers: [triggers.ItemStateChangeTrigger("KalenderWecken_CurrentEventPresence", null, "OFF")],
execute: (event) => {
items.getItem("SchlafzimmerRoom_Helligkeit").sendCommand("0");
}
});