export {};
const DEBUG = false;
const cMinLux = 1800;
const luxminFront = 60;
const luxminBehind = 80;
const luxminComputer = 20;
let front = false;
let behind = false;
let behindComputer = false;
const miredDiff = 180;
const dimValueOptions: dimValueOptionsType = {
    begin: '21:00',
    end: '23:00',
    reset: '6:00',
    sunset: 340
    // default values here
}
// für hinteren Bereich
const cShutterPosForLight = 60;
let hyperion_on = getState('sonoff.0.Gosund Steckdose 8.POWER').val;
const path = '0_userdata.0.scene'
const cCurrentLuxState = 'alias.0.zuhause.og.Abstellraum.Lux-Tasmota.lux';
const mySwitch = 'zigbee2mqtt.0.0x001788010635d03f.';
const mySwitch2 = 'zigbee2mqtt.0.0x0017880104f33a08.';
var mySwitchTimeout:any = null;
const axios = require('axios');
//Objekte;
const dimmer:{[key: number]: {value: number, timeout: any}} = {};
let autoModeBright = existsState(`${path}.wohnzimmer.autoModeBright`) ? getState(`${path}.wohnzimmer.autoModeBright`).val : false;
let autoModeOffTimeout = autoModeBright ? 15000 : 3000
// homematic 6 fach schalter
// Wandlampe Wohnzimmer
const cShutterPos = 'homepilot20.0.Actuator.2-27601565.Position'
let shutterPos = getState(cShutterPos).val;
on({id: cShutterPos, change: 'ne'}, (obj) => {
    shutterPos = obj.state.val
})
on({ id: 'hm-rpc.1.000B5D89B01C44.1.PRESS_SHORT', change: 'any', val: true }, function (obj) {
   flipState(`${path}.wohnzimmer.autoModeBright`);
})
on({ id: 'hm-rpc.1.000B5D89B01C44.3.PRESS_SHORT', change: 'any', val: true }, function (obj) {
   flipState('sonoff.0.NOUS 03.POWER')
})
on({ id: 'hm-rpc.1.000B5D89B01C44.6.PRESS_SHORT', change: 'any', val: true }, function (obj) {
    if (!mySwitchTimeout) {
        mySwitchTimeout = setTimeout(function () {
            autoScene(0);
            mySwitchTimeout = null;
        }, 300);
    }
})
on({ id: 'hm-rpc.1.000B5D89B01C44.2.PRESS_SHORT', change: 'any', val: true }, function (obj) {
    flipState('shelly.0.SHSW-1#E8DB84D7B242#1.Relay1.Switch')
})
on({ id: 'hm-rpc.1.000B5D89B01C44.4.PRESS_SHORT', change: 'any', val: true }, function (obj) {
    flipState('sonoff.0.NOUS 05.POWER')
})
on({ id: 'hm-rpc.1.000B5D89B01C44.5.PRESS_LONG_START', change: 'any', val: true }, function (obj) {
    let lights = $('state(functions=beleuchtung)');
    if (lights) {
        lights.each(async (obj) => {
            await sleep(100)
            const obj2 = getObject(obj, 'rooms');
            let rooms = obj2.enumIds
            if (rooms === undefined) return;
            rooms.forEach(async (room) => {
                await sleep(20)
                // workaround manche Geräte enthalten Räume die ich nicht entfernen kann.
                var enumObj = getObject(room);
                if (enumObj.common.members.findIndex((a) => { return obj.includes(a) }) == -1) return;
                const roomName = enumObj.common.name as iobJS.StringOrTranslated;
                let r = typeof roomName === 'string' ? roomName : roomName.de;
                if (r != 'Wohnzimmer') setState(obj, false);
            });
        });
    }
})
on({ id: 'hm-rpc.1.000B5D89B01C44.5.PRESS_SHORT', change: 'any', val: true }, function (obj) {
    setState('0_userdata.0.currentSceneWZ', -1);;
})
let essbereichSchalter = getState('shelly.0.SHSW-25#E8DB8480264D#1.Relay0.Input').val
on({ id: 'shelly.0.SHSW-25#E8DB8480264D#1.Relay0.Input', change: 'ne' }, function (obj) {
   essbereichSchalter = obj.state.val;
   setLights();
})
let schreibtischbereichSchalter = getState('shelly.0.SHSW-25#E8DB8480264D#1.Relay1.Input').val
on({ id: 'shelly.0.SHSW-25#E8DB8480264D#1.Relay1.Input', change: 'ne' }, function (obj) {
   schreibtischbereichSchalter = obj.state.val;
   setLights();
})
async function flipState(id) {
    setStateAsync(id, !getState(id).val);
}
/* Lightsobjects at home
device, lightSubTyp (Typ) */
// 0= hue 1= shelly 2= alexa
//STARTGLOBAL
type zoneIntersect = 'couch' | 'schreibtisch' | 'essbereich' | 'durchgang' | 'durchgang_schreibtisch' | 'durchgang_essbereich' | 'durchgang_couch';
type lightNameType = 'Couch' | 'Stehlampe' | 'Esstisch' | 'Computer-Wandlampe' | 'Vitrine' | 'Ambiente 1' | 'Ambiente 2' | 'Deckenstrahler' 
                        | 'Schreibtisch' | 'Fensterbank' | 'Deckenpanel';
type lightObjectsType = {
    id: string;
    name: lightNameType;
    day: boolean;
    night: boolean;
    timeout?: any;
} & lightSubType;
type LightZoneType = {}
//type sceneSettings = Record<lightNameType,{}>
type subCommandTyp = {
    stateName: string;
    mqttName?: string;
}
type lightSubType = ( { 
        mode: 0;
        state?:   
        {   
            on: subCommandTyp;
            bri: subCommandTyp;
            color?: subCommandTyp;
            colortemp?: subCommandTyp;
        }
    } | { 
        mode: 1;
        state?:   
        {
            on:subCommandTyp;
        }
    } | { 
        mode: 2;
        state?:   
        {  
            on: subCommandTyp;
        }
    } | { 
        mode: 3;
        state?:   
    {
            on: subCommandTyp
        }
    } | { 
        mode: 4;
        state?:   
        {
            on: subCommandTyp;
            bri: subCommandTyp;
            ps: subCommandTyp;
        }
    }
)
const lightSubMode: lightSubType[] =  [{ 
        mode: 0,
        state:   
        {   
            on:{stateName:".state", mqttName: 'state'},
            bri:{stateName: ".brightness", mqttName:'brightness'},
            color:{stateName:".color", mqttName:'color'},
            colortemp:{stateName:".colortemp", mqttName:'color_temp'},
        }
    } , { 
        mode: 1,
        state:   
        {
            on:{stateName:".Switch",},
        }
    } , { 
        mode: 2,
        state:   
        {  
            on:{stateName:".powerState", },
        }
    } , { 
        mode: 3,
        state:   
    {
        on:{stateName:".STATE",},
        }
    } , { 
        mode: 4,
        state:   
        {
            on:{stateName:".on", mqttName: 'on'},
            bri:{stateName: ".bri", mqttName:'bri'},
            ps:{stateName:".ps", mqttName:'ps'},
        }
    }]
