node-red-contrib-clowire
Version:
clowire for node-red
181 lines (136 loc) • 5.31 kB
JavaScript
module.exports = function (RED) {
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const tcpPort = require('./ha/tcp')
const handleTcp = require('./ha/handleTcp')
const { ClimateObjToSerivce, SwitchObjToSerivce } = require('./ha/toHaService')
let globalContext = null
const nodeStatus = {
yellow: { fill: "yellow", shape: "ring", text: "node-red:common.status.connecting" },
red: { fill: "red", shape: "ring", text: "node-red:common.status.disconnected" },
green: { fill: "green", shape: "dot", text: "node-red:common.status.connected" }
}
function clowireConfig(n) {
RED.nodes.createNode(this, n);
/**
* 克纶威尔连接
*/
globalContext = this.context().global
this.host = n.host || '127.0.0.1'
this.port = n.port || 8666
this.nodes = [] //设备实列
this.handleTcp = {
'hasskit': null,
'clowire': null,
'alive':null,
getObjToService: function(domain){
if(domain === 'climate')
return ClimateObjToSerivce
else
return SwitchObjToSerivce
}
}
//处理TCP对象集合
this.tcpClient = new tcpPort(this.host, this.port, this)
this.on('error', function (e) {
console.log(e)
})
//this.BoardTcp = new BoardTcp(this.tcpClient)
this.repeatSend = 0
let self = this
this.on('close', function (done) {
self.nodes = []
clearInterval(self.repeatSend)
self.tcpClient.close(function () {
done()
})
});
this.tcpClient.onClose = function () {
self.nodes.forEach(it => {
it.status(nodeStatus.red);
})
}
this.tcpClient.onConnect = function () {
self.nodes.forEach(it => {
it.status(nodeStatus.green);
})
console.log("onconnect")
}
this.tcpClient.onError = function () {
console.log("onerr")
self.nodes.forEach(it => {
it.status(nodeStatus.red);
})
}
this.register = function (cp) {
if (!this.handleTcp[cp.devtype]) {
this.handleTcp[cp.devtype] = new handleTcp(this.tcpClient, cp.devtype)
this.handleTcp[cp.devtype].onData = function (data) {
self.nodes.forEach(it => {
if (it.devtype = cp.devtype)
it.ondata(data)
})
}
}
if (this.nodes.indexOf(cp) == -1) {
cp.status(nodeStatus.yellow);
this.nodes.push(cp)
}
}
this.tcpClient.connect()
}
RED.nodes.registerType("clowire config", clowireConfig);
function ceckInputData(msg,domain) {
if (typeof msg.payload !== 'object') return
if (msg.payload.event_type !== 'state_changed') return
if (!msg.payload.event.new_state) return
const curDomain = msg.payload.entity_id.split('.')[0]
if(curDomain === 'light') return true
if (domain === curDomain ) return true
}
function boardInit(n,domain){
RED.nodes.createNode(this, n);
this.server = RED.nodes.getNode(n.server);
this.uid = parseInt(n.uid)
this.address = parseInt(n.address) || 0
this.devtype = n.devtype
this.entity_id = n.entity_id
let node = this
if (this.server) {
this.server.register(this)
const buf2obj = node.server.handleTcp[n.devtype].getBufToObj(domain)
const obj2buf = node.server.handleTcp[n.devtype].getObjToBuf(domain)
const ObjToService = node.server.handleTcp.getObjToService(domain)
//收到消息
this.ondata = function (data) {
let obj = buf2obj(data, node)
if (!obj) return
obj = ObjToService(obj)//转成HA服务数据
if (!obj) return
node.send({ call_service: obj.call_service, payload: obj.data })
}
node.on('input', function (msg) {
if (!ceckInputData(msg, domain)) return
let buf = obj2buf(msg.payload.event.new_state, node)
if (buf) {
if(Array.isArray(buf[0]))
for (let i of buf)
node.server.handleTcp[n.devtype].write_lock(i)
else node.server.handleTcp[n.devtype].write_lock(buf)
}
})
} else {
node.status(nodeStatus.red);
}
}
function climateBoard(n) {
boardInit.call(this,n,'climate')
}
RED.nodes.registerType("climate board", climateBoard);
function switchBoard(n) {
boardInit.call(this,n,'switch')
}
RED.nodes.registerType("switch board", switchBoard);
RED.httpAdmin.get("/GetHaDevList", function (req, res) {
res.json({ data: globalContext.get('homeassistant') })
});
}