homebridge-dht-rgpio
Version:
DHTxx temperature/humidity sensor plugin using remote GPIO
138 lines (119 loc) • 4.67 kB
JavaScript
'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]
}
}