<commit_before>/*  nodejs-poolController.  An application to control pool equipment.
Copyright (C) 2016, 2017, 2018, 2019, 2020.  <NAME>, tagyoureit.  <EMAIL>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
import { Inbound } from "../Messages";
import { sys, Body, Circuit, ICircuit } from "../../../Equipment";
import { state, BodyTempState } from "../../../State";
import { logger } from "../../../../logger/Logger";

export class CircuitMessage {
    public static processTouch(msg: Inbound): void {
        switch (msg.action) {
            case 11: // IntelliTouch Circuits
                CircuitMessage.processCircuitAttributes(msg);
                break;
            case 39: // IntelliTouch Light Groups
            case 167:
                CircuitMessage.processIntelliBrite(msg);
                break;
            default:
                logger.debug(`Unprocessed Message ${msg.toPacket()}`)
                break;
        }
    }
    public static processIntelliCenter(msg: Inbound) {
        switch (msg.extractPayloadByte(1)) {
            case 0: // Circuit Type
                CircuitMessage.processCircuitTypes(msg);
                break;
            case 1: // Freeze
                CircuitMessage.processFreezeProtect(msg);
                break;
            case 2: // Show in features
                CircuitMessage.processShowInFeatures(msg);
                break;
            case 3: // Circuit Names
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            case 21:
            case 22:
            case 23:
            case 24:
                CircuitMessage.processCircuitNames(msg);
                break;
            case 25: // Not sure what this is.
                break;
            case 26:
                CircuitMessage.processLightingTheme(msg);
                break;
            case 27:
                CircuitMessage.processEggTimerHours(msg);
                break;
            case 28:
                CircuitMessage.processEggTimerMinutes(msg);
                break;
            case 29:
                CircuitMessage.processDontStop(msg);
                break;
            default:
                logger.debug(`Unprocessed Config Message ${msg.toPacket()}`)
                break;
        }
    }
    private static processIntelliBrite(msg: Inbound) {
        //                        1        2             3            4           5           6           7           8
        //                        0  1 2 3 4  5  6  7   8   9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
        // [165,16,16,34,167,32],[9,32,0,0,7,32, 0, 0, 18, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 254]
        // [165,16,15,16, 39,32],[8, 0,0,0,9, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1,44]

        // [255,255,255,255,255,255,255,0,255,165,1,15,16,39,25,2,255,129,45,127,215,235,250,203,251,249,128]

        /* IntelliTouch does NOT notify the controllers when something is deleted.
            Thus, we must keep track of all current items and delete/re-init them every time.
            The IntelliBrite Collection does that and we will wipe clean all IntelliBrite/Circuit relationships and re-establish each time the packet(s) are resent.  */
        let byte: number; // which byte are we starting with?
        msg.datalen === 25 ? byte = 1 : byte = 0;
        // sys.intellibrite.isActive = true;
        let lg = sys.lightGroups.getItemById(sys.board.equipmentIds.circuitGroups.start, true);
        let sgrp = state.lightGroups.getItemById(sys.board.equipmentIds.circuitGroups.start, true);
        lg.isActive = sgrp.isActive = true;
        lg.name = sgrp.name = 'Intellibrite';
        lg.type = sgrp.type = 3;
        sgrp.action = 0;
        if ((msg.datalen === 25 && msg.extractPayloadByte(0) === 0) || msg.datalen === 32) {
            for (let i = 0; i < lg.circuits.length; i++) {
                let lgCircuit = lg.circuits.getItemByIndex(i);
                lgCircuit.isActive = false;
            }
        }
        for (byte; byte <= msg.datalen; byte = byte + 4) {
            let circuitId = msg.extractPayloadByte(byte);
            if (circuitId > 0) {
                let pair = msg.extractPayloadByte(byte + 1);
                let _isActive = circuitId > 0 && pair > 0;
                if (_isActive) {
                    const lgCircuit = lg.circuits.getItemByCircuitId(circuitId, _isActive);
                    lgCircuit.isActive = _isActive;
                    lgCircuit.circuit = circuitId;
                    lgCircuit.position = (pair >> 4) + 1;
                    lgCircuit.color = pair & 15;
                    lgCircuit.swimDelay = msg.extractPayloadByte(byte + 2) >> 1;
                }
            }
        }
        // go through and clean up what is not active only if this is the last (or only) packet
        if ((msg.datalen === 25 && msg.extractPayloadByte(0) === 1) || msg.datalen === 32)
            for (let idx = 0; idx < lg.circuits.length; idx++) {
                const lgCircuit = lg.circuits.getItemByIndex(idx);
                if (lgCircuit.isActive === true) continue;
                lg.circuits.removeItemById(lgCircuit.circuit);<commit_msg>Initialized the lighting theme when the Intellibrite group is created for Touch.<commit_after>/*  nodejs-poolController.  An application to control pool equipment.
Copyright (C) 2016, 2017, 2018, 2019, 2020.  <NAME>, tagyoureit.  <EMAIL>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
import { Inbound } from "../Messages";
import { sys, Body, Circuit, ICircuit } from "../../../Equipment";
import { state, BodyTempState } from "../../../State";
import { logger } from "../../../../logger/Logger";

export class CircuitMessage {
    public static processTouch(msg: Inbound): void {
        switch (msg.action) {
            case 11: // IntelliTouch Circuits
                CircuitMessage.processCircuitAttributes(msg);
                break;
            case 39: // IntelliTouch Light Groups
            case 167:
                CircuitMessage.processIntelliBrite(msg);
                break;
            default:
                logger.debug(`Unprocessed Message ${msg.toPacket()}`)
                break;
        }
    }
    public static processIntelliCenter(msg: Inbound) {
        switch (msg.extractPayloadByte(1)) {
            case 0: // Circuit Type
                CircuitMessage.processCircuitTypes(msg);
                break;
            case 1: // Freeze
                CircuitMessage.processFreezeProtect(msg);
                break;
            case 2: // Show in features
                CircuitMessage.processShowInFeatures(msg);
                break;
            case 3: // Circuit Names
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            case 21:
            case 22:
            case 23:
            case 24:
                CircuitMessage.processCircuitNames(msg);
                break;
            case 25: // Not sure what this is.
                break;
            case 26:
                CircuitMessage.processLightingTheme(msg);
                break;
            case 27:
                CircuitMessage.processEggTimerHours(msg);
                break;
            case 28:
                CircuitMessage.processEggTimerMinutes(msg);
                break;
            case 29:
                CircuitMessage.processDontStop(msg);
                break;
            default:
                logger.debug(`Unprocessed Config Message ${msg.toPacket()}`)
                break;
        }
    }
    private static processIntelliBrite(msg: Inbound) {
        //                        1        2             3            4           5           6           7           8
        //                        0  1 2 3 4  5  6  7   8   9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
        // [165,16,16,34,167,32],[9,32,0,0,7,32, 0, 0, 18, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 254]
        // [165,16,15,16, 39,32],[8, 0,0,0,9, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1,44]

        // [255,255,255,255,255,255,255,0,255,165,1,15,16,39,25,2,255,129,45,127,215,235,250,203,251,249,128]

        /* IntelliTouch does NOT notify the controllers when something is deleted.
            Thus, we must keep track of all current items and delete/re-init them every time.
            The IntelliBrite Collection does that and we will wipe clean all IntelliBrite/Circuit relationships and re-establish each time the packet(s) are resent.  */
        let byte: number; // which byte are we starting with?
        msg.datalen === 25 ? byte = 1 : byte = 0;
        // sys.intellibrite.isActive = true;
        let lg = sys.lightGroups.getItemById(sys.board.equipmentIds.circuitGroups.start, true);
        let sgrp = state.lightGroups.getItemById(sys.board.equipmentIds.circuitGroups.start, true);
        lg.isActive = sgrp.isActive = true;
        lg.name = sgrp.name = 'Intellibrite';
        lg.type = sgrp.type = 3;
        sgrp.action = 0;
        if (typeof lg.lightingTheme === 'undefined') lg.lightingTheme = 0;
        sgrp.lightingTheme = lg.lightingTheme;
        if ((msg.datalen === 25 && msg.extractPayloadByte(0) === 0) || msg.datalen === 32) {
            for (let i = 0; i < lg.circuits.length; i++) {
                let lgCircuit = lg.circuits.getItemByIndex(i);
                lgCircuit.isActive = false;
            }
        }
        for (byte; byte <= msg.datalen; byte = byte + 4) {
            let circuitId = msg.extractPayloadByte(byte);
            if (circuitId > 0) {
                let pair = msg.extractPayloadByte(byte + 1);
                let _isActive = circuitId > 0 && pair > 0;
                if (_isActive) {
                    const lgCircuit = lg.circuits.getItemByCircuitId(circuitId, _isActive);
                    lgCircuit.isActive = _isActive;
                    lgCircuit.circuit = circuitId;
                    lgCircuit.position = (pair >> 4) + 1;
                    lgCircuit.color = pair & 15;
                    lgCircuit.swimDelay = msg.extractPayloadByte(byte + 2) >> 1;
                }
            }
        }
        // go through and clean up what is not active only if this is the last (or only) packet
        if ((msg.datalen === 25 && msg.extractPayloadByte(0) === 1) || msg.datalen === 32)
            for (let idx = 0; idx < lg.circuits.length; idx++) {
                const lgCircuit = lg.circuits.getItemByIndex(idx);
                if (lgCircuit.isActive === true) continue;
                lg.circuits.removeItemById(lgCircuit.circuit);
{'fraction_non_alphanumeric': 0.10266677344438216, 'fraction_numerical': 0.05517738447985905, 'mean_word_length': 1.620226605119597, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4147088', 'n_tokens_mistral': 4234, 'n_tokens_neox': 3508, 'n_words': 1138}