Hallo,
ich bin Momentan dabei die JavaSkripte für die Beleuchtung in meinem Heim zu verbessern/überarbeiten.
Ich würde gerne eine Klasse für die Beleuchtung anlegen.
Das Skript sieht folgendermaßen aus:
//room and light names
var roomName = "livingRoom"
var lightName = "light1"
//physical light
var stateID = 'zigbee.0.00158d000484f150.state'/*Switch state*///'zigbee.0.group_1.state'/*Switch state*/
var brighnessID = 'zigbee.0.00158d000484f150.brightness'/*Brightness*///'zigbee.0.group_1.brightness'/*Brightness*/
var colortempID = 'zigbee.0.00158d0001aa6b65.colortemp'/*Color temperature*///'zigbee.0.group_1.colortemp'/*Color temperature*/
var rgbcolorID = ""
//physical button
var buttonClickID = 'shelly.0.SHSW-1#500291F0A6E5#1.Relay0.Input'/*Input / Detach*/
var buttonDoubleClickID = ""
var buttonHoldID = ""
class light {
constructor(roomName, lightName, stateID, brightnessID, colorTempID, RGBcolorID, buttonClickID, buttonDoubleClickID, buttonHoldID) {
this.roomName = roomName
this.lightName = lightName
this.stateID = stateID
this.brighnessID = brightnessID
this.colorTempID = colorTempID
this.RGBcolorID = RGBcolorID
this.buttonClickID = buttonClickID
this.buttonDoubleClickID = buttonDoubleClickID
this.buttonHoldID = buttonHoldID
log(this.stateID) //debug
//set new folder for the light and objects for state, brightness etc. but only if parameter was given to constructor
if(this.stateID != ""){
//create userdata object for virtual light
createState(("0_userdata.0." + roomName + "." + this.lightName + ".state"), false, function() {
//Init physical light
log(this.stateID) //debug
log(stateID) //debug
log("0_userdata.0." + this.roomName + "." + this.lightName + ".state") //debug
log(getState("0_userdata.0.livingRoom.light1.state").val) //debug
log(getState("0_userdata.0." + roomName + "." + this.lightName + ".state").val) //debug
setState(this.stateID, getState("0_userdata.0." + roomName + "." + this.lightName + ".state").val)
});
}
if(this.brighnessID != ""){
createState(("0_userdata.0." + this.roomName + "." + this.lightName + ".brightness"), 255, function() {
setState(this.brighnessID, getState("0_userdata.0." + roomName + this.lightName + ".brightness").val)
});
}
if(this.colorTempID != ""){
createState(("0_userdata.0." + this.roomName + "." + this.lightName + ".colorTemp"), 100, function() {
setState(this.colorTempID, getState("0_userdata.0." + roomName + "." + this.lightName + ".colorTemp").val)
});
}
if(this.RGBcolorID != ""){
createState(("0_userdata.0." + this.roomName + "." + this.lightName + ".RGBcolor"), false, function() {
setState(this.RGBcolorID, getState("0_userdata.0." + roomName + "." + this.lightName + ".RGBcolor").val)
});
}
}
//turn on/off light
setLight(trigger){
if(getState(this.stateID).val){
setState(this.stateID, false);
setState("0_userdata.0." + this.roomName + "." + this.lightName + ".state", false, true)
log("Light turned off by " + trigger)
}
else{
setState(this.stateID, true);
setState("0_userdata.0." + this.roomName + "." + this.lightName + ".state", true, true)
log("Light turned on by " + trigger)
}
}
//Methods for changing brightness, colortemp and rgb
//Trigger shelly button click (momentary switch)
//on({id: this.buttonClickID, val: true}, function (obj) { //not working
//this.setLight("button") //Not working
//}) //not working
//Trigger button double tap and hold
//Trigger from siri over "0_userdata.0.livingRoom.light1.state"
}
const livingRoomLight = new light(roomName, lightName, stateID, brighnessID, colortempID, rgbcolorID, buttonClickID, buttonDoubleClickID, buttonHoldID);
Es wird ein virtuelles Licht durch createState im Konstruktor angelegt. Je nach Übergabe-Parameter werden neben dem Objekt State auch die Objekte Brightness, ColorTemp und RGB angelegt. Zudem wird das “physische Licht” (in dem Fall Zigbee) initialisiert - state false, brightness 255 etc.
Es wurde testhalber eine Methode angelegt um das Licht erstmal ein/auszuschalten. Die Methode funktioniert, wenn der Trigger ausserhalb der Klasse angelegt wird.
Ich würde gerne nun mehrer Trigger in der Klasse anlegen (ab Zeile 71). Im Regelfall gibt es pro Raum einen Lichtschalter (Shelly/Zigbee) und einen virtuellen Schalter mittels Siri (yahka) welcher die durch createState angelegten Objekte in userdata ändert.
Wie kann ich am besten einen Trigger in der Klasse realisieren? Das obere Beispiel funktioniert jedenfalls nicht und der Output sieht folgendermaßen aus:
00:25:50.872 info javascript.0 (2155) Start javascript script.js.living_room.living_room_light_oop
00:25:50.885 info javascript.0 (2155) script.js.living_room.living_room_light_oop: zigbee.0.00158d000484f150.state
00:25:50.886 info javascript.0 (2155) script.js.living_room.living_room_light_oop: registered 0 subscriptions and 0 schedules
00:25:50.962 info javascript.0 (2155) script.js.living_room.living_room_light_oop: undefined
00:25:50.962 info javascript.0 (2155) script.js.living_room.living_room_light_oop: zigbee.0.00158d000484f150.state
00:25:50.963 info javascript.0 (2155) script.js.living_room.living_room_light_oop: 0_userdata.0.undefined.undefined.state
00:25:50.963 info javascript.0 (2155) script.js.living_room.living_room_light_oop: false
00:25:50.964 warn javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:40:21)
00:25:50.964 info javascript.0 (2155) script.js.living_room.living_room_light_oop: null
00:25:50.965 warn javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:41:40)
00:25:50.967 warn javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:41:17)
00:25:50.971 warn javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:46:44)
00:25:50.973 warn javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:46:17)
00:25:50.977 warn javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:51:44)
00:25:50.979 warn javascript.0 (2155) at Object.<anonymous> (script.js.living_room.living_room_light_oop:51:17)
Die Objekte in Userdata werden aber angelegt:
Warum wird this.stateID in Zeile 27 ausgegeben aber in Zeile 33 nicht?
Sollte die Klasse funktionieren, wie kann ich Objekte in neuen (leeren) Skripten anlegen ohne jedes Mal die Klasse kopieren zu müssen?
Mir ist bekannt das man mittels TypeSkript Funktionen auslagern kann.
Muss ich mit der Klasse später auch diesen Weg gehen?
Für heute genug IOBroker - ich geh jetzt ins Bett.
Grüße
Christoph
Der IOBroker wurde vor ein paar Tagen von 3.x.x auf 4.0.24 geupdatet.
Node.js v12.22.6
NPM 6.14.15
Raspberry ist Model 4 mit 4gb RAM