SHARE
TWEET

Untitled

a guest Jul 19th, 2019 70 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var logger = require('../../utils/logger').light;
  2. var request = require('request');
  3. var net = require('net');
  4.  
  5. var LightState = require('../../model/light-state');
  6. var LightColor = require('../../model/light-color');
  7. var config = require('../../config');
  8.  
  9. "use strict";
  10.  
  11. const HexValues = {
  12.     TRUE: 0xf0, // 0xf0
  13.     FALSE: 0x0f, // 0x0f
  14.     ON: 0x23, // 0x23
  15.     OFF: 0x24, // 0x24
  16.     LOCAL: 0x0f, // command received locally
  17.     REMOTE: 0xf0, // command received remotely
  18.     RGBCHANGE: 0xf0, // changing rgb values
  19.     WCHANGE: 0x0f // changing w values
  20. }
  21.  
  22. const CommandValues = {
  23.     GetState1: 0x81,
  24.     GetState2: 0x8a,
  25.     GetState3: 0x8b,
  26.     SetPower: 0x71,
  27.     SetColor: 0x31
  28. }
  29.  
  30. module.exports = {
  31.     port: config.zengge.port,
  32.  
  33.     /**
  34.      * Sets the color to the given value on the specified IP.
  35.      *
  36.      * @param ip - IP of the controller
  37.      * @param color - color object
  38.      */
  39.     setColor(ip, color) {
  40.         var self = this;
  41.         self._checkIfIpIsPresent(ip);
  42.  
  43.         return new Promise(function (resolve, reject) {
  44.             let baseCommand = [CommandValues.SetColor];
  45.  
  46.             let commandArray = baseCommand.concat(color.toCommandArray(HexValues.TRUE, HexValues.FALSE));
  47.  
  48.             // status sign: 0xF0 - changing rgb, 0x0f changing w value
  49.             commandArray.push(HexValues.RGBCHANGE);
  50.  
  51.             // setting remote (0xf0) or local command value (0x0f)
  52.             commandArray.push(HexValues.LOCAL);
  53.  
  54.             // calculating and appending checksum
  55.             commandArray.push(self._calculate1ByteChecksum(commandArray));
  56.  
  57.             if (config.dev.emulatelights) {
  58.                 // device in emulation mode, no need to signal light controller
  59.                 resolve();
  60.                 return;
  61.             }
  62.  
  63.             var client = new net.Socket();
  64.  
  65.             client.connect(self.port, ip, function () {
  66.                 logger.debug('Connected to TCP on IP \'' + ip + '\'.');
  67.                 logger.info('Changing color to [ R: ' + color.r + ' G: ' + color.g + ' B: ' + color.b + '] on IP: \'' + ip + '\'.');
  68.                 client.write(new Buffer(commandArray));
  69.  
  70.                 // destroying client immediately. no response is expected...
  71.                 client.destroy();
  72.                 resolve();
  73.             });
  74.  
  75.             client.on('error', function (error) {
  76.                 logger.error('Error while connecting to client. ' + error.toString());
  77.                 logger.error(error);
  78.                 reject(error);
  79.             });
  80.  
  81.             client.on('close', function () {
  82.                 logger.debug('TCP connection closed on IP \'' + ip + '\'.');
  83.             });
  84.         });
  85.     },
  86.  
  87.     /**
  88.      * Gets the current state of the light on the given IP.
  89.      *
  90.      * @param ip - IP of the controller
  91.      */
  92.     getCurrentState(ip) {
  93.         var self = this;
  94.         self._checkIfIpIsPresent(ip);
  95.  
  96.         return new Promise(function (resolve, reject) {
  97.  
  98.             let commandArray = [CommandValues.GetState1, CommandValues.GetState2, CommandValues.GetState3];
  99.             // calculating checksum...
  100.             commandArray.push(self._calculate1ByteChecksum(commandArray));
  101.             let hexString = Buffer.from(commandArray).toString('hex');
  102.  
  103.             if (config.dev.emulatelights) {
  104.                 if (config.dev.lightsoffline) {
  105.                     resolve({
  106.                         offline: true
  107.                     });
  108.                     return;
  109.                 }
  110.  
  111.                 var testResponse = "814423612101fefb8a000400f0e2";
  112.  
  113.                 let state = self.parseState(self._chopStringIntoPieces(testResponse, 2));
  114.  
  115.                 // device in emulation mode, no need to signal light controller
  116.                 resolve(state);
  117.                 return;
  118.             }
  119.  
  120.             var client = new net.Socket();
  121.  
  122.             client.connect(self.port, ip, function () {
  123.                 logger.debug('Connected to TCP on IP \'' + ip + '\'.');
  124.                 client.write(new Buffer(commandArray));
  125.             });
  126.  
  127.             client.on('data', function (response) {
  128.                 let responseString = "";
  129.  
  130.                 for (let i = 0; i < response.length; i++) {
  131.                     let byte = response[i];
  132.                     let hexChar = byte.toString(16); // convert the decimal 'byte' to hex string;
  133.  
  134.                     if (hexChar.length == 1) {
  135.                         hexChar = '0' + hexChar;
  136.                     }
  137.  
  138.                     responseString += hexChar;
  139.                 }
  140.  
  141.                 logger.debug('Received: ' + responseString);
  142.  
  143.                 var data = self._chopStringIntoPieces(responseString, 2);
  144.                 var state = self.parseState(data);
  145.                 logger.debug(state);
  146.  
  147.                 client.destroy();
  148.  
  149.                 resolve(state);
  150.             });
  151.  
  152.             client.on('error', function (error) {
  153.                 logger.error('Error occured while getting current light state: ' + error.toString());
  154.                 logger.error(error);
  155.                 resolve({
  156.                     offline: true
  157.                 });
  158.             });
  159.  
  160.             client.on('close', function () {
  161.                 logger.debug('TCP connection closed on IP \'' + ip + '\'.');
  162.             });
  163.         });
  164.     },
  165.  
  166.     /**
  167.      * Power on the light controller.
  168.      *
  169.      * @param ip - IP of the controller
  170.      */
  171.     powerOn(ip) {
  172.         return this._powerOnOff(ip, true);
  173.     },
  174.  
  175.     /**
  176.      * Power off the light controller.
  177.      *
  178.      * @param ip - IP of the controller
  179.      */
  180.     powerOff(ip) {
  181.         return this._powerOnOff(ip, false);
  182.     },
  183.  
  184.     /**
  185.      * Powers the controller on or off.
  186.      *
  187.      * @param ip - IP of the controller
  188.      * @param on - bool value indicating of it should be turned on or off
  189.      */
  190.     _powerOnOff(ip, on) {
  191.         var self = this;
  192.         self._checkIfIpIsPresent(ip);
  193.  
  194.         return new Promise(function (resolve, reject) {
  195.             let commandArray = [CommandValues.SetPower];
  196.  
  197.             if (on) {
  198.                 commandArray.push(HexValues.ON);
  199.             } else {
  200.                 commandArray.push(HexValues.OFF);
  201.             }
  202.  
  203.             // we are modifying from local address
  204.             commandArray.push(HexValues.LOCAL);
  205.  
  206.             commandArray.push(self._calculate1ByteChecksum(commandArray));
  207.  
  208.             if (config.dev.emulatelights) {
  209.                 // device in emulation mode, no need to signal light controller
  210.                 resolve();
  211.                 return;
  212.             }
  213.  
  214.             var client = new net.Socket();
  215.  
  216.             client.connect(self.port, ip, function () {
  217.                 logger.debug('Connected to TCP on IP \'' + ip + '\'.');
  218.                 logger.info('Powering the device ' + (on ? 'ON' : 'OFF') + '.');
  219.  
  220.                 client.write(new Buffer(commandArray));
  221.                 client.destroy();
  222.                 resolve();
  223.             });
  224.  
  225.             client.on('error', function (error) {
  226.                 logger.error('Error occured while chaning power state: ' + error.toString());
  227.                 logger.error(error);
  228.                 reject();
  229.             });
  230.  
  231.             client.on('close', function () {
  232.                 logger.debug('TCP connection closed on IP \'' + ip + '\'.');
  233.             });
  234.         });
  235.     },
  236.  
  237.     /**
  238.      * Parses state data received from the zengge controller.
  239.      *
  240.      * @param data - received state data (should be string)
  241.      */
  242.     parseState(data) {
  243.         return new LightState({
  244.             // data[0] - always 0x81 (command id)
  245.             deviceType: data[1],
  246.             isOn: parseInt('0x' + data[2]) == HexValues.ON,
  247.             mode: data[3],
  248.             // data[4] - always 0x33
  249.             speed: data[5],
  250.             ledVersion: data[10]
  251.         }, this.parseColor({
  252.             r: data[6],
  253.             g: data[7],
  254.             b: data[8],
  255.             ww: data[9],
  256.             cw: data[11],
  257.             status: data[12]
  258.         }));
  259.     },
  260.  
  261.     /**
  262.      * Parses color data received form the zenge controller.
  263.      *
  264.      * @param rgbw - rgbw color value
  265.      * @param ignoreW - bool value deciding if w value should be ignored
  266.      * @returns LightColor
  267.      */
  268.     parseColor(rgbww) {
  269.         return new LightColor(rgbww, true /* parameters are hex values */ );
  270.     },
  271.  
  272.     /**
  273.      * Calculates a one byte checsum from the array of values.
  274.      *
  275.      * @param data - values to be sent
  276.      * @returns - 1 byte checksum
  277.      */
  278.     _calculate1ByteChecksum(data) {
  279.         var hash = new Uint8Array(1);
  280.  
  281.         for (var i = 0; i < data.length; i++) {
  282.             hash[0] += data[i];
  283.         }
  284.  
  285.         return hash[0];
  286.     },
  287.  
  288.     /**
  289.      * Chops the given string into 'length' size pieces.
  290.      *
  291.      * @param string - string to chop up
  292.      * @param length - size of the string pieces
  293.      * @returns arrays of string pieces
  294.      */
  295.     _chopStringIntoPieces(string, length) {
  296.         return string.match(new RegExp('.{1,' + length + '}', 'g'));
  297.     },
  298.  
  299.     /**
  300.      * Checks if the input IP parameter is present and in a correct format.
  301.      *
  302.      * @param ip - input IP address
  303.      */
  304.     _checkIfIpIsPresent(ip) {
  305.         if (!ip) {
  306.             throw new Error('[LIGHT-MANAGER] IP parameter is required for the light-manager methods.');
  307.         }
  308.  
  309.         let ipRegex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  310.  
  311.         if (!ipRegex.test(ip)) {
  312.             throw new Error('[ERROR] [LIGHT-MANAGER] IP parameter \'' + ip + '\' is invalid.');
  313.         }
  314.     }
  315. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top