Skip to content

Commit

Permalink
Merge pull request #32 from shaonianzhentan/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
shaonianzhentan committed Sep 11, 2023
2 parents 9ac0af9 + 982ebe4 commit b28bafb
Show file tree
Hide file tree
Showing 30 changed files with 744 additions and 143 deletions.
263 changes: 133 additions & 130 deletions HomeAssistant.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,150 +4,153 @@ const pinyin = require("node-pinyin")
const pk = JSON.parse(fs.readFileSync(__dirname + '/package.json', 'utf-8'))

function object_id(name) {
let arr = pinyin(name, { style: 'normal' })
return arr.map(ele => ele[0]).join('_')
let arr = pinyin(name, { style: 'normal' })
return arr.map(ele => ele[0]).join('_').replace(/ /g, "_")
}

const DiscoveryDevice = {}
module.exports = class HomeAssistant {
constructor(node, cfg, device_info) {
this.device_info = device_info
node.config = cfg.config
this.node = node
const { name } = cfg
const entity_id = object_id(name)
const type = node.type.replace('ha-mqtt-', '')
const topic = `ha-mqtt/${type}/${entity_id}/`
this.config = {
name,
unique_id: topic.replace(/\//g, '_'),
discovery_topic: `homeassistant/${type}/${entity_id}/config`,
state_topic: `${topic}state`,
json_attr_t: `${topic}attr`,
command_topic: `${topic}set`,
position_topic: `${topic}position/state`,
set_position_topic: `${topic}position/set`,
availability_topic: `${topic}availability/state`,
power_command_topic: `${topic}power/set`,
effect_state_topic: `${topic}effect/state`,
effect_command_topic: `${topic}effect/set`,
brightness_state_topic: `${topic}brightness/state`,
brightness_command_topic: `${topic}brightness/set`,
current_temperature_topic: `${topic}current_temperature`,
target_humidity_state_topic: `${topic}target_humidity/state`,
target_humidity_command_topic: `${topic}target_humidity/set`,
temperature_state_topic: `${topic}temperature/state`,
temperature_command_topic: `${topic}temperature/set`,
mode_state_topic: `${topic}mode/state`,
mode_command_topic: `${topic}mode/set`,
fan_mode_state_topic: `${topic}fan_mode/state`,
fan_mode_command_topic: `${topic}fan_mode/set`,
swing_mode_state_topic: `${topic}swing_mode/state`,
swing_mode_command_topic: `${topic}swing_mode/set`,
oscillation_state_topic: `${topic}oscillation/state`,
oscillation_command_topic: `${topic}oscillation/set`,
percentage_state_topic: `${topic}percentage/state`,
percentage_command_topic: `${topic}percentage/set`,
preset_mode_state_topic: `${topic}preset_mode/state`,
preset_mode_command_topic: `${topic}preset_mode/set`,
tilt_state_topic: `${topic}tilt/state`,
tilt_status_topic: `${topic}tilt/status`,
tilt_command_topic: `${topic}tilt/set`,
battery_level_topic: `${topic}battery_level/state`,
charging_topic: `${topic}charging/state`,
cleaning_topic: `${topic}cleaning/state`,
docked_topic: `${topic}docked/state`,
error_topic: `${topic}error/state`,
fan_speed_topic: `${topic}fan_speed/state`,
set_fan_speed_topic: `${topic}set_fan_speed/set`,
send_command_topic: `${topic}send_command/set`,
}
constructor(node, cfg, device_info) {
this.device_info = device_info
node.config = cfg.config
this.node = node
const { name } = cfg
const entity_id = object_id(name)
const type = node.type.replace('ha-mqtt-', '')
const topic = `ha-mqtt/${type}/${entity_id}/`
this.config = {
name,
unique_id: topic.replace(/\//g, '_'),
discovery_topic: `homeassistant/${type}/${entity_id}/config`,
state_topic: `${topic}state`,
json_attr_t: `${topic}attr`,
command_topic: `${topic}set`,
position_topic: `${topic}position/state`,
set_position_topic: `${topic}position/set`,
availability_topic: `${topic}availability/state`,
power_command_topic: `${topic}power/set`,
pause_command_topic: `${topic}pause/set`,
dock_command_topic: `${topic}dock/set`,
start_mowing_command_topic: `${topic}start_mowing/set`,
effect_state_topic: `${topic}effect/state`,
effect_command_topic: `${topic}effect/set`,
brightness_state_topic: `${topic}brightness/state`,
brightness_command_topic: `${topic}brightness/set`,
current_temperature_topic: `${topic}current_temperature`,
target_humidity_state_topic: `${topic}target_humidity/state`,
target_humidity_command_topic: `${topic}target_humidity/set`,
temperature_state_topic: `${topic}temperature/state`,
temperature_command_topic: `${topic}temperature/set`,
mode_state_topic: `${topic}mode/state`,
mode_command_topic: `${topic}mode/set`,
fan_mode_state_topic: `${topic}fan_mode/state`,
fan_mode_command_topic: `${topic}fan_mode/set`,
swing_mode_state_topic: `${topic}swing_mode/state`,
swing_mode_command_topic: `${topic}swing_mode/set`,
oscillation_state_topic: `${topic}oscillation/state`,
oscillation_command_topic: `${topic}oscillation/set`,
percentage_state_topic: `${topic}percentage/state`,
percentage_command_topic: `${topic}percentage/set`,
preset_mode_state_topic: `${topic}preset_mode/state`,
preset_mode_command_topic: `${topic}preset_mode/set`,
tilt_state_topic: `${topic}tilt/state`,
tilt_status_topic: `${topic}tilt/status`,
tilt_command_topic: `${topic}tilt/set`,
battery_level_topic: `${topic}battery_level/state`,
charging_topic: `${topic}charging/state`,
cleaning_topic: `${topic}cleaning/state`,
docked_topic: `${topic}docked/state`,
error_topic: `${topic}error/state`,
fan_speed_topic: `${topic}fan_speed/state`,
set_fan_speed_topic: `${topic}set_fan_speed/set`,
send_command_topic: `${topic}send_command/set`,
}
}

static get version() {
return pk.version
}
static get version() {
return pk.version
}

static AutoDiscovery(nodes) {
for (const node_id in DiscoveryDevice) {
// delete empty nodes
if (nodes && nodes.getNode(node_id) == null) {
delete DiscoveryDevice[node_id]
continue
}
DiscoveryDevice[node_id]()
}
static AutoDiscovery(nodes) {
for (const node_id in DiscoveryDevice) {
// delete empty nodes
if (nodes && nodes.getNode(node_id) == null) {
delete DiscoveryDevice[node_id]
continue
}
DiscoveryDevice[node_id]()
}
}

discovery(config, callback) {
const node_id = this.node.id
DiscoveryDevice[node_id] = () => {
if (this.node.config) {
config = Object.assign(config, JSON.parse(this.node.config))
}
this.publish_config(config)
callback()
}
this.subscribe('homeassistant/status', (payload) => {
if (payload === 'online') {
HomeAssistant.AutoDiscovery()
}
})
// publish config
DiscoveryDevice[node_id]()
discovery(config, callback) {
const node_id = this.node.id
DiscoveryDevice[node_id] = () => {
if (this.node.config) {
config = Object.assign(config, JSON.parse(this.node.config))
}
this.publish_config(config)
callback()
}
this.subscribe('homeassistant/status', (payload) => {
if (payload === 'online') {
HomeAssistant.AutoDiscovery()
}
})
// publish config
DiscoveryDevice[node_id]()
}

publish_config(data) {
const { name, unique_id, discovery_topic, state_topic, json_attr_t } = this.config
const mergeConfig = Object.assign({
name,
unique_id,
state_topic,
json_attr_t,
device: this.device_info
}, data)
// Delete the property of NULL
Object.keys(mergeConfig).forEach(key => {
if (mergeConfig[key] === null) {
delete mergeConfig[key]
}
})
this.publish(discovery_topic, mergeConfig)
}
publish_config(data) {
const { name, unique_id, discovery_topic, state_topic, json_attr_t } = this.config
const mergeConfig = Object.assign({
name,
unique_id,
state_topic,
json_attr_t,
device: this.device_info
}, data)
// Delete the property of NULL
Object.keys(mergeConfig).forEach(key => {
if (mergeConfig[key] === null) {
delete mergeConfig[key]
}
})
this.publish(discovery_topic, mergeConfig)
}

subscribe(topic, callback) {
this.node.server.subscribe(topic, { qos: 0 }, function (mtopic, mpayload, mpacket) {
callback(mpayload.toString())
})
}
subscribe(topic, callback) {
this.node.server.subscribe(topic, { qos: 0 }, function (mtopic, mpayload, mpacket) {
callback(mpayload.toString())
})
}

send_payload(payload, i, len = 4) {
let arr = []
arr.length = len
arr[i - 1] = { payload }
this.node.send(arr)
}
send_payload(payload, i, len = 4) {
let arr = []
arr.length = len
arr[i - 1] = { payload }
this.node.send(arr)
}

publish(topic, payload, msg = "") {
const type = Object.prototype.toString.call(payload)
switch (type) {
case '[object Uint8Array]':
this.node.server.client.publish(topic, payload, { retain: false })
return;
case '[object Object]':
payload = JSON.stringify(payload)
break;
case '[object Number]':
payload = String(payload)
break;
}
this.node.server.client.publish(topic, payload)
if (msg) {
this.node.status({ fill: "green", shape: "ring", text: `${msg}${payload}` });
}
publish(topic, payload, msg = "") {
const type = Object.prototype.toString.call(payload)
switch (type) {
case '[object Uint8Array]':
this.node.server.client.publish(topic, payload, { retain: false })
return;
case '[object Object]':
payload = JSON.stringify(payload)
break;
case '[object Number]':
payload = String(payload)
break;
}

isEmpty(value) {
return value !== 0 && !value
this.node.server.client.publish(topic, payload)
if (msg) {
this.node.status({ fill: "green", shape: "ring", text: `${msg}${payload}` });
}
}

isEmpty(value) {
return value !== 0 && !value
}
}
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ Example:https://github.com/shaonianzhentan/node-red-contrib-ha-mqtt/wiki
- ✔️ [cover](https://www.home-assistant.io/integrations/cover.mqtt/)
- ✔️ [device_tracker](https://www.home-assistant.io/integrations/device_tracker.mqtt/)
- ✔️ [device_automation](https://www.home-assistant.io/integrations/device_trigger.mqtt/)
- [event](https://www.home-assistant.io/integrations/event.mqtt/)
- ✔️ [event](https://www.home-assistant.io/integrations/event.mqtt/)
- ✔️ [fan](https://www.home-assistant.io/integrations/fan.mqtt/)
- ✔️ [humidifier](https://www.home-assistant.io/integrations/humidifier.mqtt/)
- [image](https://www.home-assistant.io/integrations/image.mqtt/)
- [lawn_mower](https://www.home-assistant.io/integrations/lawn_mower.mqtt/)
- ✔️ [image](https://www.home-assistant.io/integrations/image.mqtt/)
- ✔️ [lawn_mower](https://www.home-assistant.io/integrations/lawn_mower.mqtt/)
- ✔️ [light](https://www.home-assistant.io/integrations/light.mqtt/)
- ✔️ [lock](https://www.home-assistant.io/integrations/lock.mqtt/)
- ✔️ [number](https://www.home-assistant.io/integrations/number.mqtt/)
Expand All @@ -41,9 +41,9 @@ Example:https://github.com/shaonianzhentan/node-red-contrib-ha-mqtt/wiki
- ✔️ [sensor](https://www.home-assistant.io/integrations/sensor.mqtt/)
- ✔️ [switch](https://www.home-assistant.io/integrations/switch.mqtt/)
- ✔️ [siren](https://www.home-assistant.io/integrations/siren.mqtt/)
- [update](https://www.home-assistant.io/integrations/update.mqtt/)
- ✔️ [update](https://www.home-assistant.io/integrations/update.mqtt/)
- ✔️ [tag](https://www.home-assistant.io/integrations/tag.mqtt/)
- [text](https://www.home-assistant.io/integrations/text.mqtt/)
- ✔️ [text](https://www.home-assistant.io/integrations/text.mqtt/)
- ✔️ [vacuum](https://www.home-assistant.io/integrations/vacuum.mqtt/)
-[water_heater](https://www.home-assistant.io/integrations/water_heater.mqtt/)

Expand Down
10 changes: 5 additions & 5 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
- ✔️ [cover - 窗帘](https://www.home-assistant.io/integrations/cover.mqtt/)
- ✔️ [device_tracker - 设备检测](https://www.home-assistant.io/integrations/device_tracker.mqtt/)
- ✔️ [device_automation - 设备自动化](https://www.home-assistant.io/integrations/device_trigger.mqtt/)
- [event - 事件](https://www.home-assistant.io/integrations/event.mqtt/)
- ✔️ [event - 事件](https://www.home-assistant.io/integrations/event.mqtt/)
- ✔️ [fan - 风扇](https://www.home-assistant.io/integrations/fan.mqtt/)
- ✔️ [humidifier - 加湿器](https://www.home-assistant.io/integrations/humidifier.mqtt/)
- [image - 图像](https://www.home-assistant.io/integrations/image.mqtt/)
- [lawn_mower - 割草机](https://www.home-assistant.io/integrations/lawn_mower.mqtt/)
- ✔️ [image - 图像](https://www.home-assistant.io/integrations/image.mqtt/)
- ✔️ [lawn_mower - 割草机](https://www.home-assistant.io/integrations/lawn_mower.mqtt/)
- ✔️ [light - 灯](https://www.home-assistant.io/integrations/light.mqtt/)
- ✔️ [lock - 锁](https://www.home-assistant.io/integrations/lock.mqtt/)
- ✔️ [number - 数字](https://www.home-assistant.io/integrations/number.mqtt/)
Expand All @@ -39,9 +39,9 @@
- ✔️ [sensor - 传感器](https://www.home-assistant.io/integrations/sensor.mqtt/)
- ✔️ [switch - 开关](https://www.home-assistant.io/integrations/switch.mqtt/)
- ✔️ [siren - 警报器](https://www.home-assistant.io/integrations/siren.mqtt/)
- [update - 更新](https://www.home-assistant.io/integrations/update.mqtt/)
- ✔️ [update - 更新](https://www.home-assistant.io/integrations/update.mqtt/)
- ✔️ [tag - 标签](https://www.home-assistant.io/integrations/tag.mqtt/)
- [text - 文本](https://www.home-assistant.io/integrations/text.mqtt/)
- ✔️ [text - 文本](https://www.home-assistant.io/integrations/text.mqtt/)
- ✔️ [vacuum - 扫地机器人](https://www.home-assistant.io/integrations/vacuum.mqtt/)
-[water_heater - 热水器](https://www.home-assistant.io/integrations/water_heater.mqtt/)

Expand Down
49 changes: 49 additions & 0 deletions event/event.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script type="text/html" data-template-name="ha-mqtt-event">
<div class="form-row">
<label for="node-input-server" data-i18n="node-red-contrib-ha-mqtt/common:label.mqttServer"></label>
<select id="node-input-server"></select>
</div>
<div class="form-row">
<label for="node-input-device" data-i18n="node-red-contrib-ha-mqtt/common:label.deviceName"></label>
<select type="text" id="node-input-device" data-i18n="[placeholder]node-red-contrib-ha-mqtt/common:label.deviceName"></select>
</div>
<div class="form-row">
<label for="node-input-name" data-i18n="node-red-contrib-ha-mqtt/common:label.entityName"></label>
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red-contrib-ha-mqtt/common:label.entityName">
</div>
<div class="form-row">
<label for="node-input-types" data-i18n="label.type"></label>
<input type="text" id="node-input-types" data-i18n="[placeholder]placeholder.type">
</div>
<div class="form-row">
<a href="https://www.home-assistant.io/integrations/event.mqtt/" target="_blank" style="color:blue;">
<label for="node-input-config" data-i18n="node-red-contrib-ha-mqtt/common:label.config"></label>
</a>
<input type="text" id="node-input-config" data-i18n="[placeholder]node-red-contrib-ha-mqtt/common:label.config">
</div>
</script>
<script type="text/javascript">
RED.nodes.registerType('ha-mqtt-event', {
category: RED._("node-red-contrib-ha-mqtt/common:homeAssistantCategory"),
color: '#C0DEED',
icon: "font-awesome/fa-info",
paletteLabel: 'Event',
defaults: {
server: { value: "", type: "mqtt-broker", required: true },
device: { value: "", type: "ha-mqtt-device", required: true },
name: { value: "", required: true },
types: { value: "", required: true },
config: { value: "" }
},
inputs: 1,
outputs: 0,
inputLabels: RED._("node-red-contrib-ha-mqtt/common:ioLabels.state"),
label: function () {
return this.name || "event";
},
oneditprepare: function () {
$("#node-input-config").typedInput({ type: "json", types: ["json"] })
}
});

</script>
Loading

0 comments on commit b28bafb

Please sign in to comment.