homebridge-434mhz-flamingo
Version:
Support for Flamingo SF-501 433,92 MHz RF Outlets.
143 lines (108 loc) • 5.91 kB
JavaScript
"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)
}