Skip to content

Commit

Permalink
Merge pull request #1572 from bartbutenaers/ui-switch-sync-issue
Browse files Browse the repository at this point in the history
ui-switch: sync issue
  • Loading branch information
joepavitt authored Jan 10, 2025
2 parents 6e66c17 + 1d95f57 commit 69faee5
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 6 deletions.
11 changes: 9 additions & 2 deletions docs/contributing/guides/registration.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ Similar to `onAction`, when used as a boolean, this flag will trigger the defaul
2. Appends any `msg.topic` defined on the node config
3. Runs `evts.beforeSend()` _(if provided)_
4. Store the most recent message on the widget under the `._msg` property which will contain the latest state/value of the widget
5. Sends the `msg` onwards to any connected nodes
5. Pushes a `widget-sync` event to synchronize the widgets in all clients.
6. Sends the `msg` onwards to any connected nodes

#### Custom `onChange` Handler

Expand All @@ -111,8 +112,10 @@ Alternatively, you can override this default behaviour by providing a custom `on
* Handle the input from the widget
* @param {object} msg - the last known msg received (prior to this new value)
* @param {boolean} value - the updated value sent by the widget
* @param {Socket} conn - socket.io socket connecting to the server
* @param {String} id - widget id sending the action
*/
onChange: async function (msg, value) {
onChange: async function (msg, value, conn, id) {
// ensure we have latest instance of the widget's node
const wNode = RED.nodes.getNode(node.id)

Expand All @@ -127,6 +130,10 @@ onChange: async function (msg, value) {
const off = RED.util.evaluateNodeProperty(config.offvalue, config.offvalueType, wNode)
msg.payload = value ? on : off

// sync this change to all clients with the same widget
const exclude = [conn.id]
base.emit('widget-sync:' + id, msg, node, exclude)

// simulate Node-RED node receiving an input
wNode.send(msg)
}
Expand Down
4 changes: 2 additions & 2 deletions nodes/config/ui_base.js
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ module.exports = function (RED) {

msg = addConnectionCredentials(RED, msg, conn, n)

async function defaultHandler (msg, value) {
async function defaultHandler (msg, value, conn, id) {
if (typeof (value) === 'object' && value !== null && hasProperty(value, 'payload')) {
msg.payload = value.payload
} else {
Expand All @@ -673,7 +673,7 @@ module.exports = function (RED) {
// Most of the time, we can just use this default handler,
// but sometimes a node needs to do something specific (e.g. ui-switch)
const handler = typeof (widgetEvents.onChange) === 'function' ? widgetEvents.onChange : defaultHandler
await handler(msg, value)
await handler(msg, value, conn, id)
} catch (error) {
console.log(error)
let errorHandler = typeof (widgetEvents.onError) === 'function' ? widgetEvents.onError : null
Expand Down
8 changes: 6 additions & 2 deletions nodes/widgets/ui_switch.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = function (RED) {

// which group are we rendering this widget
const group = RED.nodes.getNode(config.group)
const base = group.getBase()

// retrieve the assigned on/off values
const on = RED.util.evaluateNodeProperty(config.onvalue, config.onvalueType, node)
Expand All @@ -27,7 +28,7 @@ module.exports = function (RED) {
const evts = {
// runs on UI interaction
// value = true | false from the ui-switch
onChange: async function (msg, value) {
onChange: async function (msg, value, conn, id) {
msg.payload = value ? on : off

if (config.topic || config.topicType) {
Expand All @@ -42,7 +43,10 @@ module.exports = function (RED) {
shape: 'ring',
text: value ? states[1] : states[0]
})
datastore.save(group.getBase(), node, msg)
datastore.save(base, node, msg)

const exclude = [conn.id] // sync this change to all clients with the same widget
base.emit('widget-sync:' + id, msg, node, exclude) // let all other connect clients now about the value change

// simulate Node-RED node receiving an input
node.send(msg)
Expand Down

0 comments on commit 69faee5

Please sign in to comment.