0.0.9 • Published 5 months ago

@uboness/knx2mqtt v0.0.9

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

@uboness/knx2mqtt

A KNX to MQTT bridge

!!! Experimental !!!

(heavily inspired by knx-mqtt-bridge)

!!! Experimental !!!

  • This is an experimental project
  • Use at your own risk
  • Don't rely on support
  • You can submit bugs / feature req. / etc... though response to those submission is not guaranteed
  • What to do with bugs and lack of response?... you can clone this repo and fix it yourself :)

Install

npm install -g @uboness/knx2mqtt

Setup

knx2mqtt expect a configuration directory. You can either pass the location of this config dir as argument. When not passed as an argument, it'll try to resolve the following dirs (in the following order):

  • <cwd>/config - will look for a config dir under the current working directory
  • <user_home>/.knx2mqtt - will look for a .knx2mqtt dir under the user home dir

When passing the config dir as an argument, if the dir starts with / it'll be treated as an absolute path, otherwise it'll be treated as a relative path to the current working directory (cwd).

So:

Do this to specify a custom config dir:

knx2mqtt -c /some/path/to/config

Do this to fall on the default config dir (either under the cwd or under the user home):

knx2mqtt

Configuration

The config dir should typically have two files:

  • config.yaml - the main configuration file
  • <ets-export>.xml - an etx group export file that will be loaded (the exact name of this file is up to you.. should be set in config.yaml);

config.yaml

Here's a typical config.yaml file:

mqtt:
  host: <ip/host>
  auth:
    username: <string>
    password: <string>

knx:
  ipAddr: <knx-gateway-ip>
  physAddr: <knx-physical-address>

bridge:
  ets: <path-to-ets-export-file>

log:
  _level: <default-log-lvel>
  bus: <custom-log-level>
