node-red-contrib-symi
Version:
Node-RED nodes for smart home device communication with Home Assistant integration, supporting HassKit, Clowire, Alive, LF and complete Symi protocols
419 lines (369 loc) • 10.6 kB
JavaScript
/**
* 设备对象转Home Assistant服务调用
*/
/**
* 气候设备对象转HA服务
* @param {object} obj 设备对象
* @returns {object} HA服务调用对象
*/
function ClimateObjToSerivce(obj) {
if (!obj || !obj.uid) return null
let call_service = null
let data = {
entity_id: obj.uid,
attributes: {}
}
switch (obj.type) {
case 'mode':
call_service = {
domain: 'climate',
service: 'set_hvac_mode',
service_data: {
entity_id: obj.uid,
hvac_mode: obj.val
}
}
data.state = obj.val
break
case 'setTemperature':
call_service = {
domain: 'climate',
service: 'set_temperature',
service_data: {
entity_id: obj.uid,
temperature: obj.val
}
}
data.attributes.temperature = obj.val
break
case 'fan_speed':
call_service = {
domain: 'climate',
service: 'set_fan_mode',
service_data: {
entity_id: obj.uid,
fan_mode: obj.val
}
}
data.attributes.fan_mode = obj.val
break
case 'power':
const service = obj.val === 'on' ? 'turn_on' : 'turn_off'
call_service = {
domain: 'climate',
service: service,
service_data: {
entity_id: obj.uid
}
}
data.state = obj.val
break
default:
return null
}
return {
call_service: call_service,
data: data
}
}
/**
* 开关设备对象转HA服务
* @param {object} obj 设备对象
* @returns {object} HA服务调用对象
*/
function SwitchObjToSerivce(obj) {
if (!obj || !obj.uid) return null
let call_service = null
let data = {
entity_id: obj.uid,
attributes: {}
}
switch (obj.type) {
case 'power':
case 'state':
const service = obj.val === 'on' || obj.val === 1 ? 'turn_on' : 'turn_off'
const domain = obj.uid.startsWith('light.') ? 'light' : 'switch'
call_service = {
domain: domain,
service: service,
service_data: {
entity_id: obj.uid
}
}
data.state = obj.val === 'on' || obj.val === 1 ? 'on' : 'off'
break
case 'brightness':
call_service = {
domain: 'light',
service: 'turn_on',
service_data: {
entity_id: obj.uid,
brightness: obj.val
}
}
data.attributes.brightness = obj.val
data.state = obj.val > 0 ? 'on' : 'off'
break
default:
return null
}
return {
call_service: call_service,
data: data
}
}
/**
* 面板设备对象转HA服务
* @param {object} obj 设备对象
* @returns {object} HA服务调用对象
*/
function PanelObjToSerivce(obj) {
if (!obj || !obj.uid) return null
let call_service = null
let data = {
entity_id: obj.uid,
attributes: {}
}
switch (obj.type) {
case 'power':
case 'state':
const service = obj.val === 'on' || obj.val === 1 ? 'turn_on' : 'turn_off'
let domain = 'switch'
// 根据entity_id判断域名
if (obj.uid.startsWith('light.')) {
domain = 'light'
} else if (obj.uid.startsWith('input_boolean.')) {
domain = 'input_boolean'
}
call_service = {
domain: domain,
service: service,
service_data: {
entity_id: obj.uid
}
}
data.state = obj.val === 'on' || obj.val === 1 ? 'on' : 'off'
break
case 'brightness':
call_service = {
domain: 'light',
service: 'turn_on',
service_data: {
entity_id: obj.uid,
brightness: obj.val
}
}
data.attributes.brightness = obj.val
data.state = obj.val > 0 ? 'on' : 'off'
break
default:
return null
}
// 添加面板特有的数据
if (obj.panelData) {
data.attributes.panel_address = obj.panelData.address
data.attributes.panel_channel = obj.panelData.channel
data.attributes.panel_code = obj.panelData.code
}
return {
call_service: call_service,
data: data
}
}
/**
* 灯光设备对象转HA服务
* @param {object} obj 设备对象
* @returns {object} HA服务调用对象
*/
function LightObjToSerivce(obj) {
if (!obj || !obj.uid) return null
let call_service = null
let data = {
entity_id: obj.uid,
attributes: {}
}
switch (obj.action) {
case 'switch':
const service = obj.val === 'on' ? 'turn_on' : 'turn_off'
call_service = {
domain: 'light',
service: service,
service_data: {
entity_id: obj.uid
}
}
data.state = obj.val
break
case 'brightness':
call_service = {
domain: 'light',
service: 'turn_on',
service_data: {
entity_id: obj.uid,
brightness_pct: obj.val
}
}
data.attributes.brightness = Math.round(obj.val * 255 / 100)
data.state = obj.val > 0 ? 'on' : 'off'
break
case 'dual_temp':
call_service = {
domain: 'light',
service: 'turn_on',
service_data: {
entity_id: obj.uid,
color_temp: Math.round(obj.val.color_temp * 500 / 100),
brightness_pct: obj.val.brightness
}
}
data.attributes.color_temp = Math.round(obj.val.color_temp * 500 / 100)
data.attributes.brightness = Math.round(obj.val.brightness * 255 / 100)
data.state = obj.val.brightness > 0 ? 'on' : 'off'
break
case 'rgbw':
call_service = {
domain: 'light',
service: 'turn_on',
service_data: {
entity_id: obj.uid,
rgb_color: obj.val.rgb_color,
brightness: obj.val.brightness
}
}
data.attributes.rgb_color = obj.val.rgb_color
data.attributes.brightness = obj.val.brightness
data.state = obj.val.brightness > 0 ? 'on' : 'off'
break
default:
return null
}
return {
call_service: call_service,
data: data
}
}
/**
* 窗帘设备对象转HA服务
* @param {object} obj 设备对象
* @returns {object} HA服务调用对象
*/
function CurtainObjToSerivce(obj) {
if (!obj || !obj.uid) return null
let call_service = null
let data = {
entity_id: obj.uid,
attributes: {}
}
switch (obj.action) {
case 'switch':
const service = obj.val === 'open' ? 'open_cover' : 'close_cover'
call_service = {
domain: 'cover',
service: service,
service_data: {
entity_id: obj.uid
}
}
data.state = obj.val
break
case 'position':
call_service = {
domain: 'cover',
service: 'set_cover_position',
service_data: {
entity_id: obj.uid,
position: obj.val
}
}
data.attributes.current_position = obj.val
data.state = obj.val > 50 ? 'open' : 'closed'
break
default:
return null
}
return {
call_service: call_service,
data: data
}
}
/**
* 新风设备对象转HA服务
* @param {object} obj 设备对象
* @returns {object} HA服务调用对象
*/
function VentilationObjToSerivce(obj) {
if (!obj || !obj.uid) return null
let call_service = null
let data = {
entity_id: obj.uid,
attributes: {}
}
switch (obj.action) {
case 'power':
const service = obj.val === 'on' ? 'turn_on' : 'turn_off'
call_service = {
domain: 'fan',
service: service,
service_data: {
entity_id: obj.uid
}
}
data.state = obj.val
break
case 'fan_speed':
call_service = {
domain: 'fan',
service: 'set_speed',
service_data: {
entity_id: obj.uid,
speed: obj.val
}
}
data.attributes.speed = obj.val
data.state = 'on'
break
default:
return null
}
return {
call_service: call_service,
data: data
}
}
/**
* 场景设备对象转HA服务
* @param {object} obj 设备对象
* @returns {object} HA服务调用对象
*/
function SceneObjToSerivce(obj) {
if (!obj || !obj.uid) return null
let call_service = null
let data = {
entity_id: obj.uid,
attributes: {}
}
if (obj.action === 'trigger') {
call_service = {
domain: 'scene',
service: 'turn_on',
service_data: {
entity_id: obj.uid
}
}
data.state = 'on'
data.attributes.scene_id = obj.sceneId
}
return {
call_service: call_service,
data: data
}
}
module.exports = {
ClimateObjToSerivce,
SwitchObjToSerivce,
PanelObjToSerivce,
LightObjToSerivce,
CurtainObjToSerivce,
VentilationObjToSerivce,
SceneObjToSerivce
};