-
Notifications
You must be signed in to change notification settings - Fork 17
/
example_json.ex
109 lines (97 loc) · 2.61 KB
/
example_json.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
defmodule Parser do
use Platform.Parsing.Behaviour
require Logger
#
# ELEMENT IoT Example parser for parsing json from a packet
#
# Name: Example parser for parsing packets with json payload encoding.
# Changelog:
# 2020-12-10 [jb]: Initial implementation for payload_encoding=json
# 2021-08-10 [jb]: Added handling of "utf8" payload encodings, like from MQTT driver.
# 2023-02-08 [jb]: Added config.merge_previous=false option for merging previous reading.
#
def config() do
%{
# Will merge the previous reading.
merge_previous: false
}
end
def config(key, meta), do: get(meta, [:_config, key], Map.get(config(), key))
# Using matching
def parse(json, %{payload_encoding: encoding} = meta) do
case to_string(encoding) do
"json" ->
# Already parsed to data. Not a string anymore.
json
|> merge_previous(meta)
"utf8" ->
json
|> to_string
|> json_decode
|> case do
{:ok, data} ->
data
|> merge_previous(meta)
{:error, error} ->
%{json_error: error}
end
other ->
%{error: "unknown payload_encoding: #{other}"}
end
end
def parse(payload, meta) do
Logger.warn(
"Could not parse payload #{inspect(payload)} with frame_port #{inspect(get_in(meta, [:meta, :frame_port]))}"
)
[]
end
def merge_previous(row, meta) do
case config(:merge_previous, meta) do
true ->
case get_last_reading(meta, []) do
%{data: data} when is_map(data) -> Map.merge(data, row)
_ -> row
end
_ ->
row
end
end
def tests() do
[
{
:parse_json,
"{\"a\":42,\"b\":true,\"c\":\"hello\"}",
%{payload_encoding: "json"},
%{"a" => 42, "b" => true, "c" => "hello"}
},
{
:parse,
"{\"a\":42,\"b\":true,\"c\":\"hello\"}",
%{payload_encoding: "utf8"},
%{"a" => 42, "b" => true, "c" => "hello"}
},
{
:parse,
"{invalid_json+-%&/(",
%{payload_encoding: "utf8"},
%{json_error: {:invalid, "i", 1}}
},
{
:parse,
"42",
%{payload_encoding: "hey"},
%{error: "unknown payload_encoding: hey"}
},
{
:parse_json,
"{\"a\":42,\"b\":true,\"c\":\"hello\"}",
%{
payload_encoding: "json",
_last_reading: %{data: %{"hey" => 1337}},
_config: %{merge_previous: true}
},
%{"a" => 42, "b" => true, "c" => "hello", "hey" => 1337}
}
]
end
end