<commit_before>/**
 *
 *      ioBroker Philips Hue Bridge Adapter
 *
 *      (c) 2014-2015 hobbyquaker
 *
 *      MIT License
 *
 */
/* jshint -W097 */// jshint strict:false
/*jslint node: true */
"use strict";

var hue = require('node-hue-api');
var utils = require(__dirname + '/lib/utils'); // Get common adapter utils
var huehelper = require('./lib/HueHelper');

var adapter = utils.adapter('hue');

adapter.on('stateChange', function (id, state) {
    if (!id || !state || state.ack) {
        return;
    }

    adapter.log.debug('stateChange ' + id + ' ' + JSON.stringify(state));
    var tmp = id.split('.');
    var dp = tmp.pop();
    id = tmp.slice(2).join('.');
    var ls = {};
    //if .on changed instead change .bri to 254 or 0
    var bri = 0;
    if (dp == 'on') {
        bri = state.val ? 254 : 0;
        adapter.setState([id, 'bri'].join('.'), {val: bri, ack: false});
        return;
    }
    //if .level changed instead change .bri to level.val*254
    if (dp == 'level') {
        bri = Math.max(Math.min(Math.round(state.val * 2.54), 254), 0);
        adapter.setState([id, 'bri'].join('.'), {val: bri, ack: false});
        return;
    }
    //get lamp states
    adapter.getStates(id + '.*', function (err, idStates) {
        if (err) {
            adapter.log.error(err);
            return;
        }
        //gather states that need to be changed
        ls = {};
        var alls = {};
        var lampOn = false;
        for (var idState in idStates) {
            if (!idStates.hasOwnProperty(idState)) {
                continue;
            }
            var idtmp = idState.split('.');
            var iddp = idtmp.pop();
            switch (iddp) {
                case 'bri':
                    alls[iddp] = idStates[idState].val;
                    ls[iddp] = idStates[idState].val;
                    if (idStates[idState].ack && idStates[idState].val > 0) lampOn = true;
                    break;
                case 'alert':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'alert') ls[iddp] = idStates[idState].val;
                    break;
                case 'effect':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'effect') ls[iddp] = idStates[idState].val;
                    break;
                case 'r':
                case 'g':
                case 'b':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'r' || dp == 'g' || dp == 'b') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'ct':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'ct') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'hue':
                case 'sat':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'hue' || dp == 'sat') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'xy':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'xy') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'command':
                    if (dp == 'command') {
                        try {
                            var commands = JSON.parse(state.val);
                            for (var command in commands) {
                                if (!commands.hasOwnProperty(command)) {
                                    continue;
                                }
                                if (command == 'on') {
                                    //convert on to bri
                                    if (commands[command] && !commands.hasOwnProperty('bri')) {
                                        ls.bri = 254;
                                    } else {
                                        ls.bri = 0;
                                    }
                                } else {
                                    ls[command] = commands[command];
                                }
                            }
                        } catch (e) {
                            adapter.log.error(e);
                            return;
                        }
                    }
                    alls[iddp] = idStates[idState].val;
                    break;
                default:
                    alls[iddp] = idStates[idState].val;
                    break;
            }
        }
        //apply rgb to xy
        if ('r' in ls || 'g' in ls || 'b' in ls) {
            if (!('r' in ls)) {
                ls.r = 0;
            }
            if (!('g' in ls)) {
                ls.g = 0;
            }
            if (!('b' in ls)) {
                ls.b = 0;
            }
            var xyb = huehelper.RgbToXYB(ls.r / 255, ls.g / 255, ls.b / 255, 'LCT001');
            ls.bri = xyb.b;//Math.max(ls.r,ls.g,ls.b);
            ls.xy = xyb.x + ',' + xyb.y;
        }


        //create lightState from ls
        //and check values
        var lightState = hue.lightState.create();
        var finalLS = {};
        if (ls.bri > 0) {
            lightState = lightState.on().bri(Math.min(254, ls.bri));
            finalLS.bri = Math.min(254, ls.bri);
            finalLS.on = true;
        } else {
            lightState = lightState.off();
            finalLS.bri = 0;
            finalLS.on = false;
        }
        if ('xy' in ls) {
            var xy = ls.xy.split(',');
            xy = {'x': xy[0], 'y': xy[1]};
            xy = huehelper.GamutXYforModel(xy.x, xy.y, 'LCT001');
            finalLS.xy = xy.x + ',' + xy.y;
            lightState = lightState.xy(xy.x, xy.y);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
        }
        if ('ct' in ls) {
            finalLS.ct = Math.max(153, Math.min(500, ls.ct));
            lightState = lightState.ct(finalLS.ct);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
        }
        if ('hue' in ls) {
            finalLS.hue = Math.max(0, Math.min(65535, ls.hue));
            lightState = lightState.hue(finalLS.hue);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
        }
        if ('sat' in ls) {
            finalLS.sat = Math.max(0, Math.min(254, ls.sat));
            lightState = lightState.sat(finalLS.sat);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
        }<commit_msg>fast write back rgb on xy changes<commit_after>/**
 *
 *      ioBroker Philips Hue Bridge Adapter
 *
 *      (c) 2014-2015 hobbyquaker
 *
 *      MIT License
 *
 */
/* jshint -W097 */// jshint strict:false
/*jslint node: true */
"use strict";

var hue = require('node-hue-api');
var utils = require(__dirname + '/lib/utils'); // Get common adapter utils
var huehelper = require('./lib/HueHelper');

