UNPKG

homebridge-dht-rgpio

Version:

DHTxx temperature/humidity sensor plugin using remote GPIO

138 lines (119 loc) 4.67 kB
'use strict'; var debug = require('debug')('DHTxx'); const moment = require('moment'); var os = require("os"); const delay = millis => new Promise(resolve => setTimeout(resolve, millis)); const fixed2 = number => (Math.round(number * 100) / 100).toFixed(2); const round1 = number => Math.round(number * 10) / 10; let Service, Characteristic; var FakeGatoHistoryService; module.exports = (homebridge) => { Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic; FakeGatoHistoryService = require('fakegato-history')(homebridge); homebridge.registerAccessory('homebridge-dht-rgpio', 'DHTxx', DHTXXPlugin); }; class DHTXXPlugin { constructor(log, config) { debug('Debug enabled'); this.log = log; this.name = config.name; this.loglevel= config.loglevel || 0; this.gpiochip= config.gpiochip || 0; this.gpio = config.gpio || 4; this.hostname = config.hostname || 'localhost' this.name_temperature = config.name_temperature || `dht-${this.hostname}-${this.gpiochip}-${this.gpio}-temperature`; this.name_humidity = config.name_humidity || `dht-${this.hostname}-${this.gpiochip}-${this.gpio}-humidity`; this.refresh = config.refresh || 30; // Update every 30 seconds if (config['recordpath']) { this.recording = { size: 14400, storage: 'fs', path: config.recordpath } if (this.loglevel > 0) { this.log(`Recording to: ${this.recording.path}/homebridge_${this.name_temperature}_persist.json`); } } else { this.recording = {}; if (this.loglevel > 0) { this.log("Not Recording"); } } this.init = false; this.data = {}; this.informationService = new Service.AccessoryInformation(); this.informationService .setCharacteristic(Characteristic.Manufacturer, "Asair") .setCharacteristic(Characteristic.Model, "DHTxx") .setCharacteristic(Characteristic.SerialNumber, this.hostname + "-dht-" + this.gpiochip + "-" + this.gpio) .setCharacteristic(Characteristic.FirmwareRevision, require('./package.json').version); this.temperatureService = new Service.TemperatureSensor(this.name_temperature); this.temperatureService .getCharacteristic(Characteristic.CurrentTemperature) .setProps({ minValue: -100, maxValue: 100 }); this.humidityService = new Service.HumiditySensor(this.name_humidity); this.temperatureService.log = this.log; this.humidityService.log = this.log; this.loggingService = new FakeGatoHistoryService("weather", this.temperatureService, this.recording); setInterval(this.devicePolling.bind(this), this.refresh * 1000); } async readSensorData() { const sensorScriptFile = `${__dirname}/lib/DHT.py`; // eslint-disable-next-line @typescript-eslint/no-var-requires const spawn = require('child_process').spawn; const process = spawn('/usr/bin/env', ['python3', sensorScriptFile, "--hostname", this.hostname, "-c", this.gpiochip, this.gpio]); return new Promise((resolve, reject) => { process.stdout.on('data', data => { try { resolve(JSON.parse(data.toString())); } catch (err) { reject(err.toString()); } }); process.stderr.on('data', err => { reject(err.toString()); }); }); } devicePolling() { this.readSensorData() .then(data => { if (data.status == 0) { if (this.loglevel > 1) { this.log(`${fixed2(data.temperature)}°C, ` + `${fixed2(data.humidity)}%`); } this.loggingService.addEntry({ time: moment().unix(), temp: round1(data.temperature), humidity: round1(data.humidity) }); this.temperatureService .setCharacteristic(Characteristic.CurrentTemperature, round1(data.temperature)); this.humidityService .setCharacteristic(Characteristic.CurrentRelativeHumidity, round1(data.humidity)); } else { if (this.loglevel > 0) { if ("gpio" in data) this.log(`Error (gpio ${data.gpio}): ${data.msg}`); else this.log(`Error: ${data.msg}`); } } }) .catch(err => { this.log(`DHTXX read error: ${err}`); if (err.stack) { debug(`err.stack: ${err.stack}`) } }); } getServices() { return [this.informationService, this.temperatureService, this.humidityService, this.loggingService] } }