type lightControlType = Record<lightNameType, lightSubType>
const lightObj: lightObjectsType[] = [
    { id: 'zigbee2mqtt.0.0x0017880102887f42', name: 'Couch', mode: 0, day: true, night: true }, // 0 Couch 
    { id: 'zigbee2mqtt.0.0x00178801028fc5cd', name: 'Stehlampe', mode: 0, day: true, night: true }, // 1 Standlicht
    // { id: 'zigbee2mqtt.0.0x0017880102922a60', mode: 0,  name: 'Wohnzimmer', day: false, night: true }, // 1 Kugel
    // { id: 'zigbee2mqtt.0.0x0017880109bde7e3', mode: 0,  name: 'Wohnzimmer', day: true, night: true }, // 2 Computer
    { id: 'zigbee2mqtt.0.group_4', name: 'Esstisch', mode: 0, day: true, night: true }, // 2 Esszimmer
    { id: 'zigbee2mqtt.0.0xb43522fffe55d341', name: 'Computer-Wandlampe', mode: 0, day: true, night: true }, // 3 Computer Wandlampe
    { id: 'alexa2.0.Smart-Home-Devices.54a20611-b863-4a2d-80c5-9b7f3caa2339', name: 'Vitrine', mode: 2, day: false, night: true }, // 4 Vitrine
    { id: 'shelly.0.SHSW-1#E8DB84D7B242#1.Relay0', name: 'Deckenpanel', mode: 1, day: true, night: true }, // 10 Deckenlampe Wohnzimmer
    { id: 'zigbee2mqtt.0.0x001788010bea2ef4', name: 'Ambiente 1', mode: 0, day: true, night: true }, // 11 Ambiente 1
    { id: 'zigbee2mqtt.0.0x001788010bea2ec7', name: 'Ambiente 2', mode: 0, day: true, night: true }, // 12 Ambiente 2
    { id: 'zigbee2mqtt.0.group_3', name: 'Deckenstrahler', mode: 0, day: true, night: true }, // 12 Deckenstrahler
    { id: 'wled.0.0cb815b8af3c', name: 'Schreibtisch', mode: 4, day: true, night: true, timeout: null }, // 13 Schreibtisch
    { id: 'wled.0.2cbcbb4f014c', name: 'Fensterbank', mode: 4, day: true, night: true, timeout: null } // 13 Fensterbank
];
// Subobj [x][1]
var lightSubTyp = [['.state', '.brightness', '.sat', '.color', '.colortemp']];
lightSubTyp.push(['.Switch']);
lightSubTyp.push(['.powerState']);
lightSubTyp.push(['.STATE']);
lightSubTyp.push(['.on','.bri', '.ps'])
const arrayLightSubTypToText = [
    ['On', 'Helligkeit', 'Saturation', 'Farbe', 'Farbtemperatur'],
    ['On'],
    ['On'],
    ['On'],
    ['On', 'Helligkeit', 'Voreinstellung',]
]
var Y = -1;
let lightScene:([boolean, number, number, string, number?] | [boolean] | [boolean, number,number])[][] = []; //0
//0
lightScene.push([[false, 180, 140, '#151200', 450]]); //0
lightScene[++Y].push([false, 250, 140, '#151200', 450]); //1
//lightScene[Y].push([false,100,140,'#151200', 2200]]); //1
//lightScene[Y].push([false,200,140,'#151200', 2200]]); //2
lightScene[Y].push([false, 230, 0, '', 450]); //8
lightScene[Y].push([false, 20,0,'',450]); //3
lightScene[Y].push([false]); //4
lightScene[Y].push([false]); //5
lightScene[Y].push([false, 230, 140, '#001237', 450]); //6
lightScene[Y].push([false, 230, 140, '#001237', 450]); //7
lightScene[Y].push([true, 230, 0, '', 450]); //8
lightScene[Y].push([false,200, 1]); //Schreibtisch 9
lightScene[Y].push([true,10,1]); //Fensterbank
// +1
//Globale Variablen
var currentScene = getState('0_userdata.0.currentSceneWZ').val;
var dimmerRef = null;
//setState('0_userdata.0.currentSceneWZ', currentScene);
// Wir überprüfen Scene und Lights Array ob sie zusammenpassen und werfen hilfreiche Fehlermeldungen raus, wenn nicht
pruefeBeideArraysAufFehler();
// Überprüfung der Array erledigt
function pruefeBeideArraysAufFehler() {
    var myBreak = false;
    var isError = false;
    for (var i = 0; i < lightScene.length; i++) {
        if (lightScene[i].length != lightObj.length) {
            var myErrorMsg = 'Anzahl der LightScene ' + i + ' Einträge: ' + lightScene[i].length + ' entspricht nicht der Anzahl and LightObjects: ' + lightObj.length;
            log(myErrorMsg, 'error');
            var maxLength;
            isError = true;
            if (lightScene[i].length > lightObj.length) maxLength = lightScene[i].length;
            else maxLength = lightObj.length;
            for (var y = 0; y < maxLength; y++) {
                myErrorMsg = '';
                if (y < lightScene[i].length) {
                    myErrorMsg = 'LightScene: ' + i + ' existiert Werte: ' + lightScene[i][y];
                    log(myErrorMsg, 'info');
                } else {
                    myErrorMsg = 'In LightScene: ' + i + ' existiert Datensatz ' + y + ' nicht!';
                    log(myErrorMsg, 'error');
                    myBreak = true;
                    break;
                }
                if (y < lightObj.length) {
                    myErrorMsg = 'LightObjects: ' + y + ' existiert ObjID: ' + lightObj[y][0];
                    log(myErrorMsg, 'info');
                } else {
                    myErrorMsg = 'LightObjects: ' + y + ' existiert nicht!';
                    log(myErrorMsg, 'error');
                    myBreak = true;
                    break;
                };
            }
            if (myBreak) break;
        }
    }
    if (isError) {
        myErrorMsg = 'Skript abgebrochen und pausiert. ';
        //@ts-ignore
        stopScript();
    }
}
// Überprüfung der Array erledigt
init();
async function init() {
    if (!await existsObjectAsync(path)) {
        await createFolderAsync(path, 'Szenen');
    }
    if (!await existsObjectAsync(`${path}.wohnzimmer`)) {
        await createDeviceAsync(`${path}.wohnzimmer`, 'Szenen');
    }
    if (!await existsObjectAsync(`${path}.wohnzimmer.autoModeBright`)) {
        await createStateAsync(`${path}.wohnzimmer.autoModeBright`, false, false, {name:'Hohe Helligkeit', role: 'state', type: 'boolean', read: true, write: true});
    }
    on({ id: `${path}.wohnzimmer.autoModeBright`, change: 'ne' }, function (obj) {
        autoModeBright = obj.state.val;
        autoModeOffTimeout = autoModeBright ? 15000 : 2000
        resetAutoMode();
        if (obj.id) setState(obj.id, obj.state.val, true);
    })
    
    for (const a in lightScene) {
        if (!await existsObjectAsync(`${path}.wohnzimmer.${a}`)) {
            await createChannelAsync(`${path}.wohnzimmer.${a}`, 'Szene');
            await createStateAsync(`${path}.wohnzimmer.${a}.dimmer`, 80, false, {name:'Helligkeitseinstellung', role: 'level.dimmer', type: 'number', unit:'%', min:1, max: 100, step:1, read: true, write: true});
        }
        if (!await existsObjectAsync(`${path}.wohnzimmer.${a}.useDimmer`)) {
            await createStateAsync(`${path}.wohnzimmer.${a}.useDimmer`, a != '0', false, {name:'Nutze Dimmer', role: 'switch', type: 'boolean', read: true, write: true});
        }
        dimmer[a] = {value: (getState(`${path}.wohnzimmer.${a}.dimmer`)).val/100, timeout: null};
        on({id: `${path}.wohnzimmer.${a}.dimmer`, change:'any', ack: false}, (dp) => {
            if (!dp || !dp.id) return;
            const arr = dp.id.split('.');
            arr.pop()
            const key = arr.pop();
            if (key !== undefined) {
                dimmer[key].value = dp.state.val / 100;
                if (dimmer[key].value <= 0.01 || dimmer[key].value >= 1) {
                    for (const light of lightObj) {
                        if (light.mode === 0 && dimmer[key].timeout == null && getState(light.id + lightSubTyp[light.mode][0]).val) {
                            setState(light.id + '.effect', 'blink');
                            dimmer[key].timeout = setTimeout((light) => {
                                setState(light.id + '.effect', 'stop_effect');
                                dimmer[key].timeout = null;
                            }, 1000, light);
                        }
                    }
                }
            }
            
            if (dp.oldState.val !== dp.state.val) reSetScene(true);
            setState(dp.id, dp.state.val, true);
        })
        for (const b in lightScene[a]) {
            if (!await existsObjectAsync(`${path}.wohnzimmer.${a}.${b}`)) {
                await createChannelAsync(`${path}.wohnzimmer.${a}.${b}`, lightObj[b].name);
            } else {
                await extendObjectAsync(`${path}.wohnzimmer.${a}.${b}`, {common:{ name: lightObj[b].name, } });
            }
            for (let cIndex = 0; cIndex < lightScene[a][b].length; cIndex++) {
                const c = arrayLightSubTypToText[lightObj[b].mode][cIndex]
                let value: any = undefined;
                if (await existsObjectAsync(`${path}.wohnzimmer.${a}.${b}.${cIndex}`)) {
                    value = getState(`${path}.wohnzimmer.${a}.${b}.${cIndex}`).val;
                    deleteState(`${path}.wohnzimmer.${a}.${b}.${cIndex}`);
                }
                if (!await existsStateAsync(`${path}.wohnzimmer.${a}.${b}.${c}`)) {     
                    value = value === undefined ? lightScene[a][b][cIndex] : value
                    await createStateAsync(`${path}.wohnzimmer.${a}.${b}.${c}`, value, {name: c, role: 'value', type: typeof lightScene[a][b][cIndex], read: true, write: true});
                    setState(`${path}.wohnzimmer.${a}.${b}.${c}`, value, true)
                } else {
                    if (typeof getState(`${path}.wohnzimmer.${a}.${b}.${c}`).val == 'object'){
                        value =  lightScene[a][b][cIndex];
                    }
                    if (value !== undefined) setState(`${path}.wohnzimmer.${a}.${b}.${c}`, value, true)
                    //if (c == 'Farbtemperatur') setState(`${path}.wohnzimmer.${a}.${b}.${c}`, 450, true)
                    const typ = typeof lightScene[a][b][cIndex];
                    switch (typ) {
                        case 'string':
                        case 'number':
                        case 'boolean':
                            await extendObjectAsync(`${path}.wohnzimmer.${a}.${b}.${c}`, {common:{ name: c, } });
                    }
                    
                }   
                await sleep(2) 
                lightScene[a][b][cIndex] = (getState(`${path}.wohnzimmer.${a}.${b}.${c}`)).val
            }
            on({id: new RegExp(`^${path}\\.wohnzimmer\\.${a}\\.${b}\..+`, 'g'), change:'any', ack: false}, (dp) => {
                if (!dp || !dp.id) return;
                const arr = dp.id.split('.');
                const c = arr.pop()
                if (c === undefined) return;
                const lampe = parseInt(arr.pop() ?? '');
                const scene = arr.pop();
                const option = arrayLightSubTypToText[lightObj[lampe].mode].findIndex((a) => a === c);
                if (scene === undefined || lampe === undefined || option === undefined) return;
                lightScene[scene][lampe][option] = dp.state.val;
                if (dp.oldState.val !== dp.state.val) {
                    if (currentScene != 0) reSetScene(true);
                    else resetAutoMode();
                }
                setState(dp.id, dp.state.val, true);
            })
        }
    }
}
function getCommandString(a,b) {
    return lightSubTyp[lightObj[a].mode][b]
}
schedule({ astro: "sunset" }, reSetScene);
schedule({ astro: "sunrise" }, reSetScene);
function autoScene(x) {
    // setze scene zurück wenn der ON Status der Lampen nicht der Scene entspricht.
    if (currentScene > x - 1 && currentScene < lightScene.length) {
        for (var i = 0; i < lightScene[currentScene].length; i++) {
            let astro = lightObj[i].day && isAstroDay() || !isAstroDay() && lightObj[i].night;
            if (lightObj[i].state && (lightScene[currentScene][i][0] && astro) != lightObj[i].state![getCommandString(i,0)]) {
                currentScene = x - 1;
                break;
            }
        }
    }
    // Scenen counter 
    currentScene++;
    if (currentScene >= 0 || currentScene >= lightScene.length || currentScene < x) {
        currentScene = x;
    }
    setState('0_userdata.0.currentSceneWZ', currentScene);
}
on({ id: '0_userdata.0.szene_wohnzimmer', change: 'any', ack: false }, function (obj) {
    switch (obj.state.val) {
        case 'c':
            setState('0_userdata.0.currentSceneWZ', 8);
            break;
        case 'f':
            setState('0_userdata.0.currentSceneWZ', 10);
            break;
        case 'e':
            setState('0_userdata.0.currentSceneWZ', 9);
            break;
        case 's':
            setState('0_userdata.0.currentSceneWZ', 11);
            break;
        case 'o':
            setState('0_userdata.0.currentSceneWZ', -1);
            break;
    }
})
on({ id: '0_userdata.0.currentSceneWZ', change: 'any', ack: false }, setScene)
function reSetScene(force = false) {
    if (DEBUG) log('current scene: ' + currentScene);
    if (currentScene == -1 || currentScene >= lightScene.length) return;
    for (var i = 0; i < lightScene[currentScene].length; i++) {
        if (!force && lightObj[i].state && lightScene[currentScene][i][0] != (lightObj[i].state![getCommandString(i,0)] == (lightObj[i].day && isAstroDay() || !isAstroDay() && lightObj[i].night))) {
            return;
        }
    }
    setScene(undefined)
}
async function setScene(obj) {
    if (obj !== undefined) {
        currentScene = obj.state.val;
    }
    if (currentScene == lightScene.length) return;
    if (currentScene == -1) { stopScene(); return; };
    if (currentScene === 0) {resetAutoMode(); return;}
    // Aktive Lampen auf Endwert setzen
    for (var i = 0; i < lightScene[currentScene].length; i++) {
        await sleep (25);
        switchLight(lightScene[currentScene][i], lightObj[i].name)
    }
    if (DEBUG) log("setScene to: " + currentScene);
    setState('0_userdata.0.currentSceneWZ', currentScene, true);
    switch (currentScene) {
        case 8:
            setState('0_userdata.0.szene_wohnzimmer', 'c', true)
            break;
        case 10:
            setState('0_userdata.0.szene_wohnzimmer', 'f', true);
            break;
        case 9:
            setState('0_userdata.0.szene_wohnzimmer', 'e', true);
            break;
        case 11:
            setState('0_userdata.0.szene_wohnzimmer', 's', true);
            break;
        case -1:
            setState('0_userdata.0.szene_wohnzimmer', 'o', true);
            break;
        default:
            setState('0_userdata.0.szene_wohnzimmer', '', true);
    }
};
let lastCommandTimeout: any = null
let lastCommand:any ={}
async function switchLight(cArray, lightName: string, overwriteOn: boolean|null = null, overwriteDim: number|null = null) {
    const light = lightObj.find(a => a.name == lightName);
    if (!light) return;
    
    var cTyp = light.mode;
    let astro = light.day && isAstroDay() || !isAstroDay() && light.night;
    let lOn = (overwriteOn === null || overwriteOn === true ? astro && (cArray[0] || !!overwriteOn) : false);
    let dimFix = currentScene != -1 ? (getState(`${path}.wohnzimmer.${currentScene}.useDimmer`).val ? dimmer[currentScene].value : 1) : 1;
    let dim = (overwriteDim !== null ? overwriteDim/100 : 1) * dimFix
    let carray4 = cArray[4]
    
    lastCommandTimeout && clearTimeout(lastCommandTimeout);
    lastCommandTimeout = setTimeout(() => {lastCommand = {}}, 30000)
    if (lastCommand[lightName] && lastCommand[lightName].cArray === cArray && lastCommand[lightName].overwriteOn === overwriteOn 
        && lastCommand[lightName].overwriteDim === overwriteDim && lastCommand[lightName].dim === dim && lastCommand[lightName].astro === astro ) {
        return;
    } else {
        lastCommand[lightName] = {cArray, overwriteOn, overwriteDim, dim, astro}
    }
    // Verweizweigung der Lampen nach Funktion;
    const isOn = getState(light.id + lightSubTyp[cTyp][0]).val;
   
    if (lOn === false && (isOn === false || light.timeout)) return;
     //log (overwriteOn + ' ' + astro + ' ' + cArray[0] + ' ' + lOn + ' '+ (astro && (cArray[0] || !!overwriteOn)) + ' ' + isOn)
    if (lOn) {
        if (cTyp == 0) { 
            let msg:{state:string, brightness: number, transition: number, color?:string, color_temp?: number} = {state: lOn ? 'ON' : 'OFF', brightness:(Math.round((cArray[1]-1) * dim)+1), transition: 1 }
            if (!cArray[4]) {
                msg.color = cArray[3];
            } else {
                carray4 = dimValue(cArray[4]-miredDiff, cArray[4]);
                msg.color_temp = carray4
            }
            if ((isOn && lOn)) {
                if (dim < dimFix) msg.transition = 3;
                else msg.transition = 3;
            } else {
                msg.transition = 1
            }
            if (isOn !== lOn || getState(light.id + lightSubTyp[cTyp][1]).val !== (Math.round((cArray[1]-1) * dim)+1) 
                || carray4 && getState(light.id + lightSubTyp[cTyp][4]).val !== carray4 || !carray4 && getState(light.id + lightSubTyp[cTyp][3]).val !== cArray[3]) {
                    sendTo('mqtt.0', 'sendMessage2Client', { topic: getTopic(light.id), message: JSON.stringify(msg) });
                }
            //log(getTopic(light.id) + ': ' + JSON.stringify(msg))
            //log(cArray[3])
        
        } else if (cTyp == 4) {    
            if (light.timeout) clearTimeout(light.timeout);       
            light.timeout = null;
            let bri = Math.round((cArray[1]-1) * dim)+1
            try {
                if (bri != getState(`${light.id}.bri`).val || lOn != getState(`${light.id}.on`).val || cArray[2] != getState(`${light.id}.ps`).val ) {
                    setState(`${light.id}.action`, JSON.stringify({
                        "bri": bri,
                        "on": lOn,
                        'ps': cArray[2],
                        'transition': 1
                    }))
                }
            } catch(error) {
                console.warn(`wled ${light.id} nicht erreichbar! ` + error)
            }
        } else {
            if (!isOn) setState(light.id + lightSubTyp[cTyp][0], lOn);        
        }
    } else {
        if (cTyp == 0) {
            let msg:{state:string, brightness: number, transition: number, color?:string, color_temp?: number} = {state: lOn ? 'ON' : 'OFF', brightness:(Math.round((cArray[1]-1) * dim)+1), transition: 2 }
             msg.transition = 6;
            
            if (isOn !== lOn)  sendTo('mqtt.0', 'sendMessage2Client', { topic: getTopic(light.id), message: JSON.stringify(msg) });
        } else if (cTyp === 4) {
            const ip = getState(`${light.id}._info.ip`).val
            try {
                if (!getState(`${light.id}.on`).val) {
                    if (light.timeout) clearTimeout(light.timeout);
                    return;
                }
                setState(`${light.id}.action`, JSON.stringify({
                    "bri": 1,
                    'ps': 5,           
                    })
                )
            } catch(error) {
                console.warn(`wled ${light.id} nicht erreichbar! ` + error)
            }
            if (light.timeout) clearTimeout(light.timeout);
            light.timeout = setTimeout((id) => {   
               setState(`${id}.on`, false)
            }, 60000*1, light.id)
        } else {
            if (getState(light.id + lightSubTyp[cTyp][0]).val) setStateDelayed(light.id + lightSubTyp[cTyp][0], false, 100)
        }
    }
    //log(lightObj[i].id+lightSubTyp[cTyp][0] + ' state: ' + lOn)
}
function getTopic(id) {
    const r = getTopic2(id);  
    return r.replace('group_3', 'Deckenstrahler').replace('group_4', 'Esstisch')
}
function getTopic2(id) {
    let a = id.split('.')
    return 'zigbee2mqtt/' + a[a.length - 1] + '/set'
}
async function stopScene() {
    currentScene = -1;
    for (var i = 0; i < lightObj.length; i++) {
        await sleep(50)
        await switchLight(lightScene[0][i], lightObj[i].name, false)
        //var cTyp = lightObj[i].mode;
        //if (getState(lightObj[i].id + lightSubTyp[cTyp][0]).val) setState(lightObj[i].id + lightSubTyp[cTyp][0], false);
    }
    setState('0_userdata.0.currentSceneWZ', currentScene, true)
    setState('0_userdata.0.szene_wohnzimmer', 'o', true);
}
function setBriOfLightsTo(value) {
    for (var i = 0; i < lightScene[currentScene].length; i++) {
        var cArray = lightScene[currentScene][i];
        if (cArray[0]) {
            var cTyp = lightObj[i].mode;
            if (cTyp == 0) {
                setState(lightObj[i].id + lightSubTyp[cTyp][1], value);
            } else {
            }
        }
    }
}
on({ id: 'shelly.0.SHSW-1#E8DB84D7B242#1.Relay0.longpush', change: 'ne' }, function (obj) {
    if (obj.state.val) {
        setState('0_userdata.0.currentSceneWZ', -1);
    }
})
on({ id: mySwitch + 'on_press', change: 'ne', val: true }, function (obj) {
    if (!mySwitchTimeout) {
        mySwitchTimeout = setTimeout(function () {
            autoScene(0);
            mySwitchTimeout = null;
        }, 300);
    }
});
on({ id: mySwitch + 'off_press', change: 'ne', val: true }, function (obj) {
    setState('0_userdata.0.currentSceneWZ', -1)
});
on({ id: mySwitch + 'off_hold', change: 'ne', val: true }, function (obj) {
    if (currentScene != -1)  setBriOfLightsTo(1);
});
on({ id: mySwitch + 'on_hold', change: 'ne', val: true }, function (obj) {
    if (!mySwitchTimeout) {
        mySwitchTimeout = setTimeout(function () {
            autoScene(7);
            mySwitchTimeout = null;
        }, 300);
    }
});
on({ id: mySwitch2 + 'on_press', change: 'ne', val: true }, function (obj) {
    atv(true)
});
on({ id: mySwitch2 + 'off_press', change: 'ne', val: true }, function (obj) {
    atv(false)
});
on({ id: mySwitch2 + 'down_press', change: 'ne', val: true }, function (obj) {
    if (!getState("hyperion_ng.0.1.components.V4L").val) setState("hyperion_ng.0.1.components.V4L", true);
});
on({ id: mySwitch2 + 'up_press', change: 'ne', val: true }, function (obj) {
    if (getState("hyperion_ng.0.1.components.V4L").val) setState("hyperion_ng.0.1.components.V4L", false);
});
on({ id: '0_userdata.0.Dummys.AppleTV_Licht_einschalten', change: "any", ack: false }, function (obj) {
    if (obj.state.val == true) {
        atv(true)
    }
    else {
        atv(false)
    }
    if (obj.id) setState(obj.id, obj.state.val, true);
})
let hyperionStartupCheck;
let appleTvPlaying = getState('homekit-controller.0.IP-68:80:C5:D1:2D:02.1.sensor-motion-52.motion-detected').val;
let hyperionWledIdOn = getState('sonoff.0.Gosund Steckdose 8.POWER').val;
let subscriptWled: any = null;
on({ id: 'sonoff.0.Gosund Steckdose 8.POWER', change: "ne" }, function (obj) {
    if (subscriptWled) clearTimeout(subscriptWled);
    if (!obj.state.val) {
        hyperionWledIdOn = obj.state.val;
        setState('hyperion-connector.0.107a543b-ddfc-5ac9-8f44-051ae0e6db4d.controls.system.suspend', true);
        SetLightsForAppleTV();   
    } else {
        subscriptWled = setTimeout(() => {
                hyperionWledIdOn = obj.state.val;
                SetLightsForAppleTV();     
        },500)       
    } 
})
let appleTvOffTimeout = null;
on({id:'homekit-controller.0.IP-68:80:C5:D1:2D:02.1.television-8.active', change:'ne'}, (obj) => {
    if (!hyperionWledIdOn) {
        appleTvOffTimeout = null;
        return;
    }
    if (obj.state.val != 0) {
        if (appleTvOffTimeout) {
            clearTimeout(appleTvOffTimeout)
            appleTvOffTimeout = null;
        }
        return;
    }
    if (appleTvOffTimeout) return;    
    appleTvOffTimeout = setTimeout(()=>{ 
        setState('sonoff.0.Gosund Steckdose 8.POWER', false); 
        appleTvOffTimeout = null;
        }, 120000)
})
on({id: 'homekit-controller.0.IP-68:80:C5:D1:2D:02.1.sensor-motion-52.motion-detected', change: 'ne'}, function(obj) {
    appleTvPlaying = obj.state.val;
    SetLightsForAppleTV(obj.state.val)
})
function SetLightsForAppleTV(isPlaying: boolean | null = null) {
    if (isPlaying === null) isPlaying = appleTvPlaying;
    if (isPlaying && hyperionWledIdOn) {
        setState('hyperion-connector.0.107a543b-ddfc-5ac9-8f44-051ae0e6db4d.controls.system.resume', true);
        if (!getState('hyperion-connector.0.107a543b-ddfc-5ac9-8f44-051ae0e6db4d.controls.componentstate.LEDDEVICE').val) setState('hyperion-connector.0.107a543b-ddfc-5ac9-8f44-051ae0e6db4d.controls.componentstate.LEDDEVICE', true);
        hyperion_on = true;
        setLights();
    } else {
        setState('hyperion-connector.0.107a543b-ddfc-5ac9-8f44-051ae0e6db4d.controls.system.idle', true);
        hyperion_on = false;
        setLights();
    }
}
async function atv(on) {
    if (on) {
        if (!getState('sonoff.0.Gosund Steckdose 3.POWER').val) {
            setState('sonoff.0.Gosund Steckdose 3.POWER', true)
            await sleep(5000)
        }
        if (!getState('sonoff.0.Gosund Steckdose 8.POWER').val) {
            setState('sonoff.0.Gosund Steckdose 8.POWER', true);
        }
        setState('0_userdata.0.Dummys.AppleTV_einschalten', true, false)
    } else {
        if (getState('sonoff.0.Gosund Steckdose 8.POWER').val) setState('sonoff.0.Gosund Steckdose 8.POWER', false);
        setStateDelayed('0_userdata.0.currentSceneWZ', currentScene, 800)
        setState('0_userdata.0.Dummys.AppleTV_ausschalten', true)
    }
}
on({ id: 'shelly.0.SHSW-1#E8DB84D7B242#1.Relay0.Input', change:'ne', val:true }, () => {
    DeckenpanelShouldOn = !DeckenpanelShouldOn;
    setLights(true);
})
let bigLampShouldOn = getState('shelly.0.SHSW-1#E8DB84D7B242#1.Relay0.Switch').val
let DeckenpanelShouldOn = getLightObjectState('Deckenpanel')
if (DeckenpanelShouldOn) {
    setLightObjectState('Deckenpanel', false)
    DeckenpanelShouldOn = false;
}
let presence
const radarZone = {
    lux: {
        front:'homekit-controller.0.IP-7D:4F:34:4A:51:D1.1.sensor-light-2672.light-level-current',
        behindComputer:'sonoff.0.lux1_tasmota_638B51.BH1750_Illuminance',
    },
    presence1: {
        id: 'homekit-controller.0.IP-C6:61:82:37:C4:1F.1.sensor-occupancy-2688.occupancy-detected',
        count: 0
    },
    presence2: {
        id: 'homekit-controller.0.IP-7D:4F:34:4A:51:D1.1.sensor-occupancy-2688.occupancy-detected',
        count: 0
    },
    durch: {
        id: 'homekit-controller.0.IP-C6:61:82:37:C4:1F.1.sensor-occupancy-2700.occupancy-detected',
        id2: 'homekit-controller.0.IP-7D:4F:34:4A:51:D1.1.sensor-occupancy-2696.occupancy-detected',
        count:0,
        count2: 0,
        state: false
    },
    couch: {
        id: 'homekit-controller.0.IP-C6:61:82:37:C4:1F.1.sensor-occupancy-2704.occupancy-detected',
        id2:'homekit-controller.0.IP-7D:4F:34:4A:51:D1.1.sensor-occupancy-2704.occupancy-detected',
        count:0,
        count2:0,
        state: false
    },
    computer: {
        id: 'homekit-controller.0.IP-C6:61:82:37:C4:1F.1.sensor-occupancy-2692.occupancy-detected',
        id2: 'homekit-controller.0.IP-7D:4F:34:4A:51:D1.1.sensor-occupancy-2692.occupancy-detected',
        count: 0,
        count2: 0,
        state: false
    },
    ess: {
        id: 'homekit-controller.0.IP-C6:61:82:37:C4:1F.1.sensor-occupancy-2696.occupancy-detected',
        id2: 'homekit-controller.0.IP-7D:4F:34:4A:51:D1.1.sensor-occupancy-2700.occupancy-detected',
        count: 0,
        count2: 0,
        state: false
    },
    durch_ess: {
        id: 'homekit-controller.0.IP-C6:61:82:37:C4:1F.1.sensor-occupancy-2712.occupancy-detected',
        count: 0,
        state: false
    },
    durch_computer: {
        id: 'homekit-controller.0.IP-C6:61:82:37:C4:1F.1.sensor-occupancy-2708.occupancy-detected',
        count: 0,
        state: false
    }
}
front = getState(radarZone.lux.front).val < luxminFront;
behindComputer = getState(radarZone.lux.behindComputer).val < luxminBehind;
behind = getState(radarZone.lux.front).val < luxminBehind;
let oldPresense: boolean | undefined = undefined
function checkPresence() {
    presence = !!radarZone.presence1.count || !!radarZone.presence2.count
    if (currentScene !== 0 && currentScene !== -1) {
        oldPresense = undefined;
        return;
    }
    if (oldPresense !== presence) {
        if (presence) {
            currentScene = 0;        
            //schreibtischLampe(true);
            //esstischLampe(true);
            //durchgang(true);
            setLights(undefined, true);
        }
    }
    oldPresense = presence;
    const dimmode =  getState('0_userdata.0.NSPanel.2.ScreensaverInfo.Trigger_Dimmode').val;
    if (presence ) {     
            if (!dimmode) setState('0_userdata.0.NSPanel.2.ScreensaverInfo.Trigger_Dimmode', true)
            setState('0_userdata.0.currentSceneWZ', 0, true) ;                     
        } else {
            if (dimmode) setState('0_userdata.0.NSPanel.2.ScreensaverInfo.Trigger_Dimmode', false)
            if (currentScene == 0) {
                setState('0_userdata.0.currentSceneWZ', -1)
            }
        }
}
radarZone.presence1.count = getState(radarZone.presence1.id).val;
radarZone.presence2.count = getState(radarZone.presence2.id).val;
on({id: radarZone.presence1.id, change: 'ne'}, function(obj){
    //log('0 Anwesenheit ' + obj.state.val)
    radarZone.presence1.count = obj.state.val 
    checkPresence();
});
on({id: radarZone.presence2.id, change: 'ne'}, function(obj){
    //log('0 Anwesenheit ' + obj.state.val)
    radarZone.presence2.count = obj.state.val 
    checkPresence();
});
on({id: radarZone.lux.front, change: 'ne'}, function(obj){
    front = obj.state.val < luxminFront;
    behind = obj.state.val < luxminBehind;
   
   
});
on({id: radarZone.lux.behindComputer, change: 'ne'}, function(obj){
    behindComputer = obj.state.val < luxminComputer;
});
on({id: radarZone.computer.id, change: 'ne'}, function(obj){
    //log('1 Schreibtisch ' + obj.state.val)
    radarZone.computer.count = obj.state.val
    if (currentScene != 0) return;
    setLights()
    //schreibtischLampe()
    
});
on({id: radarZone.computer.id2, change: 'ne'}, function(obj){
    //log('1 Schreibtisch ' + obj.state.val)
    radarZone.computer.count2 = obj.state.val
    if (currentScene != 0) return;
    setLights()
    //schreibtischLampe()
    
});
on({id: radarZone.ess.id, change: 'ne'}, function(obj){
    //log('2 Essbereich' + obj.state.val)
    radarZone.ess.count = obj.state.val
    if (currentScene != 0) return;
    setLights()
    //esstischLampe()
    //durchgang()
});
on({id: radarZone.ess.id2, change: 'ne'}, function(obj){
    //log('2 Essbereich' + obj.state.val)
    radarZone.ess.count2 = obj.state.val
    if (currentScene != 0) return;
    setLights()
    //esstischLampe()
    //durchgang()
});
on({id: radarZone.durch.id, change: 'ne'}, function(obj){
    //log('3 Durchgangsbereich' + obj.state.val)
    radarZone.durch.count = obj.state.val
    if (currentScene != 0) return;    
    setLights()
    //schreibtischLampe()
    //esstischLampe()
    //couchLampe()
    //durchgang()
});
on({id: radarZone.durch.id2, change: 'ne'}, function(obj){
    //log('3 Durchgangsbereich' + obj.state.val)
    radarZone.durch.count2 = obj.state.val
    if (currentScene != 0) return;    
    setLights()
    //schreibtischLampe()
    //esstischLampe()
    //couchLampe()
    //durchgang()
});
on({id:radarZone.couch.id, change: 'ne'}, function(obj){
    //log('4 Couch ' + obj.state.val)
    radarZone.couch.count = obj.state.val
    if (currentScene != 0) return;
    setLights()
    //couchLampe()
});
on({id: radarZone.durch_computer.id, change: 'ne'}, function(obj){
    //log('3 Durchgangsbereich' + obj.state.val)
    radarZone.durch_computer.count = obj.state.val
    if (currentScene != 0) return;   
     setLights() 
    //schreibtischLampe()
    //durchgang()
});
on({id: radarZone.durch_ess.id, change: 'ne'}, function(obj){
    //log('3 Durchgangsbereich' + obj.state.val)
    radarZone.durch_ess.count = obj.state.val
    if (currentScene != 0) return;    
    setLights()
    //esstischLampe()
    //durchgang()
});
on({id:radarZone.couch.id2, change: 'ne'}, function(obj){
    //log('4 Couch ' + obj.state.val)
    radarZone.couch.count2 = obj.state.val
    if (currentScene != 0) return;
    setLights()
    //couchLampe()
});
resetAutoMode()
function resetAutoMode() {
    if (currentScene != 0) return;
    
    const obj: {state:{val:any}} = {state: {val:0}}
   
    obj.state.val = getState(radarZone.computer.id).val
    radarZone.computer.count = obj.state.val
    
    obj.state.val = getState(radarZone.computer.id2).val
    radarZone.computer.count2 = obj.state.val
    obj.state.val = getState(radarZone.ess.id).val
    radarZone.ess.count = obj.state.val
    obj.state.val = getState(radarZone.ess.id2).val
    radarZone.ess.count2 = obj.state.val
    obj.state.val = getState(radarZone.durch.id).val
    radarZone.durch.count = obj.state.val
    obj.state.val = getState(radarZone.durch.id2).val
    radarZone.durch.count2 = obj.state.val
    obj.state.val = getState(radarZone.couch.id).val
    radarZone.couch.count = obj.state.val
    obj.state.val = getState(radarZone.durch_computer.id).val
    radarZone.durch_computer.count = obj.state.val
    obj.state.val = getState(radarZone.durch_ess.id).val
    radarZone.durch_ess.count = obj.state.val
 
    obj.state.val = getState(radarZone.couch.id2).val
    radarZone.couch.count2 = obj.state.val
    obj.state.val = getState(radarZone.lux.front).val
    front = obj.state.val < luxminFront;
    behind = obj.state.val < luxminBehind;
    obj.state.val = getState(radarZone.lux.behindComputer).val
    behindComputer = obj.state.val < luxminComputer;
    setLights();
}
const lightZoneSettings:Record<lightNameType, {on: boolean, dim: number, timeout: any, hyperion?:boolean}>  = {
    Couch: {
        on: false,
        hyperion: true,
        dim:0,
        timeout: null,
    },
    Schreibtisch: {
        on: false,
        
        dim:0,
        timeout: null,
    },
    Esstisch: {
        on: false,
        
        dim:0,
        timeout: null,
    },
    Deckenstrahler: {
        on: false,
        
        dim:0,
        timeout: null,
    },
    "Computer-Wandlampe": {
        on: false,
        dim:0,
        timeout: null,
    },
    "Deckenpanel": {
        on: false,
        hyperion: true,
        dim:0,
        timeout: null,
    },
    "Ambiente 1": {
        on: false,
        
        dim:0,
        timeout: null,
    },
    "Ambiente 2": {
        on: false,
        
        dim:0,
        timeout: null,
    },
    Fensterbank: {
        on: false,
        
        dim:0,
        timeout: null,
    },
    Stehlampe: {
        on: false,
        hyperion: true,
        dim:0,
        timeout: null,
    },
    "Vitrine": {
        on: false,
        
        dim:0,
        timeout: null,
    },
    
}
/*
* getLightObject
* @param name: lightNameType  
* @returns lightObject
*/
function getLightObject(name: lightNameType): lightObjectsType {
    const result = lightObj.find(a => a.name === name);
    if (!result) {
        throw new Error(`lightObject ${name} not found`)
    }
    return result;
}   
function getLightObjectState(name: lightNameType): boolean {
    return getState(getLightObject(name).id + lightSubTyp[getLightObject(name).mode][0]).val
}
function getLightObjectIndex(name: lightNameType) {
    return lightObj.findIndex(a => a.name === name)
}
function setLightObjectState(name: lightNameType, on: boolean): void {
    setState(getLightObject(name).id + lightSubTyp[getLightObject(name).mode][0], on)
}
let timeoutSetLights: any = null;
function setLights(force: boolean = false, go: boolean = false) {
    try {
        //debounce
        if (timeoutSetLights) {
            clearTimeout(timeoutSetLights)
            timeoutSetLights = null;
        }
        if (!go) {
            timeoutSetLights = setTimeout(() => {
                setLights(force, true)
            }, 100)
            return;
        }
        // reset variables
        for (const key in lightZoneSettings) {
            lightZoneSettings[key].on = false;
            lightZoneSettings[key].dim = 0;
        }
        /*
        * 1. Couch
        * 2. Schreibtisch
        * 3. Esstisch
        * 4. Deckenstrahler
        * 5. Computer-Wandlampe
        * 6. Deckenpanel
        * 7. Ambiente 1
        * 8. Ambiente 2
        * 9. Fensterbank
        * 10. Stehlampe
        * 11. Vitrine
        * 
        *  lux is the indoor light sensor value
        *  toDark is true if the outdoor light sensor value is below the minimum lux value
        */
        const toDark = shutterPos > cShutterPosForLight || behind || !isAstroDay();
        const toDarkComputer = shutterPos > cShutterPosForLight || behindComputer || !isAstroDay();
        //Couch
        let on = radarZone.couch.count > 0 || radarZone.couch.count2 > 0;
        let dim = radarZone.couch.count > 0 || radarZone.couch.count2 > 0 ? 100 : 5;
        on = on && front;
        lightZoneSettings.Couch.on = lightZoneSettings.Couch.on || on;
        lightZoneSettings.Couch.dim = Math.max(lightZoneSettings.Couch.dim ,dim);
        lightZoneSettings.Stehlampe.on = lightZoneSettings.Stehlampe.on || on;
        lightZoneSettings.Stehlampe.dim = Math.max(lightZoneSettings.Stehlampe.dim, dim);
        lightZoneSettings.Deckenpanel.on = lightZoneSettings.Deckenpanel.on || on;
        lightZoneSettings.Deckenpanel.dim = Math.max(lightZoneSettings.Deckenpanel.dim, dim);
        
        //Computer
        on =  radarZone.computer.count > 0 || radarZone.computer.count2 > 0 || radarZone.durch_computer.count > 0 ;
        on = on && toDarkComputer || schreibtischbereichSchalter
        dim =  radarZone.computer.count > 0 || radarZone.computer.count2 > 0 || radarZone.durch_computer.count > 0  || schreibtischbereichSchalter? 100 : 15;
        
        let dim2 = schreibtischbereichSchalter ? 100 : on ? 50 : 10;
        lightZoneSettings['Computer-Wandlampe'].on = lightZoneSettings['Computer-Wandlampe'].on || on
        lightZoneSettings['Computer-Wandlampe'].dim = Math.max(lightZoneSettings['Computer-Wandlampe'].dim, dim2) 
        lightZoneSettings['Ambiente 1'].on = lightZoneSettings['Ambiente 1'].on || on
        lightZoneSettings['Ambiente 1'].dim = Math.max(lightZoneSettings['Ambiente 1'].dim, dim)
        lightZoneSettings['Ambiente 2'].on = lightZoneSettings['Ambiente 2'].on || on
        lightZoneSettings['Ambiente 2'].dim = Math.max(lightZoneSettings['Ambiente 2'].dim, dim)
        lightZoneSettings.Schreibtisch.on = lightZoneSettings.Schreibtisch.on || on
        lightZoneSettings.Schreibtisch.dim = Math.max(lightZoneSettings.Schreibtisch.dim, dim)
        
        //Esstisch
        on =  lightZoneSettings.Esstisch.on || radarZone.ess.count > 0 || radarZone.ess.count2 > 0 || radarZone.durch_ess.count > 0;
        on = on && toDark || essbereichSchalter
        dim = Math.max(lightZoneSettings.Esstisch.dim, radarZone.ess.count > 0 || radarZone.ess.count2 > 0 || radarZone.durch_ess.count > 0 || essbereichSchalter ? 100 : 15);
        lightZoneSettings.Esstisch.on = on;
        lightZoneSettings.Esstisch.dim = dim;
        // Durchgang
        on = radarZone.durch.count +radarZone.durch.count2 > 0 || radarZone.durch_ess.count > 0 || radarZone.durch_computer.count > 0 || (schreibtischbereichSchalter && DeckenpanelShouldOn);
        on = on && toDark
        dim = Math.max(radarZone.durch.count+radarZone.durch.count2 > 0 ? 85 : 0);
        dim = Math.max(dim, radarZone.durch_ess.count > 0 || radarZone.durch_computer.count > 0 || (schreibtischbereichSchalter && DeckenpanelShouldOn) ? 70 : 0);
        lightZoneSettings.Couch.on = lightZoneSettings.Couch.on || (on && front);
        lightZoneSettings.Stehlampe.on = lightZoneSettings.Stehlampe.on || (on && front);
        lightZoneSettings.Deckenstrahler.on = lightZoneSettings.Deckenstrahler.on || on;
        lightZoneSettings.Deckenstrahler.dim = Math.max(lightZoneSettings.Deckenstrahler.dim, dim);
        lightZoneSettings.Deckenpanel.on = lightZoneSettings.Deckenpanel.on || on;
        lightZoneSettings.Deckenpanel.dim = Math.max(lightZoneSettings.Deckenpanel.dim, dim);
        lightZoneSettings.Fensterbank.on = lightZoneSettings.Fensterbank.on || on;
        lightZoneSettings.Fensterbank.dim = Math.max(lightZoneSettings.Fensterbank.dim, dim);
        lightZoneSettings['Ambiente 1'].on = on  || lightZoneSettings['Ambiente 1'].on;
        lightZoneSettings['Ambiente 1'].dim = Math.max(lightZoneSettings['Ambiente 1'].dim, 3);
        lightZoneSettings['Ambiente 2'].on = on  || lightZoneSettings['Ambiente 2'].on;
        lightZoneSettings['Ambiente 2'].dim = Math.max(lightZoneSettings['Ambiente 2'].dim, 3);
        lightZoneSettings.Schreibtisch.on = on  || lightZoneSettings.Schreibtisch.on;
        lightZoneSettings.Schreibtisch.dim = Math.max(lightZoneSettings.Schreibtisch.dim, 3);
        lightZoneSettings.Esstisch.on =  on  || lightZoneSettings.Esstisch.on;
        lightZoneSettings.Esstisch.dim = Math.max(lightZoneSettings.Esstisch.dim, 3);
        
        // if Durchgang is true dont deactivate lights in Schreibtisch and Esstisch
        on = radarZone.durch.count+radarZone.durch.count2 > 0 || radarZone.durch_ess.count > 0 || radarZone.durch_computer.count > 0
        on = on && toDark
        lightZoneSettings.Couch.on = (getLightObjectState("Couch") && on && front) || lightZoneSettings.Couch.on
        lightZoneSettings.Stehlampe.on = (getLightObjectState("Stehlampe") && on && front) || lightZoneSettings.Stehlampe.on
        lightZoneSettings["Computer-Wandlampe"].on = (getLightObjectState("Computer-Wandlampe") && on) || lightZoneSettings["Computer-Wandlampe"].on;
        lightZoneSettings["Computer-Wandlampe"].dim = Math.max(lightZoneSettings["Computer-Wandlampe"].dim, 10);
        lightZoneSettings['Ambiente 1'].on = (getLightObjectState('Ambiente 1') && on)  || lightZoneSettings['Ambiente 1'].on;
        lightZoneSettings['Ambiente 1'].dim = Math.max(lightZoneSettings['Ambiente 1'].dim, 3);
        lightZoneSettings['Ambiente 2'].on = (getLightObjectState('Ambiente 2') && on)  || lightZoneSettings['Ambiente 2'].on;
        lightZoneSettings['Ambiente 2'].dim = Math.max(lightZoneSettings['Ambiente 2'].dim, 3);
        lightZoneSettings.Schreibtisch.on = (getLightObjectState('Schreibtisch') && on)  || lightZoneSettings.Schreibtisch.on;
        lightZoneSettings.Schreibtisch.dim = Math.max(lightZoneSettings.Schreibtisch.dim, 3);
        lightZoneSettings.Esstisch.on = (getLightObjectState('Esstisch') && on)  || lightZoneSettings.Esstisch.on;
        lightZoneSettings.Esstisch.dim = Math.max(lightZoneSettings.Esstisch.dim, 3);
        
    
        /*
        * Dont activate the light if day is detected
        */
        if (isAstroDay()) {
            lightZoneSettings.Fensterbank.on = getLightObjectState('Fensterbank') || schreibtischbereichSchalter && lightZoneSettings.Fensterbank.on;
            lightZoneSettings.Schreibtisch.on = getLightObjectState('Schreibtisch') || schreibtischbereichSchalter && lightZoneSettings.Schreibtisch.on;
        }
        // Deactive the big light if the value is false
        if (!bigLampShouldOn) {
            lightZoneSettings.Deckenpanel.on = false;
            lightZoneSettings.Deckenpanel.dim = 0;
            //lightZoneSettings['Computer-Wandlampe'].on = false;
            lightZoneSettings['Computer-Wandlampe'].dim = schreibtischbereichSchalter ? 100 : Math.max(lightZoneSettings['Computer-Wandlampe'].dim, 10);
        } else {
            lightZoneSettings.Deckenpanel.on = true;
            lightZoneSettings.Deckenpanel.dim = 0;
            lightZoneSettings['Computer-Wandlampe'].on = true;
            lightZoneSettings['Computer-Wandlampe'].dim = 95;
        }
        // if hyperion is on deactivate the other lights
        if (hyperion_on) {
            lightZoneSettings.Couch.on = false;
            lightZoneSettings.Couch.dim = 0;
            lightZoneSettings.Stehlampe.on = false;
            lightZoneSettings.Stehlampe.dim = 0;
            lightZoneSettings.Deckenpanel.on = false;
            lightZoneSettings.Deckenpanel.dim = 0;
            lightZoneSettings.Deckenstrahler.dim = Math.min(lightZoneSettings.Deckenstrahler.dim, 25);
            lightZoneSettings.Fensterbank.dim = Math.min(lightZoneSettings.Fensterbank.dim, 5);
        }
        // if button is pressed activate the deckenpanel
        if (DeckenpanelShouldOn) {
            lightZoneSettings.Deckenpanel.on = true;
            lightZoneSettings.Deckenpanel.dim = 100;
        }
        // if any light is on activte the deckenspots
        on = false;
        for (const key in lightZoneSettings) {
            on = on || lightZoneSettings[key].on;
        }
        lightZoneSettings.Deckenstrahler.on = toDark && (on || lightZoneSettings.Deckenstrahler.on);
        lightZoneSettings.Deckenstrahler.dim = Math.max(lightZoneSettings.Deckenstrahler.dim, 5);
        
        // write the settings to the lights
        for (const key in lightZoneSettings) {
            if (lightZoneSettings[key].timeout) clearTimeout(lightZoneSettings[key].timeout);
            if (lightZoneSettings[key].on) {
                switchLight(lightScene[0][getLightObjectIndex(key as any)], key, lightZoneSettings[key].on, lightZoneSettings[key].dim == 100 ? undefined : lightZoneSettings[key].dim);
            } else {
                if (force || (hyperion_on && lightZoneSettings[key].hyperion)) {
                    switchLight(lightScene[0][getLightObjectIndex(key as any)], key, lightZoneSettings[key].on, lightZoneSettings[key].dim == 100 ? undefined : lightZoneSettings[key].dim)
                } else {
                    lightZoneSettings[key].timeout = setTimeout((key) => {
                        switchLight(lightScene[0][getLightObjectIndex(key as any)], key, lightZoneSettings[key].on, lightZoneSettings[key].dim == 100 ? undefined : lightZoneSettings[key].dim)
                    }, autoModeOffTimeout, key)
                }
            }
            
        }
    } catch(error) {
        log(error as string)
    }
}
function dimValue(from: number, to: number): number {
        return _dimValue({from, to});
}
type dimValueOptionsType = {
    begin?: string;
    end?: string;
    reset?: string;
    from?: number;
    to?: number;
    sunset?: boolean | number
}
function _dimValue(options: dimValueOptionsType = {}): number {
    options = {...dimValueOptions, ...options}
    if (!options.begin || !options.end || !options.reset || options.from === undefined || options.to === undefined ) {
        log('missing value')
        return options.from || 0;
    }
    const startArr = options.begin.split(':');
    const endArr = options.end.split(':');
    const resetArr = options.reset.split(':');
    if (startArr.length <= 1 || endArr.length <= 1 || resetArr.length <= 1) {
        log('dimValue: missing string in start, reset or end (xx:xx)')
        return options.to
    }
    const currentTime = new Date().getTime();
    let startTime = new Date().setHours(parseInt(startArr[0]), parseInt(startArr[1]), startArr[2] ? parseInt(startArr[2]) : 0 );
    let endTime = new Date().setHours(parseInt(endArr[0]), parseInt(endArr[1]), endArr[2] ? parseInt(endArr[2]) : 0 );
    let resetTime = new Date().setHours(parseInt(resetArr[0]), parseInt(resetArr[1]), resetArr[2] ? parseInt(resetArr[2]) : 0 );
    
    if (endTime < startTime) {
        if (startTime > currentTime && endTime > currentTime) {
            // end is this day
            startTime -=24 * 60 * 60 * 1000;
        } 
        if (startTime <= currentTime && endTime <= currentTime) {
            // end is next day
            endTime += 24 * 60 * 60 * 1000
        }
    }
    let from = options.from;
    const to = options.to;
    const sunset = options.sunset
    from = sunset && typeof sunset === 'number' ? calculateDimSunset(from, sunset) : from;
    if (currentTime <= startTime || currentTime >= endTime) {
        //  20:00 > 6:00 && 20:00 < 21:00 (true) || 6:00 > 2:00 && 1:00 < 2:00 (true)
        if (currentTime >= resetTime && currentTime < startTime || resetTime > startTime && currentTime < startTime ) {
            return from;
        }
        return to;
    }
    const diff = to - from;
    const result = Math.round(diff * (currentTime-startTime) / (endTime-startTime)) + from;
    return result; 
}
function calculateDimSunset(from: number, to: number | number): number {
    const sunsetStartTime = getAstroDate('sunsetStart').getTime();
    const sunsetEndTime = getAstroDate('dusk').getTime();
    const currentTime = new Date().getTime();
    if (currentTime > sunsetEndTime) return to;
    else if (currentTime < sunsetStartTime) return from;
    const diff = to - from;
    const result = Math.round(diff * (currentTime-sunsetStartTime) / (sunsetEndTime-sunsetStartTime)) + from;
    return result;
}