Skip to content

Commit

Permalink
feat(hass): added manual discovery setting (#851)
Browse files Browse the repository at this point in the history
* feat(hass): added `manual discovery` setting

With this setting discovery payload will not be sent on startup but users will be able to send them manually from the UI. Useful when using mqtt discovery paired with zwavejs integration to discovery only some entities. Fixes #819

* docs: manual discovery

* fix: undefined error and added tooltips on ui

* fix: lint issues
  • Loading branch information
robertsLando authored Mar 9, 2021
1 parent bcd4554 commit 255e9b3
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 74 deletions.
10 changes: 8 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -421,10 +421,16 @@ function setupSocket (server) {
try {
switch (data.apiName) {
case 'delete':
res = gw.publishDiscovery(data.device, data.nodeId, true, true)
res = gw.publishDiscovery(data.device, data.nodeId, {
deleteDevice: true,
forceUpdate: true
})
break
case 'discover':
res = gw.publishDiscovery(data.device, data.nodeId, false, true)
res = gw.publishDiscovery(data.device, data.nodeId, {
deleteDevice: false,
forceUpdate: true
})
break
case 'rediscoverNode':
res = gw.rediscoverNode(data.nodeId)
Expand Down
1 change: 1 addition & 0 deletions docs/usage/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ Enable this to use Z2M only as a Control Panel
- **MQTT discovery**: Enable this to use MQTT discovery. This is an alternative to Hass Zwave-js integration. (more about this [here](/guide/homeassistant))
- **Discovery Prefix**: The prefix to use to send MQTT discovery messages to HASS
- **Retain Discovery**: Set retain flag to true in discovery messages
- **Manual Discovery**: Don't automatically send the discovery payloads when a device is discovered
- **Entity name template**: Custom Entity name based on placeholders. Default is `%ln_%o`
- `%ln`: Node location with name `<location-?><name>`
- `%n`: Node Name
Expand Down
51 changes: 26 additions & 25 deletions lib/Gateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -1175,52 +1175,53 @@ Gateway.prototype.disableDiscovery = function (nodeID) {
*
* @param {HassDevice} hassDevice The hass device configuration to use for the discovery
* @param {number} nodeId The node id
* @param {boolean} deleteDevice Enable this to remove the selected device from hass discovery
* @param {boolean} update Update an hass device of a specific node in zwaveClient and send the event to socket
* @param {{deleteDevice: boolean, forceUpdate: boolean}} options options
*/
Gateway.prototype.publishDiscovery = function (
hassDevice,
nodeId,
deleteDevice,
update
options = {}
) {
try {
logger.log(
'debug',
`${deleteDevice ? 'Removing' : 'Publishing'} discovery: %o`,
`${options.deleteDevice ? 'Removing' : 'Publishing'} discovery: %o`,
hassDevice
)

this.setDiscovery(nodeId, hassDevice, deleteDevice)

// don't discovery this device when ignore is true
if (!hassDevice.ignoreDiscovery) {
if (this.config.payloadType === 2) {
// Payload is set to "Just Value"
const p = hassDevice.discovery_payload
const template =
'value' +
(p.hasOwnProperty('payload_on') && p.hasOwnProperty('payload_off')
? " == 'true'"
: '')

for (const k in p) {
if (typeof p[k] === 'string') {
p[k] = p[k].replace(/value_json\.value/g, template)
}
this.setDiscovery(nodeId, hassDevice, options.deleteDevice)

if (this.config.payloadType === 2) {
// Payload is set to "Just Value"
const p = hassDevice.discovery_payload
const template =
'value' +
(p.hasOwnProperty('payload_on') && p.hasOwnProperty('payload_off')
? " == 'true'"
: '')

for (const k in p) {
if (typeof p[k] === 'string') {
p[k] = p[k].replace(/value_json\.value/g, template)
}
}
}

const skipDiscovery =
hassDevice.ignoreDiscovery ||
(this.config.manualDiscovery && !options.forceUpdate)

if (!skipDiscovery) {
this.mqtt.publish(
hassDevice.discoveryTopic,
deleteDevice ? '' : hassDevice.discovery_payload,
options.deleteDevice ? '' : hassDevice.discovery_payload,
{ qos: 0, retain: this.config.retainedDiscovery || false },
this.config.discoveryPrefix
)
}

if (update) {
this.zwave.updateDevice(hassDevice, nodeId, deleteDevice)
if (options.forceUpdate) {
this.zwave.updateDevice(hassDevice, nodeId, options.deleteDevice)
}
} catch (error) {
logger.log(
Expand Down
10 changes: 9 additions & 1 deletion src/components/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -501,14 +501,22 @@
hint="The prefix to use for Hass MQTT discovery. Leave empty to use the mqtt prefix"
></v-text-field>
</v-col>
<v-col cols="12" v-if="newGateway.hassDiscovery">
<v-col cols="6" v-if="newGateway.hassDiscovery">
<v-switch
label="Retained discovery"
hint="Set retain flag to true in discovery messages"
v-model="newGateway.retainedDiscovery"
persistent-hint
></v-switch>
</v-col>
<v-col cols="6" v-if="newGateway.hassDiscovery">
<v-switch
label="Manual discovery"
hint="Don't automatically send the discovery payloads when a device is discovered"
v-model="newGateway.manualDiscovery"
persistent-hint
></v-switch>
</v-col>
<v-col cols="6" v-if="newGateway.hassDiscovery">
<v-text-field
v-model="newGateway.entityTemplate"
Expand Down
159 changes: 115 additions & 44 deletions src/components/nodes-table/HomeAssistant.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,62 @@
<!-- HASS DEVICES -->
<v-row v-if="hassDevices.length > 0">
<v-col cols="12" md="6" pa-1>
<v-btn color="blue darken-1" text @click="storeDevices(false)"
>Store</v-btn
>
<v-btn color="red darken-1" text @click="storeDevices(true)"
>Remove Store</v-btn
>
<v-btn color="green darken-1" text @click="rediscoverNode"
>Rediscover Node</v-btn
>
<v-btn color="yellow darken-1" text @click="disableDiscovery"
>Disable Discovery</v-btn
>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
color="blue darken-1"
text
@click="storeDevices(false)"
>Store</v-btn
>
</template>
<span
>Store all discovered devices in nodes.json in store directory.
Prevents re-discovery on startup</span
>
</v-tooltip>

<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
color="red darken-1"
text
@click="storeDevices(true)"
>Remove Store</v-btn
>
</template>
<span>Remove devices from nodes.json in store directory</span>
</v-tooltip>

<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn v-on="on" color="green darken-1" text @click="rediscoverNode"
>Rediscover Node</v-btn
>
</template>
<span
>Rediscover all node entities. Useful when changing node
name/location and need to recalculate topics</span
>
</v-tooltip>

<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
color="yellow darken-1"
text
@click="disableDiscovery"
>Disable Discovery</v-btn
>
</template>
<span
>Set the ignoreDiscovery flag to true on all entities of this node
to skip the discovery of them</span
>
</v-tooltip>

<v-data-table
:headers="headers_hass"
Expand Down Expand Up @@ -44,38 +88,65 @@
</v-data-table>
</v-col>
<v-col cols="12" md="6" pa-1>
<v-btn
v-if="!selectedDevice"
color="blue darken-1"
:disabled="errorDevice"
text
@click="addDevice"
>Add</v-btn
>
<v-btn
v-if="selectedDevice"
color="blue darken-1"
:disabled="errorDevice"
text
@click="updateDevice"
>Update</v-btn
>
<v-btn
v-if="selectedDevice"
color="green darken-1"
:disabled="errorDevice"
text
@click="rediscoverDevice"
>Rediscover</v-btn
>
<v-btn
v-if="selectedDevice"
color="red darken-1"
:disabled="errorDevice"
text
@click="deleteDevice"
>Delete</v-btn
>
<v-tooltip v-if="!selectedDevice" bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
color="blue darken-1"
:disabled="errorDevice"
text
@click="addDevice"
>Add</v-btn
>
</template>
<span>Add this device to discovered entities</span>
</v-tooltip>

<v-tooltip v-if="selectedDevice" bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
color="blue darken-1"
:disabled="errorDevice"
text
@click="updateDevice"
>Update</v-btn
>
</template>
<span
>Update the in-memory discover template. You have to press
Rediscover in order to send this to HA</span
>
</v-tooltip>

<v-tooltip v-if="selectedDevice" bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
color="green darken-1"
:disabled="errorDevice"
text
@click="rediscoverDevice"
>Rediscover</v-btn
>
</template>
<span>Send this payload to HA</span>
</v-tooltip>

<v-tooltip v-if="selectedDevice" bottom>
<template v-slot:activator="{ on }">
<v-btn
v-on="on"
color="red darken-1"
:disabled="errorDevice"
text
@click="deleteDevice"
>Delete</v-btn
>
</template>
<span>Delete this entity</span>
</v-tooltip>

<v-textarea
label="Hass Device JSON"
auto-grow
Expand Down
3 changes: 1 addition & 2 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,7 @@ export interface Z2MGateway {
publishDiscovery(
hassDevice: HassDevice,
nodeId: number,
deleteDevice: boolean,
update: boolean
{ deleteDevice: boolean, forceUpdate: boolean }
): void
setDiscovery(
nodeId: number,
Expand Down

0 comments on commit 255e9b3

Please sign in to comment.