-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.go
More file actions
151 lines (131 loc) · 3.67 KB
/
parser.go
File metadata and controls
151 lines (131 loc) · 3.67 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package gojs
import (
"fmt"
"github.com/dop251/goja"
)
// ParseResult 数据处理函数返回结果数据格式
type ParseResult struct {
// 设备ID
ID string `json:"id"`
// 设备所属工作表标识
Table string `json:"table"`
// 子设备ID
CID string `json:"cid"`
// 上数时间
Time int64 `json:"time"`
// 数据点信息
// key: 数据点标识
// value: 数据点的值
Values map[string]interface{} `json:"values"`
}
type Parser struct {
IDKey string `json:"id"`
TableKey string `json:"table"`
CIDKey string `json:"cid"`
TimeKey string `json:"time"`
ValuesKey string `json:"values"`
}
func NewParser() *Parser {
return &Parser{
IDKey: "id",
TableKey: "table",
CIDKey: "cid",
TimeKey: "time",
ValuesKey: "values",
}
}
// Parse 解析脚本返回值.
// 从返回值中解析出设备编号, 表标识, 时间和数据等信息
func (p Parser) Parse(result goja.Value) ([]ParseResult, error) {
if !IsValid(result) {
return nil, nil
}
obj, ok := result.(*goja.Object)
if !ok {
return nil, fmt.Errorf("脚本返回值不是有效的对象")
}
if obj.ClassName() != "Array" {
return nil, fmt.Errorf("不是有效的数组")
}
keys := obj.Keys()
results := make([]ParseResult, 0, len(keys))
for _, key := range keys {
value, ok := obj.Get(key).(*goja.Object)
if !ok {
return nil, fmt.Errorf("数组内的元素不是有效的对象")
}
id := value.Get(p.IDKey)
table := value.Get(p.TableKey)
time := value.Get(p.TimeKey)
cid := value.Get(p.CIDKey)
values := value.Get(p.ValuesKey)
if !IsValid(id) {
return nil, fmt.Errorf("数组内的元素 [%s] 缺少 id 字段", key)
}
if !IsValid(values) {
return nil, fmt.Errorf("数组内的元素 [%s] 缺少 values 字段", key)
}
idStr, ok := id.Export().(string)
if !ok {
return nil, fmt.Errorf("数组内的元素 [%s] 的 id 字段 %v 不是有效的字符串", key, id.Export())
}
var tableId string
if IsValid(table) {
v, ok := table.Export().(string)
if !ok {
return nil, fmt.Errorf("数组内的元素 [%s] 的 table 字段 %v 不是有效的字符串", key, table.Export())
}
tableId = v
}
valuesObj, ok := values.(*goja.Object)
if !ok {
return nil, fmt.Errorf("数组内的元素 [%s] 的 values 字段不是有效的对象", key)
}
if !IsValid(valuesObj) {
return nil, fmt.Errorf("数组内的元素 [%s] 的 values 字段不是有效的对象", key)
}
cidValue := ""
if IsValid(cid) {
v, ok := cid.Export().(string)
if !ok {
return nil, fmt.Errorf("数组内的元素 [%s] 的 cid 字段 %v 不是有效的字符串", key, cid.Export())
}
cidValue = v
}
var timeValue int64
if IsValid(time) {
if v, ok := time.Export().(int64); ok {
timeValue = v
} else if v, ok := time.Export().(float64); ok {
timeValue = int64(v)
} else {
return nil, fmt.Errorf("数组内的元素 [%s] 的 time 字段 %v 不是有效的时间戳(ms)", key, time.Export())
}
}
valueKeys := valuesObj.Keys()
fieldValues := make(map[string]interface{}, len(valueKeys))
for _, fieldKey := range valueKeys {
fieldValue := valuesObj.Get(fieldKey)
if !IsValid(fieldValue) {
continue
}
if IsBuffer(fieldValue) {
bytes, err := BufferToBytes(fieldValue)
if err != nil {
return nil, fmt.Errorf("数组内的元素 [%s] 的 values 字段的 [%s] 字段不是有效的 Buffer", key, fieldKey)
}
fieldValues[fieldKey] = bytes
} else {
fieldValues[fieldKey] = fieldValue.Export()
}
}
results = append(results, ParseResult{
ID: idStr,
Table: tableId,
CID: cidValue,
Time: timeValue,
Values: fieldValues,
})
}
return results, nil
}