modbus2mqtt - 双向 Modbus 到 MQTT 桥接器

modbus2mqtt 允许您将任何具有 Modbus 功能的设备(以太网/USB/串口)在 MQTT 中可用并可操作。

它带有以下设备的 JSON 定义文件:

您可以轻松地为自己的设备添加 JSON 定义文件。

Docker 容器使用

有一个专门为 64 位 ARM 架构设计的 Docker 镜像可用。 该镜像与包括 Raspberry Pi、Apple Silicon Macs 和其他 64 位 ARM 计算机在内的一系列设备兼容。 可以使用以下命令直接使用它:

	docker run --name modbus2mqtt \
		jollyjinx/modbus2mqtt:latest modbus2mqtt \
		--modbus-server lambda \
		--topic lambda \
		--device-description-file lambda.json

这将为 Lambda 热泵运行 modbus2mqtt,并将值输出到 MQTT 服务器主题 /lambda。 如果未指定 MQTT 服务器,则使用名为 *mqtt* 的服务器。

这将在 *MQTT Explorer* 或 *node-red* 中如下所示:

MQTT Explorer ScreenshotMQTT Explorer Screenshot

您可以使用以下命令创建自己的 Docker 容器:

    docker build . --file modbus2mqtt.product.dockerfile --tag modbus2mqtt
    docker run --name modbus2mqtt modbus2mqtt --modbus-server lambda --device-description-file lambda.json --topic lambda

JSON 定义文件

设置您自己的 modbus2mqtt 定义文件很容易。 JSON 定义文件如下所示:

{
  {
    "address": 40631,                   // modbus address
    "modbustype": "holding",            // holding,coil,
    "modbusaccess": "readwrite",        // read/write/readwrite
    "valuetype": "string",              // string, ipv4address, macaddress, uint8, int8, uint16,...
    "length": 24,                       // strings need a length
    "interval": 1000,                   // interval being updated in seconds (decimal value like 0.2 possible)
                                        // interval of 0 means it will be requested only at start and then 
                                        // using mqtt retain to retain it.
    "mqtt": "visible",                  // if shown in mqtt visible/invisible/retained
    "topic": "settings/name",           // topic to post values
    "title": "Name"                     // description for gui (like node-red)
  },
  {
    "address": 30581,
    "modbustype": "holding",
    "modbusaccess": "read",
    "valuetype": "uint32",  
    "factor": 0.001,                    // factor to multiply by
    "unit": "kWh",                      // unit for gui
    "mqtt": "visible",
    "interval": 1000,
    "topic": "counter/totalusage",
    "title": "Total Yield"
  },
  {
    "address": 1,
    "modbustype": "holding",
    "modbusaccess": "read",
    "valuetype": "uint16",
    "mqtt": "visible",
    "interval": 5,
    "map": {                            // you can add mappings for values
        "0": "OFF",                     // so value will be "AUTOMATIC" if the 
        "1": "AUTOMATIK",               // raw value is 1
        "2": "MANUAL",                  // original values can then be accessed with  
        "3": "ERROR"                    // "rawValue" key in the output
    },
    "topic": "ambient/operatingstate",
    "title": "Ambient Operating State"
  },
  {
    "address": 2,
    "modbustype": "holding",
    "modbusaccess": "read",
    "valuetype": "uint16",
    "mqtt": "visible",
    "interval": 5,
    "bits": {                            // you can bit mappings for values
        "0": { "name" : "running" },     // a single bit will be mapped to a boolean
        "1-3": { "name" : "mode" },      // multiple values will be mapped to the integer number with those bits shifted to the right
        "4-15": { "name" : "reserved" }  
    },
    "topic": "test/state",
    "title": "Test State"
  }
}

注意:请注意,JSON 不支持像本例中的注释。 创建您自己的 JSON 定义后,可以使用命令行选项 --device-description-file yourfilename 来使用它。

桥接是双向的

modbus2mqtt 是一个桥接器,它不仅允许 Modbus 设备显示在 MQTT 中,还允许从 MQTT 向 Modbus 设备写入值。 它使用请求/响应模式。 您将 MQTT 请求发送到 MQTT 请求主题,并在响应主题路径中获得请求的结果。

要将 HM310T 的输出电压设置为 14.04 伏,您可以发送以下 JSON:

{
  "value": 14.04,
  "date": "2022-10-21T08:43:22Z",
  "topic": "set/voltage",
  "id": "D2129DBF-9F94-46D7-86BC-4A07152FF1D8"
}

到 MQTT 服务器的 *hm310/request/mychange* 主题。 该桥将接收该请求并将响应返回到响应主题 *hm310/response/mychange*。 请注意,您设置的值为 14.04,它将正确转换为特定 Modbus 地址的 (u)int16 值。

在 Swift 中,请求/响应定义如下。

struct MQTTRequest:Encodable,Decodable,Hashable,Equatable
{
    let date:Date       // needs to be within request ttl time 
    let id:UUID
    let topic:String
    let value:MQTTCommandValue
}

struct MQTTResponse:Encodable,Decodable
{
    let date:Date
    let id:UUID         // same uuid of request
    let success:Bool
    let error:String?
}

状态

我正在我自己的 Modbus 设备上 24/7 使用它(我为之创建 JSON 定义的设备)。

启动应用程序

> modbus2mqtt --topic=sma/sunnystore \
              --modbus-server=sunnyboy.local \
              --mqtt-server=mqtt.local \
              --device-description-file=sma.sunnystore.json

它支持命令行帮助

> ./.build/release/modbus2mqtt --help 
USAGE: modbus2mqtt <options>

OPTIONS:
  --log-level <log-level> Set the log level. (default: notice)
  --mqtt-servername <mqtt-servername>
                          MQTT Server hostname (default: mqtt)
  --mqtt-port <mqtt-port> MQTT Server port (default: 1883)
  --mqtt-username <mqtt-username>
                          MQTT Server username
  --mqtt-password <mqtt-password>
                          MQTT Server password
  --emit-interval <emit-interval>
                          Minimum interval to send updates to mqtt Server.
                          (default: 0.1)
  -t, --topic <topic>     MQTT Server topic. (default: modbus/sunnyboy)
  --mqtt-request-ttl <mqtt-request-ttl>
                          Maximum time a mqttRequest can lie in the future/past
                          to be accepted. (default: 10.0)
  --mqtt-auto-retain-time <mqtt-auto-retain-time>
                          If mqttTopic has a refreshtime larger than this value
                          it will be retained. (default: 10.0)
  --modbus-device-path <modbus-device-path>
                          Serial Modbus Device path
  --modbus-serial-speed <modbus-serial-speed>
                          Serial Modbus Speed (default: 9600)
  -m, --modbus-server <modbus-server>
                          Modbus Device Servername. (default:
                          modbus.example.com)
  --modbus-port <modbus-port>
                          Modbus Device Port number. (default: 502)
  --modbus-address <modbus-address>
                          Modbus Device Address. (default: 3)
  --device-description-file <device-description-file>
                          Modbus Device Description file (JSON). (default:
                          sma.sunnyboy.json)
  -h, --help              Show help information.

欢迎反馈

如果您为自己的设备添加了 JSON 定义,请创建 pull requests。