keytypeRequiredDescription
http.portstringoptionalThe http server port (default: 8732)
mqtt.hoststringrequiredThe IP/host of the mqtt server
mqtt.authobjectoptionalThe username/password to authenticate to the MQTT server (if enabled)
mqtt.auth.usernamestringrequiredThe username for the MQTT server
mqtt.auth.passwordstringrequiredThe password for the MQTT server
mqtt.baseTopicstringoptionalThis will be the base topic under which all other topics will be created (default: knx)
knx.hoststringrequiredThe IP/host address of the KNX IP-Gateway
knx.physAddrstringrequiredThe physical address that should be used for knx2mqtt
bridge.etsstringrequiredThe ets group address export file (more on this below)
bridge.publish.gadbooleanoptionalIndicates whether the gad (group address) should be published as well (default: true)
log._levelstringoptionalThe default log level (one of trace, debug, info, warn, error or fatal
log.busstringoptionalWhen set to trace or debug all messages sent in the KNX bus will be logged
log.stringoptionalSets the log level for the given category (available categories: knx, mqtt and ets)

ETS file

This files contains the mappings of the KNX addresses, their data point types and their names as defined in ETS. It's easily exported from ETS:

  • Open Group Addresses Panel (Workspace > Open New Panel > Group Addresses)
  • On the sidebar, select all the top level Group Ranges
  • Right-click on the selection and click Excport Group Addresses, choose XML format.

The exported file is in XML format in the following structure:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<GroupAddress-Export>
  <GroupRange Name="main-range">
    <GroupRange Name="middle-range">
      <GroupAddress Name="device-name-and-property" Address="1/3/22" DPTs="DPT-1"/>
      <GroupAddress Name="device-name-and-property-status" Address="1/3/23" DPTs="DPT-1"/>
      ...
    </GroupRange>
    <GroupRange Name="middle-range2">

    </GroupRange>
    ...
  </GroupRange>
  <GroupRange Name="main-range2">
    ...
  </GroupRange>
</GroupAddress-Export>

Using this export file as is, is possible - just place it in the config dir and point to it in the config.yaml.

That said, it'll be better to edit it a bit and make sure all the naming of all addresses are consistent and are valid MQTT topic names. Also, while ETS will export max 2 levels of GroupRange element. knx2mqtt supports many levels - in fact, you can even have no group ranges and directly place all group addresses under GroupAddress-Export.

The way knx2mqtt will parse this export is as follows:

  • each name of a GroupRange element will be treated as a base topic to all the groups and/or addresses under it
  • each name of a GroupAddress element will be treated as the topic of the address.

This enables you to create logical grouping of addresses and avoid too long address names. Here's an example:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<GroupAddress-Export>
  <GroupRange Name="living-room">
    <GroupRange Name="light">
      <GroupAddress Name="ceiling/on" Address="1/3/22" DPTs="DPT-1"/>
      <GroupAddress Name="ceiling/on-status" Address="1/3/23" DPTs="DPT-1"/>
    </GroupRange>
  </GroupRange>
</GroupAddress-Export>

The above will be translated to the following topics in MQTT:

  • knx/living-room/ceiling/on will hold the value of 1/3/22 group address
  • knx/living-room/ceiling/on-status will hold the value of 1/3/23 group address

For those address that you can write to (e.g. knx/living-room/ceiling/on above), you can publish their value under a write topic which sit right under the relevant topic. For example, to turn on the ceiling light, just publish true to knx/living-room/ceiling/on/write.

You can request a fresh read for all addresses by publishing an value to read topic that sit right under the relevant topic. For example, to refresh the value of the ceiling status, publish true (or whatever value) to knx/living-room/ceiling/on-status/read

REST API

The base path for the API is /_api/v1 and the default port is 8732 (the port can be configured in the config file under the http.port key).

Most of the APIs (all except the SSE ones) accept a _human request parameter which will cause the returned JSON to be emitted in human friendly format.

Here are the available API endpoints:

GET /_api

Can be used as a "ping"" functionality to see if the service is up and running.

GET /_api/v1

Returns the general status of the server and the status of the different services

GET /_api/v1/_shutdown

Shuts down the knx2mqtt server. Since typically this will be installed as a service, shutting down the server will mostly be used to restart it.

GET /_api/v1/mapping

Returns the ETS mappings from KNX Group Address (gad) to MQTT topics, along with the current associated value. A single mapping is a JSON object which the following schema:

{
  topic: string,    // e.g. 'living-room/light/ceiling'
  gad: string ,     // e.g. '1/03/10'
  dpt: string,      // e.g. 'DPT1.001'
  value?: boolean | number | string | Date | null
}

It's possible to execute this call with the following two parameters:

  • topic - serves as a topic prefix to filter the mappings on the topic field
  • gad - will filter the mappings on the gad field

For example, the following call will only return the mappings associated with the living-room/# topic:

GET /_api/v1/mapping?topic=living-room?_human

GET /_api/v1/mqtt

Returns the current status of the MQTT service

GET /_api/v1/mqtt/event

Opens a SSE (Server Sent Event) stream where all the MQTT topic updates will be emitted.

POST /_api/v1/mqtt/topic

Publishes a value to a set of topics - all defined in the request body in the following schema:

[
    {
        topic: string,   // e.g. 'living-room/light/ceiling
        value: boolean | number | string | null
    },
    ...
]

GET /_api/v1/knx

Returns the current status of the KNX service

GET /_api/v1/knx/event

Opens a SSE (Server Sent Event) stream where all the KNX bus events will be emitted.

GET /_api/v1/knx/dpt

Returns all the open datapoints in the KNX service (these are based on the configured ETS mappings)

GET /_api/v1/knx/dpt/:gad

Returns the specific datapoint that is associated with the GAD (as specified in the URI)

POST /_api/v1/knx/dpt/:gad

Writes a value (as a JSON body) to the specified KNX GAD.

POST /_api/v1/knx/dpt/:gad/_read

Request the KNX to read the value of the specified KNX GAD.