Как достать json‐данные из топика mqtt - d51x/openhab-docs-russian GitHub Wiki
Это требуется в том случае, если в топике mqtt данные передаются в формате json.
Например
{
"battery": 40,
"batteryLow": false,
"contact": false,
"linkQuality": 248,
"tamper": false
}
Нам нужно достать определенный параметр contact
Для этого используется транформация JSONPATH
Строка для трансофрмации выглядит следующим образом
JSONPATH:$.contact
Есть более сложны случай, когда в json лежит целый объект, а нам из объекта АМ2301
надо достать свойство Humidity
{
"Time": "2024-01-16T13:07:03",
"Switch1": "ON",
"Switch2": "OFF",
"ANALOG": {
"A0": 373
},
"AM2301": {
"Temperature": 22.1,
"Humidity": 56.6,
"DewPoint": 13.1
},
"PCF8574-1": {
"D0": 1,
"D1": 1,
"D2": 1,
"D3": 1,
"D4": 1,
"D5": 1,
"D6": 1,
"D7": 1
},
"TempUnit": "C"
}
Строка для трансофрмации выглядит следующим образом
JSONPATH:$.AM2301.Humidity
Есть еще более сложные случаи, когда в json передам массив объектов и нам надо достать определенный объект из массива по какому-то атрибуту объекта. Например, name = WallSwitchCorridor
,
{
"devices": [
{
"active": true,
"description": "Heiman Smoke Detector HS1SA",
"firmware": "1.1.1",
"ieeeAddress": "00:0d:6f:00:0e:f3:e2:38",
"interviewFinished": true,
"lastSeen": 1704869813,
"linkQuality": 40,
"logicalType": 2,
"manufacturerCode": 4619,
"manufacturerName": "HEIMAN",
"modelName": "SmokeSensor-EM",
"networkAddress": 1146,
"powerSource": 3,
"supported": true,
"version": 18
},
{
"active": true,
"description": "Heiman Smoke Detector HS1SA",
"firmware": "1.1.1",
"ieeeAddress": "00:0d:6f:00:12:24:ce:64",
"interviewFinished": true,
"lastSeen": 1705396491,
"linkQuality": 140,
"logicalType": 2,
"manufacturerCode": 4619,
"manufacturerName": "HEIMAN",
"modelName": "SmokeSensor-EM",
"name": "SmokeSensor_Room_Banya",
"networkAddress": 34050,
"powerSource": 3,
"supported": true,
"version": 18
},
{
"ieeeAddress": "00:12:4b:00:09:fe:24:da",
"name": "Socket Plug 1 Life Control",
"networkAddress": 51771,
"removed": true
},
{
"active": true,
"description": "Sonoff 1-Channel Relay ZBMINI",
"ieeeAddress": "00:12:4b:00:24:c0:2a:d7",
"interviewFinished": true,
"lastSeen": 1705398144,
"linkQuality": 72,
"logicalType": 1,
"manufacturerCode": 4742,
"manufacturerName": "SONOFF",
"modelName": "01MINIZB",
"name": "WallSwitchCorridor",
"networkAddress": 20309,
"powerSource": 1,
"supported": true
}
]
}
Строка для трансофрмации вернет целый объект из массива
JSONPATH:$.devices.[?(@.name=="WallSwitchCorridor")]
А следующая строка трансформации уже вернет конкретный атрибут powerSource
JSONPATH:$.devices.[?(@.name=="WallSwitchCorridor")].powerSource
Может оказаться так, что мы пытаемся обратиться к атрибуту, которого нет в json.
В этом случае в логах будут сыпаться ошибки.
Чтобы их не было, можно использовать цепочку трансформаций, используя знак связывания ∩
REGEX:(.*WallSwitchRoom.*)∩JSONPATH:$.devices.[?(@.name=="WallSwitchRoom")].lastSeen
В данном примере мы проверяем, есть ли вообще в json WallSwitchRoom
. Делается это первой трансформацией REGEX
.
Так мы достанем атрибут lastSeen
из объекта массива.
Но опять же может получиться так, что объект в массиве будет, но у него не будет атрибута lastSeen
, поэтому усложним конструкцию, чтобы не было warnings в логах.
REGEX:(.*WallSwitchRoom.*)∩JSONPATH:$.devices.[?(@.name=="WallSwitchRoom")]∩REGEX:(.*lastSeen.*)∩JSONPATH:$.lastSeen
В данном примере используется цепочка из 4-х трансофрмаций:
- проверяет наличие
WallSwitchRoom
- достает из массива объект по атрибуту
- проверяет в полученном объекте наличие атрибута
lastSeen
- достает из объекта п.2 (не из всего массива) атрибут