Skip to content

Commit

Permalink
fix(ui): settings refactor, fix mesh node names (#456)
Browse files Browse the repository at this point in the history
* fix(ui): show/hide hass devices tab, fix mesh node names

* fix(ui): better show/hide useless props in settings

Moved gateway table to general section

* fix(ui): reorganized settings sections

* docs: poll a value (#455)

* docs: fixed docs to reflect changes
  • Loading branch information
robertsLando authored Feb 4, 2021
1 parent ddd9d44 commit 24f9daa
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 90 deletions.
Binary file removed docs/_images/OZW_Logo.png
Binary file not shown.
Binary file removed docs/_images/OZW_Panel_Node.png
Binary file not shown.
Binary file added docs/_images/edit_gateway_value.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_images/gateway_values_table.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/_images/mesh.png
Binary file not shown.
56 changes: 43 additions & 13 deletions docs/usage/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@ Firstly you need to open the browser at the link <http://localhost:8091> and edi
- **Log level**: Set the log level (Error, Warn, Info, Verbose, Debug, Silly)
- **Log to file**: Enable this to store the logs to a file

### Device values configuration

The Device values configuration table can be found under [General](#general) section and can be used to create valueIds specific configurations for each device. This means that if you create an entry here this configuration will be applyed to all device of the same type in your Network.

![Gateway values](../_images/gateway_values_table.png)

> [!NOTE]
> In order to appear in the dropdown list a device must have completed its interview so if you don't find it there please wait for this.
> If it is a Battery powered device try to manually wake up it
Properties of a **valueId configuration**:

- **Device**: The device type. Once scan is complete, the gateway creates an array with all devices types found in the network. A device has a `device_id` that is unique, it is composed by this node properties: `<manufacturerid>-<productid>-<producttype>`.
- **Value**: The valueId you want to configure
- **Device Class**: If the value is a multilevel sensor, a binary sensor or a meter you can set a custom `device_class` to use with home assistant discovery. Check [sensor](https://www.home-assistant.io/components/sensor/#device-class) and [binary sensor](https://www.home-assistant.io/components/binary_sensor/#device-class)
- **Topic**: The topic to use for this value. It is the topic added after topic prefix, node name and location. If gateway type is different than `Manual` this will be ignored
- **Post operation**: If you want to convert your value (valid examples: '/10' '/100' '*10' '*100')
- **Parse send**: Enable this to allow users to specify a custom `function(value,valueId,node,logger)` to parse the value sent to MQTT. The function must be sync
- **Parse receive**: Enable this to allow users to specify a custom `function(value,valueId,node,logger)` to parse the value received via MQTT. The function must be sync
- **Enable Poll**: Enable poll of this value by using zwave-js [pollValue](https://zwave-js.github.io/node-zwave-js/#/api/node?id=pollvalue)
- **Poll interval**: Seconds between two poll requests

## Zwave

- **Serial port**: The serial port where your controller is connected
Expand Down Expand Up @@ -42,7 +64,7 @@ Enable this to use Z2M only as a Control Panel

## Gateway

- **Gateway type**: This setting specify the logic used to publish Zwave Nodes Values in MQTT topics. At the moment there are 3 possible configuration, two are automatic (all values are published in a specific topic) and one needs to manually configure which values you want to publish to MQTT and what topic to use. For every gateway type you can set custom topic values, if gateway is not in 'configure manually' mode you can omit the topic of the values (the topic will depends on the gateway type) and use the table to set values you want to `poll` or if you want to scale them using `post operation`
- **Type**: This setting specify the logic used to publish Zwave Nodes Values in MQTT topics. At the moment there are 3 possible configuration, two are automatic (all values are published in a specific topic) and one needs to manually configure which values you want to publish to MQTT and what topic to use. For every gateway type you can set custom topic values, if gateway is not in 'configure manually' mode you can omit the topic of the values (the topic will depends on the gateway type) and use the table to set values you want to `poll` or if you want to scale them using `post operation`

1. **ValueId Topics**: _Automatically configured_. The topic where zwave values are published will be:

Expand Down Expand Up @@ -166,7 +188,9 @@ Enable this to use Z2M only as a Control Panel
- **Ignore location**: Enable this to remove nodes location from topics
- **Publish node details**: Creates an `nodeinfo` topic under each node's MQTT tree, with most node details. Helps build up discovery payloads.

- :star:**Hass discovery**:star:: Enable this to automatically create entities on Hass using MQTT auto discovery (more about this [here](#robot-home-assistant-integration-beta))
## Home Assistant

- :star:**Hass discovery**:star:: Enable this to automatically create entities on Hass using MQTT auto discovery (more about this [here](../guide/homeassistant?id=home-assistant-integration-beta))
- **Discovery Prefix**: The prefix to use to send MQTT discovery messages to HASS
- **Retain Discovery**: Set retain flag to true in discovery messages
- **Entity name template**: Custom Entity name based on placeholders. Default is `%ln_%o`
Expand All @@ -179,20 +203,26 @@ Enable this to use Z2M only as a Control Panel
- `%o`: HASS object_id
- `%l`: valueId label (fallback to object_id)

## Save settings

Once finished press `SAVE` and gateway will start Zwave Network Scan, then go to 'Control Panel' section and wait until the scan is completed to check discovered devices and manage them.

Settings, scenes and Zwave configuration are stored in `JSON` files under project `store` folder that you can easily **import/export** for backup purposes.

- **Gateway values table**
## Poll values

The Gateway values table can be used with all gateway types to customize specific values topic for each device type found in the network and do some operations with them. Each value has this properties:
Some legacy devices don't report all their values automatically and require polling to get updated values. In contrast to OZW, zwave-js does not automatically poll devices on a regular basis without user interaction. Polling can quickly lead to network congestion and should be used very sparingly and only where necessary.

- **Device**: The device type. Once scan is complete, the gateway creates an array with all devices types found in the network. A device has a `device_id` that is unique, it is composed by this node properties: `<manufacturerid>-<productid>-<producttype>`.
- **Value**: The value you want to customize
- **Device Class**: If the value is a multilevel sensor, a binary sensor or a meter you can set a custom `device_class` to use with home assistant discovery. Check [sensor](https://www.home-assistant.io/components/sensor/#device-class) and [binary sensor](https://www.home-assistant.io/components/binary_sensor/#device-class)
- **Topic**: The topic to use for this value. It is the topic added after topic prefix, node name and location. If gateway type is different than `Manual` this can be leave blank and the value topic will be the one based on the gateway configuration chosen
- **Post operation**: If you want to convert your value (eg. '/10' '/100' '*10' '*100')
- **Parse send**: Enable this to allow users to specify a custom `function(value,valueId,node,logger)` to parse the value sent to MQTT. The function must be sync
- **Parse receive**: Enable this to allow users to specify a custom `function(value,valueId,node,logger)` to parse the value received via MQTT. The function must be sync
- **Enable Poll**: Enable poll of this value by using zwave-js [pollValue](https://zwave-js.github.io/node-zwave-js/#/api/node?id=pollvalue). _Warning_: Polling can impose a heavy load on the network and should not be done too frequently.
- **Poll interval**: Seconds between two poll requests
zwavejs2mqtt allows you to configure scheduled polling on a per-value basis, which you can use to keep certain values updated.
It also allows you to poll individual values on-demand from your automations, which should be preferred over blindly polling all the time if possible.

> [!NOTE]
> Many values can only be polled together. For example `targetValue`, `currentValue` and `duration` for most of the switch-type CCs. Before enabling polling for all values of a node, users should check whether polling a single value already updates the desired other values too.

In order to enable Polling of specific values you need to go to Settings page, expand General section and add a new value to the [Gateway Values table](#gateway-values-table)

Now press on `NEW VALUE` to add a new value or on the `Pen Icon` in actions column of the table to open the dialog to Add/Edit a value. Select the device, the valueId, enable the `Enable Poll` flag and set a `Poll interval` in seconds:

![Edit value](../_images/edit_gateway_value.png)

Press now on `SAVE` to upload your new settings to the server and it will automatically handle the polling based on your settings.
11 changes: 2 additions & 9 deletions src/components/Mesh.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,6 @@ export default {
D3Network
},
watch: {
showLocation () {
for (const n of this.nodes) {
n.name = this.nodeName(n)
}
},
meshNodes () {
this.debounceRefresh()
}
Expand Down Expand Up @@ -255,21 +250,19 @@ export default {
}
},
mounted () {
const self = this
this.socket.on(socketEvents.api, data => {
if (data.success) {
switch (data.api) {
case 'refreshNeighbors': {
const neighbors = data.result
for (let i = 0; i < neighbors.length; i++) {
self.setNeighbors({ nodeId: i, neighbors: neighbors[i] })
this.setNeighbors({ nodeId: i, neighbors: neighbors[i] })
}
break
}
}
} else {
self.showSnackbar(
this.showSnackbar(
'Error while calling api ' + data.api + ': ' + data.message
)
}
Expand Down
155 changes: 91 additions & 64 deletions src/components/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@
<v-expansion-panel-content>
<v-card flat>
<v-card-text>
<v-row>
<v-col cols="12" sm="6">
<v-row class="mb-5">
<v-col cols="12" sm="6" md="4">
<v-switch
hint="Enable logging"
persistent-hint
label="Log enabled"
v-model="gateway.logEnabled"
></v-switch>
</v-col>
<v-col cols="12" sm="6" v-if="gateway.logEnabled">
<v-col cols="12" sm="6" md="4" v-if="gateway.logEnabled">
<v-select
:items="logLevels"
v-model="gateway.logLevel"
label="Log Level"
></v-select>
</v-col>
<v-col cols="12" sm="6" v-if="gateway.logEnabled">
<v-col cols="12" sm="6" md="4" v-if="gateway.logEnabled">
<v-switch
hint="Store logs in a file. Default: store/zwavejs2mqtt.log"
persistent-hint
Expand All @@ -41,7 +41,66 @@
></v-switch>
</v-col>
</v-row>
<v-subheader class="font-weight-bold"
>Devices values configuration</v-subheader
>
<div class="mb-5 caption">
Add here valueIds specific configurations for each device.
This means that if you create an entry here this
configuration will be applyed to each valueId of each
device of the same type in your Network.
</div>
<v-data-table
:headers="visibleHeaders"
:items="gateway.values"
:items-per-page-options="[
10,
20,
{ text: 'All', value: -1 }
]"
class="elevation-1"
>
<template v-slot:[`item.device`]="{ item }">
{{ deviceName(item.device) }}
</template>
<template v-slot:[`item.value`]="{ item }">
{{ item.value.label + ' (' + item.value.id + ')' }}
</template>
<template v-slot:[`item.topic`]="{ item }">
{{ item.topic }}
</template>
<template v-slot:[`item.postOperation`]="{ item }">
{{ item.postOperation || 'No operation' }}
</template>
<template v-slot:[`item.enablePoll`]="{ item }">
{{
item.enablePoll
? 'Interval: ' + item.pollInterval + 's'
: 'No'
}}
</template>
<template v-slot:[`item.actions`]="{ item }">
<v-icon
small
class="mr-2"
color="green"
@click="editItem(item)"
>edit</v-icon
>
<v-icon small color="red" @click="deleteItem(item)"
>delete</v-icon
>
</template>
</v-data-table>
</v-card-text>
<v-card-actions>
<v-btn
color="blue darken-1"
text
@click="dialogValue = true"
>New Value</v-btn
>
</v-card-actions>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
Expand Down Expand Up @@ -305,7 +364,7 @@
<v-col cols="12">
<v-select
v-model="gateway.type"
label="Type"
label="Topic type"
:rules="[rules.required]"
required
:items="gw_types"
Expand Down Expand Up @@ -366,6 +425,22 @@
persistent-hint
></v-switch>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>

<v-divider></v-divider>

<v-expansion-panel key="Hass" v-if="!mqtt.disabled">
<v-expansion-panel-header
>Home Assistant</v-expansion-panel-header
>
<v-expansion-panel-content>
<v-card flat>
<v-card-text>
<v-row>
<v-col cols="6">
<v-switch
label="Hass Discovery"
Expand All @@ -381,7 +456,7 @@
hint="The prefix to use for Hass MQTT discovery. Leave empty to use the mqtt prefix"
></v-text-field>
</v-col>
<v-col cols="6" v-if="gateway.hassDiscovery">
<v-col cols="12" v-if="gateway.hassDiscovery">
<v-switch
label="Retained discovery"
hint="Set retain flag to true in discovery messages"
Expand Down Expand Up @@ -414,67 +489,10 @@
</div>
</v-col>
</v-row>
<v-data-table
:headers="headers"
:items="gateway.values"
:items-per-page-options="[
10,
20,
{ text: 'All', value: -1 }
]"
class="elevation-1"
>
<template v-slot:item="{ item }">
<tr>
<td>{{ deviceName(item.device) }}</td>
<td>
{{ item.value.label + ' (' + item.value.id + ')' }}
</td>
<td class="text-xs">{{ item.topic }}</td>
<td class="text-xs">
{{ item.postOperation || 'No operation' }}
</td>
<td class="text-xs">
{{
item.enablePoll
? 'Interval: ' + item.pollInterval + 's'
: 'No'
}}
</td>
<!-- <td class="text-xs">
{{
item.verifyChanges ? 'Verified' : 'Not Verified'
}}
</td> -->
<td>
<v-icon
small
class="mr-2"
color="green"
@click="editItem(item)"
>edit</v-icon
>
<v-icon small color="red" @click="deleteItem(item)"
>delete</v-icon
>
</td>
</tr>
</template>
</v-data-table>
</v-card-text>
<v-card-actions>
<v-btn
color="blue darken-1"
text
@click="dialogValue = true"
>New Value</v-btn
>
</v-card-actions>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>

<v-divider></v-divider>
</v-expansion-panels>

<DialogGatewayValue
Expand Down Expand Up @@ -522,6 +540,15 @@ export default {
fileInput
},
computed: {
visibleHeaders () {
if (!this.mqtt.disabled) return this.headers
else {
const headersCopy = [...this.headers]
headersCopy.splice(2, 1) // remove topic header
return headersCopy
}
},
secure () {
if (!this.mqtt.host) return false
const parsed = parse(this.mqtt.host)
Expand Down Expand Up @@ -587,7 +614,7 @@ export default {
{ text: 'Post Operation', value: 'postOperation' },
{ text: 'Poll', value: 'enablePoll' },
// { text: 'Changes', value: 'verifyChanges' },
{ text: 'Actions', sortable: false }
{ text: 'Actions', value: 'actions', sortable: false }
],
e1: true,
gw_types: [
Expand Down
10 changes: 8 additions & 2 deletions src/components/dialogs/DialogGatewayValue.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@
</template>
</v-select>
</v-col>
<v-col cols="12">
<v-col
v-if="!this.mqtt.disabled && this.gateway.hassDiscovery"
cols="12"
>
<v-select
v-model="editedValue.device_class"
label="Device Class"
Expand All @@ -72,7 +75,7 @@
label="Device Icon"
></v-text-field>
</v-col>
<v-col cols="12">
<v-col v-if="!this.mqtt.disabled" cols="12">
<v-text-field
v-model.trim="editedValue.topic"
label="Topic"
Expand Down Expand Up @@ -196,6 +199,8 @@ import 'prismjs/components/prism-clike'
import 'prismjs/components/prism-javascript'
import 'prismjs/themes/prism-tomorrow.css' // import syntax highlighting styles
import { mapGetters } from 'vuex'
export default {
components: {
PrismEditor
Expand All @@ -217,6 +222,7 @@ export default {
}
},
computed: {
...mapGetters(['gateway', 'mqtt']),
deviceValues () {
const device = this.devices.find(d => d.value == this.editedValue.device) // eslint-disable-line eqeqeq
return device ? device.values : []
Expand Down
Loading

0 comments on commit 24f9daa

Please sign in to comment.