var adapter = utils.adapter('hue');

adapter.on('stateChange', function (id, state) {
    if (!id || !state || state.ack) {
        return;
    }

    adapter.log.debug('stateChange ' + id + ' ' + JSON.stringify(state));
    var tmp = id.split('.');
    var dp = tmp.pop();
    id = tmp.slice(2).join('.');
    var ls = {};
    //if .on changed instead change .bri to 254 or 0
    var bri = 0;
    if (dp == 'on') {
        bri = state.val ? 254 : 0;
        adapter.setState([id, 'bri'].join('.'), {val: bri, ack: false});
        return;
    }
    //if .level changed instead change .bri to level.val*254
    if (dp == 'level') {
        bri = Math.max(Math.min(Math.round(state.val * 2.54), 254), 0);
        adapter.setState([id, 'bri'].join('.'), {val: bri, ack: false});
        return;
    }
    //get lamp states
    adapter.getStates(id + '.*', function (err, idStates) {
        if (err) {
            adapter.log.error(err);
            return;
        }
        //gather states that need to be changed
        ls = {};
        var alls = {};
        var lampOn = false;
        for (var idState in idStates) {
            if (!idStates.hasOwnProperty(idState)) {
                continue;
            }
            var idtmp = idState.split('.');
            var iddp = idtmp.pop();
            switch (iddp) {
                case 'bri':
                    alls[iddp] = idStates[idState].val;
                    ls[iddp] = idStates[idState].val;
                    if (idStates[idState].ack && idStates[idState].val > 0) lampOn = true;
                    break;
                case 'alert':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'alert') ls[iddp] = idStates[idState].val;
                    break;
                case 'effect':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'effect') ls[iddp] = idStates[idState].val;
                    break;
                case 'r':
                case 'g':
                case 'b':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'r' || dp == 'g' || dp == 'b') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'ct':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'ct') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'hue':
                case 'sat':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'hue' || dp == 'sat') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'xy':
                    alls[iddp] = idStates[idState].val;
                    if (dp == 'xy') {
                        ls[iddp] = idStates[idState].val;
                    }
                    break;
                case 'command':
                    if (dp == 'command') {
                        try {
                            var commands = JSON.parse(state.val);
                            for (var command in commands) {
                                if (!commands.hasOwnProperty(command)) {
                                    continue;
                                }
                                if (command == 'on') {
                                    //convert on to bri
                                    if (commands[command] && !commands.hasOwnProperty('bri')) {
                                        ls.bri = 254;
                                    } else {
                                        ls.bri = 0;
                                    }
                                } else {
                                    ls[command] = commands[command];
                                }
                            }
                        } catch (e) {
                            adapter.log.error(e);
                            return;
                        }
                    }
                    alls[iddp] = idStates[idState].val;
                    break;
                default:
                    alls[iddp] = idStates[idState].val;
                    break;
            }
        }
        //apply rgb to xy
        if ('r' in ls || 'g' in ls || 'b' in ls) {
            if (!('r' in ls)) {
                ls.r = 0;
            }
            if (!('g' in ls)) {
                ls.g = 0;
            }
            if (!('b' in ls)) {
                ls.b = 0;
            }
            var xyb = huehelper.RgbToXYB(ls.r / 255, ls.g / 255, ls.b / 255, 'LCT001');
            ls.bri = xyb.b;//Math.max(ls.r,ls.g,ls.b);
            ls.xy = xyb.x + ',' + xyb.y;
        }


        //create lightState from ls
        //and check values
        var lightState = hue.lightState.create();
        var finalLS = {};
        if (ls.bri > 0) {
            lightState = lightState.on().bri(Math.min(254, ls.bri));
            finalLS.bri = Math.min(254, ls.bri);
            finalLS.on = true;
        } else {
            lightState = lightState.off();
            finalLS.bri = 0;
            finalLS.on = false;
        }
        if ('xy' in ls) {
            var xy = ls.xy.split(',');
            xy = {'x': xy[0], 'y': xy[1]};
            xy = huehelper.GamutXYforModel(xy.x, xy.y, 'LCT001');
            finalLS.xy = xy.x + ',' + xy.y;
            lightState = lightState.xy(xy.x, xy.y);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
            var rgb = huehelper.XYBtoRGB(xy.x, xy.y, (finalLS.bri / 254));
            finalLS.r = Math.round(rgb.Red * 254);
            finalLS.g = Math.round(rgb.Green * 254);
            finalLS.b = Math.round(rgb.Blue * 254);
        }
        if ('ct' in ls) {
            finalLS.ct = Math.max(153, Math.min(500, ls.ct));
            lightState = lightState.ct(finalLS.ct);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
        }
        if ('hue' in ls) {
            finalLS.hue = Math.max(0, Math.min(65535, ls.hue));
            lightState = lightState.hue(finalLS.hue);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
        }
        if ('sat' in ls) {
            finalLS.sat = Math.max(0, Math.min(254, ls.sat));
            lightState = lightState.sat(finalLS.sat);
            if (!lampOn && (!('bri' in ls) || ls.bri === 0)) {
                lightState = lightState.on();
                lightState = lightState.bri(254);
                finalLS.bri = 254;
                finalLS.on = true;
            }
        }
{'fraction_non_alphanumeric': 0.13974178874841126, 'fraction_numerical': 0.01525185631145896, 'mean_word_length': 1.0240996479826698, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1471357', 'n_tokens_mistral': 4757, 'n_tokens_neox': 4292, 'n_words': 957}