1 contributor
158 lines | 7.403kb
<script type="text/x-red" data-template-name="z2m-zg-204zv-homebus">
  <div class="form-row">
    <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
    <input type="text" id="node-input-name" placeholder="Name">
  </div>
  <div class="form-row">
    <label for="node-input-batteryLowThreshold">Battery low threshold (%)</label>
    <input type="number" id="node-input-batteryLowThreshold" min="0" max="100" placeholder="20">
  </div>
  <div class="form-row">
    <label for="node-input-batteryType">Battery type</label>
    <select id="node-input-batteryType">
      <option value="alkaline">Alkaline</option>
      <option value="nimh">Rechargeable NiMH</option>
    </select>
  </div>
</script>

<script type="text/x-red" data-help-name="z2m-zg-204zv-homebus">
  <p>
    Translates Zigbee2MQTT messages for HOBEIAN <code>ZG-204ZV</code> into canonical HomeBus topics.
  </p>
  <p>
    Canonical topic shape:
    <code>&lt;site&gt;/home/&lt;location&gt;/&lt;capability&gt;/&lt;device_id&gt;/&lt;stream&gt;</code>
  </p>
  <p>
    Example outputs:
    <code>vad/home/living-room/motion/radar-south/value</code>,
    <code>vad/home/living-room/temperature/radar-south/value</code>,
    <code>vad/home/living-room/temperature/radar-south/last</code>,
    <code>vad/home/living-room/motion/radar-south/meta</code>
  </p>
  <h3>Input</h3>
  <p>
    Expected Zigbee2MQTT telemetry topic:
    <code>zigbee2mqtt/ZG-204ZV/&lt;site&gt;/&lt;location&gt;/&lt;device_id&gt;</code> with a JSON payload.
  </p>
  <p>
    Availability topic is also supported:
    <code>zigbee2mqtt/ZG-204ZV/&lt;site&gt;/&lt;location&gt;/&lt;device_id&gt;/availability</code> with payload <code>online</code> or <code>offline</code>.
  </p>
  <p>
    Typical subscription for this adapter:
    <code>zigbee2mqtt/ZG-204ZV/#</code>
  </p>
  <p>
    Output 2 controls a dynamic <code>mqtt in</code> node on the raw Zigbee2MQTT broker. On startup, the adapter emits
    <code>{ action: "subscribe", topic: "zigbee2mqtt/ZG-204ZV/#" }</code>.
  </p>
  <p>
    This node is intended to fan out traffic for multiple <code>ZG-204ZV</code> devices, not to be instantiated per device.
  </p>
  <p>
    The node status shows adapter statistics such as detected devices, processed inputs, translated publications,
    operational messages, and errors. Invalid topics, invalid messages, invalid payloads, and unmapped payloads are counted separately in the status text.
  </p>
  <p>
    Used fields: <code>presence</code>, <code>temperature</code>, <code>humidity</code>,
    <code>fading_time</code>, <code>illuminance</code>, <code>battery</code>, <code>battery_low</code>,
    <code>tamper</code>, <code>availability</code>, <code>online</code>.
  </p>
  <p>
    Battery translation can be configured for the installed cells. Default is <code>Alkaline</code>.
    When <code>Rechargeable NiMH</code> is selected, the adapter applies a curve-based remap to the incoming
    Zigbee battery percentage before publishing <code>battery</code> and deriving <code>battery_low</code>.
  </p>
  <p>
    The NiMH remap approximates an alkaline percentage to cell voltage and then projects that voltage onto a flatter
    NiMH discharge curve. If the device firmware starts reporting a better native percentage later, switch the adapter back to
    <code>Alkaline</code> to disable the translation.
  </p>
  <h3>Output</h3>
  <ol>
    <li>MQTT-ready publish messages, emitted as an array of messages on the semantic/output path.</li>
    <li><code>mqtt in</code> control messages for the raw Zigbee2MQTT subscription.</li>
  </ol>
  <p>
    Semantic bus messages are published in minimal form only:
    <code>msg.topic</code>, <code>msg.payload</code>, <code>msg.qos</code>, and <code>msg.retain</code>.
    Adapter internals such as vendor payload snapshots are not forwarded on the HomeBus output.
  </p>
  <p>
    Live telemetry is unified on <code>value</code>. The adapter publishes lightweight hot-path <code>value</code> updates and deduplicates them on change.
  </p>
  <p>
    Retained <code>last</code> carries the timestamped latest known sample for bootstrap and freshness evaluation.
  </p>
  <p>
    The <code>last</code> payload uses a small JSON envelope with <code>value</code> and <code>observed_at</code>. When the source does not provide a timestamp, the adapter uses ingestion time and marks <code>quality=estimated</code>.
  </p>
  <p>
    The node publishes retained <code>meta</code> and <code>availability</code> topics plus live
    <code>value</code> topics for the capabilities supported by this sensor, together with retained <code>last</code> for the latest timestamped sample.
  </p>
  <p>
    Operational topics are emitted on the same output under:
    <code>&lt;site&gt;/sys/adapter/z2m-zg-204zv/{availability,stats,error,dlq}</code>.
  </p>
  <p>
    The adapter identifier is fixed to <code>z2m-zg-204zv</code>. Device identity and <code>source_ref</code> are derived per message from the inbound topic or payload.
  </p>
  <p>
    Mapping:
    <code>presence/occupancy + fading_time=0 -&gt; motion/value</code>,
    <code>presence/occupancy + fading_time&gt;0 -&gt; presence/value</code>,
    <code>temperature -&gt; temperature/value</code>,
    <code>humidity -&gt; humidity/value</code>,
    <code>illuminance -&gt; illuminance/value</code>,
    <code>battery -&gt; battery/value</code>,
    <code>battery_low -&gt; battery_low/value</code>,
    <code>tamper -&gt; tamper/value</code>.
  </p>
  <p>
    For this mmWave device, raw Zigbee <code>presence</code> is converted to HomeBus <code>motion</code> when <code>fading_time</code> is <code>0</code>. Device-level <code>presence</code> is published only when the sensor is intentionally configured to hold presence with non-zero <code>fading_time</code>.
  </p>
  <p>
    Identity is resolved with priority:
    incoming topic, then message/payload fields, then fallback defaults
    <code>unknown/unknown/device_type</code>.
  </p>
  <p>
    With the recommended topic structure, <code>site</code>, <code>location</code>, <code>device_id</code>,
    and usually <code>source_ref</code> are inferred directly from the Zigbee2MQTT topic path.
  </p>
  <p>
    If this node is created from an older flow JSON, legacy fields
    <code>mqttBus</code>, <code>mqttRoom</code>, and <code>mqttSensor</code> are still accepted as fallbacks.
  </p>
  <p>
    Malformed or unmappable inputs are routed to adapter operational topics instead of being embedded into semantic bus payloads.
  </p>
  <p>
    Input validation is strict for the source topic. Non-conforming topics or payloads are also logged with <code>node.warn</code>/<code>node.error</code> in Node-RED so they are visible in flow messages in addition to <code>sys/adapter/z2m-zg-204zv/{error,dlq}</code>.
  </p>
</script>

<script>
  RED.nodes.registerType("z2m-zg-204zv-homebus", {
    category: "myNodes",
    color: "#d9ecfb",
    defaults: {
      name: { value: "" },
      batteryLowThreshold: { value: 20, validate: RED.validators.number() },
      batteryType: { value: "alkaline" },
      mqttBus: { value: "" },
      mqttRoom: { value: "" },
      mqttSensor: { value: "" }
    },
    inputs: 1,
    outputs: 2,
    icon: "font-awesome/fa-sitemap",
    label: function() {
      return this.name || "z2m-zg-204zv-homebus";
    },
    paletteLabel: "zg-204zv homebus"
  });
</script>