Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var logger = require('../../utils/logger').light;
- var request = require('request');
- var net = require('net');
- var LightState = require('../../model/light-state');
- var LightColor = require('../../model/light-color');
- var config = require('../../config');
- "use strict";
- const HexValues = {
- TRUE: 0xf0, // 0xf0
- FALSE: 0x0f, // 0x0f
- ON: 0x23, // 0x23
- OFF: 0x24, // 0x24
- LOCAL: 0x0f, // command received locally
- REMOTE: 0xf0, // command received remotely
- RGBCHANGE: 0xf0, // changing rgb values
- WCHANGE: 0x0f // changing w values
- }
- const CommandValues = {
- GetState1: 0x81,
- GetState2: 0x8a,
- GetState3: 0x8b,
- SetPower: 0x71,
- SetColor: 0x31
- }
- module.exports = {
- port: config.zengge.port,
- /**
- * Sets the color to the given value on the specified IP.
- *
- * @param ip - IP of the controller
- * @param color - color object
- */
- setColor(ip, color) {
- var self = this;
- self._checkIfIpIsPresent(ip);
- return new Promise(function (resolve, reject) {
- let baseCommand = [CommandValues.SetColor];
- let commandArray = baseCommand.concat(color.toCommandArray(HexValues.TRUE, HexValues.FALSE));
- // status sign: 0xF0 - changing rgb, 0x0f changing w value
- commandArray.push(HexValues.RGBCHANGE);
- // setting remote (0xf0) or local command value (0x0f)
- commandArray.push(HexValues.LOCAL);
- // calculating and appending checksum
- commandArray.push(self._calculate1ByteChecksum(commandArray));
- if (config.dev.emulatelights) {
- // device in emulation mode, no need to signal light controller
- resolve();
- return;
- }
- var client = new net.Socket();
- client.connect(self.port, ip, function () {
- logger.debug('Connected to TCP on IP \'' + ip + '\'.');
- logger.info('Changing color to [ R: ' + color.r + ' G: ' + color.g + ' B: ' + color.b + '] on IP: \'' + ip + '\'.');
- client.write(new Buffer(commandArray));
- // destroying client immediately. no response is expected...
- client.destroy();
- resolve();
- });
- client.on('error', function (error) {
- logger.error('Error while connecting to client. ' + error.toString());
- logger.error(error);
- reject(error);
- });
- client.on('close', function () {
- logger.debug('TCP connection closed on IP \'' + ip + '\'.');
- });
- });
- },
- /**
- * Gets the current state of the light on the given IP.
- *
- * @param ip - IP of the controller
- */
- getCurrentState(ip) {
- var self = this;
- self._checkIfIpIsPresent(ip);
- return new Promise(function (resolve, reject) {
- let commandArray = [CommandValues.GetState1, CommandValues.GetState2, CommandValues.GetState3];
- // calculating checksum...
- commandArray.push(self._calculate1ByteChecksum(commandArray));
- let hexString = Buffer.from(commandArray).toString('hex');
- if (config.dev.emulatelights) {
- if (config.dev.lightsoffline) {
- resolve({
- offline: true
- });
- return;
- }
- var testResponse = "814423612101fefb8a000400f0e2";
- let state = self.parseState(self._chopStringIntoPieces(testResponse, 2));
- // device in emulation mode, no need to signal light controller
- resolve(state);
- return;
- }
- var client = new net.Socket();
- client.connect(self.port, ip, function () {
- logger.debug('Connected to TCP on IP \'' + ip + '\'.');
- client.write(new Buffer(commandArray));
- });
- client.on('data', function (response) {
- let responseString = "";
- for (let i = 0; i < response.length; i++) {
- let byte = response[i];
- let hexChar = byte.toString(16); // convert the decimal 'byte' to hex string;
- if (hexChar.length == 1) {
- hexChar = '0' + hexChar;
- }
- responseString += hexChar;
- }
- logger.debug('Received: ' + responseString);
- var data = self._chopStringIntoPieces(responseString, 2);
- var state = self.parseState(data);
- logger.debug(state);
- client.destroy();
- resolve(state);
- });
- client.on('error', function (error) {
- logger.error('Error occured while getting current light state: ' + error.toString());
- logger.error(error);
- resolve({
- offline: true
- });
- });
- client.on('close', function () {
- logger.debug('TCP connection closed on IP \'' + ip + '\'.');
- });
- });
- },
- /**
- * Power on the light controller.
- *
- * @param ip - IP of the controller
- */
- powerOn(ip) {
- return this._powerOnOff(ip, true);
- },
- /**
- * Power off the light controller.
- *
- * @param ip - IP of the controller
- */
- powerOff(ip) {
- return this._powerOnOff(ip, false);
- },
- /**
- * Powers the controller on or off.
- *
- * @param ip - IP of the controller
- * @param on - bool value indicating of it should be turned on or off
- */
- _powerOnOff(ip, on) {
- var self = this;
- self._checkIfIpIsPresent(ip);
- return new Promise(function (resolve, reject) {
- let commandArray = [CommandValues.SetPower];
- if (on) {
- commandArray.push(HexValues.ON);
- } else {
- commandArray.push(HexValues.OFF);
- }
- // we are modifying from local address
- commandArray.push(HexValues.LOCAL);
- commandArray.push(self._calculate1ByteChecksum(commandArray));
- if (config.dev.emulatelights) {
- // device in emulation mode, no need to signal light controller
- resolve();
- return;
- }
- var client = new net.Socket();
- client.connect(self.port, ip, function () {
- logger.debug('Connected to TCP on IP \'' + ip + '\'.');
- logger.info('Powering the device ' + (on ? 'ON' : 'OFF') + '.');
- client.write(new Buffer(commandArray));
- client.destroy();
- resolve();
- });
- client.on('error', function (error) {
- logger.error('Error occured while chaning power state: ' + error.toString());
- logger.error(error);
- reject();
- });
- client.on('close', function () {
- logger.debug('TCP connection closed on IP \'' + ip + '\'.');
- });
- });
- },
- /**
- * Parses state data received from the zengge controller.
- *
- * @param data - received state data (should be string)
- */
- parseState(data) {
- return new LightState({
- // data[0] - always 0x81 (command id)
- deviceType: data[1],
- isOn: parseInt('0x' + data[2]) == HexValues.ON,
- mode: data[3],
- // data[4] - always 0x33
- speed: data[5],
- ledVersion: data[10]
- }, this.parseColor({
- r: data[6],
- g: data[7],
- b: data[8],
- ww: data[9],
- cw: data[11],
- status: data[12]
- }));
- },
- /**
- * Parses color data received form the zenge controller.
- *
- * @param rgbw - rgbw color value
- * @param ignoreW - bool value deciding if w value should be ignored
- * @returns LightColor
- */
- parseColor(rgbww) {
- return new LightColor(rgbww, true /* parameters are hex values */ );
- },
- /**
- * Calculates a one byte checsum from the array of values.
- *
- * @param data - values to be sent
- * @returns - 1 byte checksum
- */
- _calculate1ByteChecksum(data) {
- var hash = new Uint8Array(1);
- for (var i = 0; i < data.length; i++) {
- hash[0] += data[i];
- }
- return hash[0];
- },
- /**
- * Chops the given string into 'length' size pieces.
- *
- * @param string - string to chop up
- * @param length - size of the string pieces
- * @returns arrays of string pieces
- */
- _chopStringIntoPieces(string, length) {
- return string.match(new RegExp('.{1,' + length + '}', 'g'));
- },
- /**
- * Checks if the input IP parameter is present and in a correct format.
- *
- * @param ip - input IP address
- */
- _checkIfIpIsPresent(ip) {
- if (!ip) {
- throw new Error('[LIGHT-MANAGER] IP parameter is required for the light-manager methods.');
- }
- 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]?)$/;
- if (!ipRegex.test(ip)) {
- throw new Error('[ERROR] [LIGHT-MANAGER] IP parameter \'' + ip + '\' is invalid.');
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement