UNPKG

homebridge-434mhz-flamingo

Version:

Support for Flamingo SF-501 433,92 MHz RF Outlets.

143 lines (108 loc) 5.91 kB
"use strict"; var Service, Characteristic, HomebridgeAPI, q; const Pulse = obj => [ obj.gpioOn !== 0 ? 1 : 0, obj.gpioOff !== 0 ? 1 : 0, obj.usDelay ]; const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); const logger = { info: console.log, error: console.error }; try { var couldLaunchPigpiod = false; const waves = {}; const pigpio = require('pigpio-client').pigpio({ host: 'localhost', timeout: 5 }); const ready = (new Promise((resolve, reject) => { pigpio.once('connected', _ => { logger.info("successfully connected to pigpiod."); resolve() }); pigpio.once('error', _ => { logger.error("could not connect to pigpiod."); reject() }); })) .then(async function() { let pq = await import('p-queue'); q = new pq.default({ concurrency: 1 }); }) .then((async function () { this.txPin = pigpio.gpio(17); await this.txPin.modeSet('output') await this.txPin.waveClear(); /* Pulses for auto-paring Switch Units without DIP-Switches */ var autoHigh = { gpioOn: this.txPin, gpioOff: 0, usDelay: 230 }; var autoLowShort = { gpioOn: 0, gpioOff: this.txPin, usDelay: 314 }; var autoLowLong = { gpioOn: 0, gpioOff: this.txPin, usDelay: 1256 }; /* Pulses for manual-pairing Switch Units with DIP-Switches */ var manualHighShort = { gpioOn: this.txPin, gpioOff: 0, usDelay: 300 }; var manualHighLong = { gpioOn: this.txPin, gpioOff: 0, usDelay: 300*3 }; var manualLowShort = { gpioOn: 0, gpioOff: this.txPin, usDelay: 300 }; var manualLowLong = { gpioOn: 0, gpioOff: this.txPin, usDelay: 300*3 }; /* Waves for auto-paring Switch Units without DIP-Switches */ await this.txPin.waveAddPulse([ Pulse({ gpioOn: this.txPin, gpioOff: 0, usDelay: 225 }), Pulse({ gpioOn: 0, gpioOff: this.txPin, usDelay: 2512 }) ]); this.autoAmble = await this.txPin.waveCreate(); await this.txPin.waveAddPulse([ Pulse(autoHigh), Pulse(autoLowShort), Pulse(autoHigh), Pulse(autoLowLong) ]); this.autoBit0 = await this.txPin.waveCreate(); await this.txPin.waveAddPulse([ Pulse(autoHigh), Pulse(autoLowLong), Pulse(autoHigh), Pulse(autoLowShort) ]); this.autoBit1 = await this.txPin.waveCreate(); await this.txPin.waveAddPulse([ Pulse({ gpioOn: this.txPin, gpioOff: 0, usDelay: 314 }), Pulse({ gpioOn: 0, gpioOff: this.txPin, usDelay: 10676 }) ]); this.autoGap = await this.txPin.waveCreate(); }).bind(waves)) .then(_=> couldLaunchPigpiod = true) .catch(error => logger.error("An error occured during initialization: " + error)); module.exports = function(homebridge) { Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic; HomebridgeAPI = homebridge; homebridge.registerAccessory("homebridge-434mhz-flamingo", "FlamingoOutlet", FlamingoOutlet); } function FlamingoOutlet(log, config) { this.log = log; this.name = config.name; this.remoteID = config.remoteID; this.txPinNumber = config.pin; this._service = new Service.Outlet(this.name); this.cacheDirectory = HomebridgeAPI.user.persistPath(); this.storage = require('node-persist'); this.storage.initSync({ dir:this.cacheDirectory, forgiveParseErrors: true }); this._service.getCharacteristic(Characteristic.On) .on('set', this._setOn.bind(this)); var cachedState = this.storage.getItemSync(this.name); if((cachedState === undefined) || (cachedState === false)) { this._service.setCharacteristic(Characteristic.On, false); } else { this._service.setCharacteristic(Characteristic.On, true); } } FlamingoOutlet.prototype.getServices = function() { return [this._service]; } FlamingoOutlet.prototype._setOn = function(on, callback) { if (!couldLaunchPigpiod) return; try { var command = [false, false, false, false, false, false, false, false, false, false, false, on, false, false, false, true]; var remoteIDBitString = (this.remoteID >>> 0).toString(2); let bitsToSend = remoteIDBitString .padStart(16, "0") .split('') .map(k => k == "1" ? true : false) .concat(command); var bits = []; q.add((function () { return ready.then(async () => { for (var i in bitsToSend) { bits.push(bitsToSend[i] ? waves.autoBit1 : waves.autoBit0); } await waves.txPin.waveNotBusy(); var chain = [waves.autoAmble].concat(bits).concat([waves.autoGap]); this.storage.setItemSync(this.name, on); waves.txPin.waveChainTx([ {loop: true}, {waves: chain}, {repeat: 7} ]); await wait(500); //callback(); // await led.waveTxStop(); }) }).bind(this)) .then(_ => callback()) .catch(error => this.log.error(error, this.name)); } catch(error) { this.log.error(error, this.name) } } } catch(error) { logger.error("An error occured during initialization: " + error) }