Node-Red configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ui_switch.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. const datastore = require('../store/data.js')
  2. const { appendTopic } = require('../utils/index.js')
  3. module.exports = function (RED) {
  4. function SwitchNode (config) {
  5. // create node in Node-RED
  6. RED.nodes.createNode(this, config)
  7. const node = this
  8. node.status({})
  9. const states = ['off', 'on']
  10. // which group are we rendering this widget
  11. const group = RED.nodes.getNode(config.group)
  12. const evts = {
  13. // runs on UI interaction
  14. // value = true | false from the ui-switch
  15. onChange: async function (msg, value) {
  16. // ensure we have latest instance of the widget's node
  17. const wNode = RED.nodes.getNode(node.id)
  18. // retrieve the assigned on/off value
  19. const on = RED.util.evaluateNodeProperty(config.onvalue, config.onvalueType, wNode)
  20. const off = RED.util.evaluateNodeProperty(config.offvalue, config.offvalueType, wNode)
  21. msg.payload = value ? on : off
  22. if (config.topic || config.topicType) {
  23. msg = await appendTopic(RED, config, node, msg)
  24. }
  25. if (!config.passthru && config.decouple) {
  26. wNode.send(msg)
  27. } else {
  28. node.status({
  29. fill: value ? 'green' : 'red',
  30. shape: 'ring',
  31. text: value ? states[1] : states[0]
  32. })
  33. datastore.save(group.getBase(), node, msg)
  34. // simulate Node-RED node receiving an input
  35. wNode.send(msg)
  36. }
  37. },
  38. onInput: async function (msg, send) {
  39. let error = null
  40. // ensure we have latest instance of the widget's node
  41. const wNode = RED.nodes.getNode(node.id)
  42. // retrieve the assigned on/off value
  43. const on = RED.util.evaluateNodeProperty(config.onvalue, config.onvalueType, wNode)
  44. const off = RED.util.evaluateNodeProperty(config.offvalue, config.offvalueType, wNode)
  45. if (msg.payload === undefined) {
  46. // may be setting class dynamically or something else that doesn't require a payload
  47. datastore.save(group.getBase(), node, msg)
  48. if (config.passthru) {
  49. send(msg)
  50. }
  51. } else {
  52. if (typeof msg.payload === 'object') {
  53. if (JSON.stringify(msg.payload) === JSON.stringify(on)) {
  54. msg.payload = on
  55. } else if (JSON.stringify(msg.payload) === JSON.stringify(off)) {
  56. msg.payload = off
  57. } else {
  58. // throw Node-RED error
  59. error = 'Invalid payload value'
  60. }
  61. } else {
  62. if (msg.payload === true || msg.payload === on) {
  63. msg.payload = on
  64. } else if (msg.payload === false || msg.payload === off) {
  65. msg.payload = off
  66. } else {
  67. // throw Node-RED error
  68. error = 'Invalid payload value'
  69. }
  70. }
  71. if (!error) {
  72. // store the latest msg passed to node
  73. datastore.save(group.getBase(), node, msg)
  74. node.status({
  75. fill: (msg.payload === true || msg.payload === on) ? 'green' : 'red',
  76. shape: 'ring',
  77. text: (msg.payload === true || msg.payload === on) ? states[1] : states[0]
  78. })
  79. if (config.passthru) {
  80. send(msg)
  81. }
  82. } else {
  83. const err = new Error(error)
  84. err.type = 'warn'
  85. throw err
  86. }
  87. }
  88. },
  89. beforeSend: async function (msg) {
  90. // ensure we have latest instance of the widget's node
  91. const wNode = RED.nodes.getNode(node.id)
  92. msg = await appendTopic(RED, config, wNode, msg)
  93. return msg
  94. }
  95. }
  96. const on = RED.util.evaluateNodeProperty(config.onvalue, config.onvalueType, node)
  97. const off = RED.util.evaluateNodeProperty(config.offvalue, config.offvalueType, node)
  98. config.evaluated = {
  99. on,
  100. off
  101. }
  102. // inform the dashboard UI that we are adding this node
  103. group.register(node, config, evts)
  104. }
  105. RED.nodes.registerType('ui-switch', SwitchNode)
  106. }