docs: function MQTTMsgBusValueNode(config) {
          RED.nodes.createNode(this, config)
          console.log("MQTTMsgBusValueNode(): config =", config)
  
          this.qos        = 0
          this.retain     = false
          this.nodename   = config.nodename
          this.service    = config.service
          this.dataId     = config.dataid
          this.dataType   = config.dataType
          this.event      = config.event
          this.subscribed = false
          this.lastVal    = {}
  
          this.client     = config.client
          this.clientConn = RED.nodes.getNode(this.client)
          //console.log("MQTTMsgBusValueNode(): this.clientConn =", this.clientConn)
  
          if (!this.clientConn) {
              //console.log("MQTTMsgBusValueNode(): !this.clientConn, dataId =", this.dataId)
              this.error(RED._("msgbus.errors.missing-config"))
              return
          }
  
          //this.nodenameSelf   = this.clientConn.nodename
  
          this.broker         = this.clientConn.broker
          this.brokerConn     = RED.nodes.getNode(this.broker)
  
          var node = this
  
          if (this.brokerConn) {
              this.status({fill:"red", shape:"ring", text:"node-red:common.status.disconnected"})
  
              node.brokerConn.register(this)
  
              if (    this.subscribed == false && 
                      typeof this.nodename !== 'undefined' && 
                      this.nodename != "" &&
                      typeof this.dataId !== 'undefined' && 
                      this.dataId != "") {
  
                  this.topic      = topicValueSubscribe(this.clientConn, this.nodename, this.dataId, "+")
                  this.subscribed = true
  
                  console.log("MQTTMsgBusValueNode(1): dataid =", this.dataId)
                  console.log("MQTTMsgBusValueNode(1): topic  =", this.topic)
  
                  this.brokerConn.subscribe(this.topic, this.qos, function(topic, payload, packet) {
                      console.log("MQTTMsgBusValueNode(1): payload =", payload.toString())
                      onValueHandler(node, node.brokerConn, topic, payload)
                  }, this.id)
              }
  
              if (this.brokerConn.connected) {
                  node.status({fill:"green", shape:"dot", text:"node-red:common.status.connected"})
              }
  
              this.on("input", function(msg) {
                  console.log("MQTTMsgBusValueNode(): msg =", msg)
                  //console.log("MQTTMsgBusValueNode(): hap =", msg.hap.characteristic.props)
  
                  var chk = 0
  
                  if (msg.hasOwnProperty("model")) {
                      chk++                                   // becomes 'nodename'
                  }
                  if (msg.hasOwnProperty("serialno")) {       // becomes 'dataId'
                      chk++
                  }
                  if (msg.hasOwnProperty("format")) {         // becomes 'dataType'
                      chk++
                  }
                  if (msg.hasOwnProperty("event")) {
                      chk++
                  }
  
                  var nodename = msg.model
                  var dataId   = msg.serialno
                  var dataType = msg.hap.characteristic.props.format
                  
                  if (chk == 4) {
                      if (    node.subscribed == false && 
                              typeof nodename !== 'undefined' && 
                              nodename != "" &&
                              typeof dataId !== 'undefined' && 
                              dataId != "" &&
                              typeof dataType !== 'undefined') {
                                  
                          node.topic      = topicValueSubscribe(node.clientConn, nodename, dataId, "+")
                          node.subscribed = true
  
                          console.log("MQTTMsgBusValueNode(2): dataId =", dataId)
                          console.log("MQTTMsgBusValueNode(2): topic  =", node.topic)
  
                          node.brokerConn.subscribe(node.topic, node.qos, function(topic, payload, packet) {
                              console.log("MQTTMsgBusValueNode(2): payload =", payload.toString())
                              onValueHandler(node, node.brokerConn, topic, payload)
                          }, this.id)
                      }
  
                      console.log("MQTTMsgBusValueNode(): node.lastVal =", node.lastVal)
  
                      var event         = msg.event.toLowerCase()
                      var topicNotExist = node.lastVal[event] === undefined
                      
                      if (!topicNotExist) {
                          if (node.lastVal[event] != msg.payload) {
                              console.log("MQTTMsgBusValueNode(): unequal")
                              node.lastVal[event] = msg.payload
                          } else {
                              console.log("MQTTMsgBusValueNode(): equal, not sending")
                              return
                          }
                      } else {
                          console.log("MQTTMsgBusValueNode(): not exist")
                          node.lastVal[event] = msg.payload
                      }
                  } else {
  
                  }
    
                  var d = {
                      "d": {
                          "_type":    msg.event.toLowerCase(),
                          "value":    msg.payload
                      }
                  }
  
                  //
                  // build topic
                  //
                  var topic = topicValuePublish(node.clientConn, node.nodename, dataId, dataType)
  
                  var m = {}
                  m.topic   = topic
                  m.payload = JSON.stringify(d)
                  m.qos     = node.qos
                  m.retain  = node.retain
  
                  console.log("MQTTMsgBusValueNode(publish): msg =", m)
                  node.brokerConn.publish(m)  // send the message
              })
  
              this.on('close', function(done) {
                  if (node.brokerConn) {
                      node.brokerConn.unsubscribe(node.topic, node.id)
                      node.brokerConn.deregister(node, done)
                  }
              })
          } else {
              this.error(RED._("msgbus.errors.missing-config"))
          }
  
      }