modular approach, add reconnect
This commit is contained in:
120
src/devicebase.js
Normal file
120
src/devicebase.js
Normal file
@@ -0,0 +1,120 @@
|
||||
|
||||
const TuyaDevice = require('tuyapi');
|
||||
const log4js = require('log4js');
|
||||
|
||||
class DeviceBase {
|
||||
constructor(deviceconfig, mqtt) {
|
||||
// setup logger
|
||||
const loggername = deviceconfig.id ? deviceconfig.id : "undef device"
|
||||
this.logger = log4js.getLogger(loggername);
|
||||
this.logger.level = deviceconfig.loglevel;
|
||||
// check device attributes
|
||||
if (!deviceconfig.id) {
|
||||
this.logger.error("missing attribute 'id' in device config")
|
||||
return
|
||||
}
|
||||
if (!deviceconfig.key) {
|
||||
this.logger.error("missing attribute 'key' in device config")
|
||||
return
|
||||
}
|
||||
if (!deviceconfig.topic) {
|
||||
this.logger.error("missing attribute 'topic' in device config")
|
||||
return
|
||||
}
|
||||
// define device vars
|
||||
this.mqtt = mqtt
|
||||
this.topicname = deviceconfig.topic
|
||||
this.deviceid = deviceconfig.id
|
||||
this.devicekey = deviceconfig.key
|
||||
|
||||
this.topic_get = `${deviceconfig.topic}/get`
|
||||
this.topic_set = `${deviceconfig.topic}/set`
|
||||
this.topic_state = `${deviceconfig.topic}/state`
|
||||
|
||||
this.logger.debug(`use topic (all) : ${this.topicname}`)
|
||||
this.logger.debug(`use topic (get) : ${this.topic_get}`)
|
||||
this.logger.debug(`use topic (set) : ${this.topic_set}`)
|
||||
this.logger.debug(`use topic (state) : ${this.topic_state}`)
|
||||
|
||||
this.intervall_refresh = deviceconfig.refresh ? deviceconfig.refresh * 1000 : 10000
|
||||
this.reconnect_timout = deviceconfig.reconnect ? deviceconfig.reconnect * 1000 : 5000
|
||||
|
||||
this.logger.debug(`refresh timer (ms) : ${this.intervall_refresh}`)
|
||||
this.logger.debug(`reconnect timer (ms) : ${this.reconnect_timout}`)
|
||||
|
||||
this.lastdata = {}
|
||||
// call init function
|
||||
this.init()
|
||||
|
||||
// connect to device
|
||||
try {
|
||||
this.device = new TuyaDevice({
|
||||
id: this.deviceid,
|
||||
key: this.devicekey,
|
||||
issueRefreshOnConnect: true,
|
||||
})
|
||||
this.reconnect()
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error(`Cannot connect to ${this.deviceid}`)
|
||||
this.logger.error(error.message)
|
||||
}
|
||||
|
||||
this.device.on('connected', () => {
|
||||
this.connected = true
|
||||
this.logger.info(`Connected to tuya id: ${this.deviceid}, ip: ${this.device.device.ip}, prefix: ${this.topicname}`)
|
||||
this.startWatcher()
|
||||
// subscribe to topic
|
||||
this.mqtt.subscribe(this.topic_set, (err) => {
|
||||
if (err) {
|
||||
this.logger.error(`Cannot subscribe to ${this.topic_set}`)
|
||||
} else {
|
||||
this.logger.info(`Subscribed to ${this.topic_set}`)
|
||||
}
|
||||
});
|
||||
this.logger.debug(`publish ${this.totopic_statepic_get}: "online"`)
|
||||
this.mqtt.publish(this.topic_state, "online")
|
||||
});
|
||||
|
||||
this.device.on('disconnected', () => {
|
||||
clearInterval(this.timer)
|
||||
this.logger.info(`Disconnected`)
|
||||
this.logger.debug(`publish ${this.topic_state}: "offline"`)
|
||||
this.mqtt.publish(this.topic_state, "offline")
|
||||
setTimeout(() => this.reconnect(), this.reconnect_timout)
|
||||
this.device.device.ip = undefined // will error without? WHY???
|
||||
});
|
||||
|
||||
this.device.on('error', error => {
|
||||
clearInterval(this.timer)
|
||||
this.logger.debug(`publish ${this.topic_state}: "offline"`)
|
||||
this.mqtt.publish(this.topic_state, "offline")
|
||||
setTimeout(() => this.reconnect(), this.reconnect_timout)
|
||||
});
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
this.device.find().then(el => {
|
||||
if (el) {
|
||||
this.device.connect()
|
||||
} else {
|
||||
this.logger.debug("Reconnect failed: device offline")
|
||||
setTimeout(() => this.reconnect(), this.reconnect_timout)
|
||||
}
|
||||
}).catch(el => {
|
||||
this.logger.debug("Reconnect failed: device timed out")
|
||||
setTimeout(() => this.reconnect(), this.reconnect_timout)
|
||||
})
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.connected = false
|
||||
clearInterval(this.timer)
|
||||
this.device.disconnect()
|
||||
this.logger.info(`Disconnected for id: ${this.deviceid}`)
|
||||
this.reconnect = () => {} // prevent reconnect on exit
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = DeviceBase
|
||||
Reference in New Issue
Block a user