UNPKG

homebridge-samsung-airconditioner-8888

Version:

node.js plugin for the Samsung smart samsung-airconditioners

280 lines (243 loc) 10.1 kB
var Service, Characteristic; var fs = require('fs'); var path = require('path'); const https = require('https'); const axios = require('axios'); const tls = require('tls'); // this is here until https://github.com/nodejs/node/issues/36655 is fixed const origCreateSecureContext = tls.createSecureContext; tls.createSecureContext = function(options) { if (!options.cert || !options.key || !options.ca) { return origCreateSecureContext(options); } let lessOptions = { ...options }; delete lessOptions.key; delete lessOptions.cert; delete lessOptions.ca; let ctx = origCreateSecureContext(lessOptions); ctx.context.setCert(options.cert); ctx.context.setKey(options.key, undefined); ctx.context.addCACert(options.ca); return ctx; }; module.exports = function (homebridge) { Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic; Accessory = homebridge.hap.Accessory; //UUIDGen = homebridge.hap.uuid; homebridge.registerAccessory("homebridge-samsung-airconditioner", "SamsungAirconditioner", SamsungAirco); }; function SamsungAirco(log, config) { this.log = log; this.name = config["name"]; this.ip = config["ip"]; this.token = config["token"]; this.accessoryName = config["name"]; this.setOn = true; this.setOff = false; this.httpClient = axios.create({ httpsAgent: new https.Agent({ rejectUnauthorized: false, cert: fs.readFileSync(path.join(__dirname, 'ac14k_m.pem')), key: fs.readFileSync(path.join(__dirname, 'ac14k_m.key')), ca: fs.readFileSync(path.join(__dirname, 'ca.pem')), ciphers: "DEFAULT:@SECLEVEL=0", minVersion: "TLSv1" }), headers: { 'Authorization': 'Bearer ' + this.token, } }); } SamsungAirco.prototype = { identify: function (callback) { this.log("Identify the clima!"); callback(); // success }, execGetRequest: function (url, callback) { this.httpClient.get('https://' + this.ip + ':8888' + url).then(callback) }, execPutRequest: function (url, data, callback) { this.httpClient.put('https://' + this.ip + ':8888' + url, data).then(callback) }, execPostRequest: function (url, data, callback) { this.httpClient.post('https://' + this.ip + ':8888' + url, data).then(callback) }, getServices: function () { //var uuid; //uuid = UUIDGen.generate(this.accessoryName); this.aircoSamsung = new Service.HeaterCooler(this.name); this.aircoSamsung.getCharacteristic(Characteristic.Active).on('get', this.getActive.bind(this)).on('set', this.setActive.bind(this)); //On or Off this.aircoSamsung.getCharacteristic(Characteristic.CurrentTemperature) .setProps({ minValue: -20, maxValue: 100, minStep: 0.1 }) .on('get', this.getCurrentTemperature.bind(this)); this.aircoSamsung.getCharacteristic(Characteristic.TargetHeaterCoolerState).on('get', this.getMode.bind(this)).on('set', this.setMode.bind(this)); this.aircoSamsung.getCharacteristic(Characteristic.CurrentHeaterCoolerState) .on('get', this.getCurrentHeaterCoolerState.bind(this)); this.aircoSamsung.getCharacteristic(Characteristic.HeatingThresholdTemperature) .setProps({ minValue: 16, maxValue: 30, minStep: 1 }) .on('get', this.getDesiredTemperature.bind(this)) .on('set', this.setDesiredTemperature.bind(this)); var informationService = new Service.AccessoryInformation(); return [informationService, this.aircoSamsung]; }, //services getDesiredTemperature: function (callback) { this.execGetRequest('/devices/0/temperatures/0', function (response) { if (response.status >= 200 && response.status < 300) { let res = response.data; callback(null, res.Temperature.desired); } else { this.log('getDesiredTemperature function failed', response); callback(response); } }.bind(this)) }, setDesiredTemperature: function (temp, callback) { this.execPutRequest('/devices/0/temperatures/0', {desired: temp}, function (response) { if (response.status >= 200 && response.status < 300) { callback(null, temp); } else { this.log('setDesiredTemperature function failed', response); callback(response); } }.bind(this)) }, getCurrentHeaterCoolerState: function (callback) { this.execGetRequest('/devices/0/mode', function (response) { if (response.status >= 200 && response.status < 300) { let res = response.data; switch (res.Mode.modes[0]) { case "Cool": callback(null, Characteristic.CurrentHeaterCoolerState.COOLING); break; case "Heat": callback(null, Characteristic.CurrentHeaterCoolerState.HEATING); break; case "Fan": callback(null, Characteristic.CurrentHeaterCoolerState.OFF); break; case "Wind": callback(null, Characteristic.CurrentHeaterCoolerState.OFF); break; case "Dry": callback(null, Characteristic.CurrentHeaterCoolerState.OFF); break; case "Auto": callback(null, Characteristic.CurrentHeaterCoolerState.AUTO); break; default: callback(null, Characteristic.CurrentHeaterCoolerState.OFF); break; } } else { this.log('getCurrentHeaterCoolerState function failed', response); callback(response); } }.bind(this)) }, getCurrentTemperature: function (callback) { this.execGetRequest('/devices/0/temperatures/0', function (response) { if (response.status >= 200 && response.status < 300) { let res = response.data; callback(null, res.Temperature.current); } else { this.log('getCurrentTemperature function failed', response); callback(response); } }.bind(this)) }, getActive: function (callback) { this.execGetRequest('/devices/0/operation', function (response) { if (response.status >= 200 && response.status < 300) { let res = response.data; if (res.Operation.power == "On") { callback(null, Characteristic.Active.ACTIVE); } else { callback(null, Characteristic.Active.INACTIVE); } } else { this.log('getActive function failed', response); callback(response); } }.bind(this)) }, setActive: function (state, callback) { this.execPutRequest('/devices/0', {"Operation": {power: state == Characteristic.Active.ACTIVE ? "On" : "Off"}}, function (response) { if (response.status >= 200 && response.status < 300) { callback(); } else { this.log('setActive function failed', response); callback(response); } }.bind(this)) }, setPowerState: function (powerOn, callback) { this.execPutRequest('/devices/0', {"Operation": {power: powerOn ? "On" : "Off"}}, function (response) { if (response.status >= 200 && response.status < 300) { callback(); } else { this.log('setActive function failed', response); callback(response); } }.bind(this)) }, getMode: function (callback) { this.execGetRequest('/devices/0/mode', function (response) { if (response.status >= 200 && response.status < 300) { let res = response.data; var mode = Characteristic.TargetHeaterCoolerState.AUTO; switch (res.Mode.modes[0]) { case "Cool": mode = Characteristic.TargetHeaterCoolerState.COOL; break; case "Heat": mode = Characteristic.TargetHeaterCoolerState.HEAT; break; case "Fan": case "Wind": case "Dry": case "Auto": default: mode = Characteristic.TargetHeaterCoolerState.AUTO; break; } callback(null, mode); } else { this.log('getMode function failed', response); callback(response); } }.bind(this)); }, setMode: function (state, callback) { var mode; switch (state) { case Characteristic.TargetHeaterCoolerState.COOL: mode = "Cool"; break; case Characteristic.TargetHeaterCoolerState.HEAT: mode = "Heat"; break; case Characteristic.TargetHeaterCoolerState.AUTO: mode = "Auto"; break; } this.execPutRequest('/devices/0/mode', {modes: [mode]}, function (response) { if (response.status >= 200 && response.status < 300) { callback(); } else { this.log('setMode function failed', response); callback(response); } }.bind(this)); } };