nayota-show-sdk 1.3.69 → 1.3.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/utils/iot-module-specs.js +140 -3
- package/utils/iot-module-specs.test.js +132 -0
package/package.json
CHANGED
|
@@ -160,6 +160,13 @@ function normalizeHierarchyFloorPlan(data = {}) {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
function mapDepartsToIotBody(data = {}) {
|
|
163
|
+
const hasParentId = Object.prototype.hasOwnProperty.call(data, 'parentId')
|
|
164
|
+
const hasFather = Object.prototype.hasOwnProperty.call(data, 'father')
|
|
165
|
+
const parentId = hasParentId
|
|
166
|
+
? data.parentId
|
|
167
|
+
: hasFather
|
|
168
|
+
? resolveLegacyReference(data.father)
|
|
169
|
+
: undefined
|
|
163
170
|
const metadata = mergeMetadata(data.metadata, {
|
|
164
171
|
mapCenter: data.mapCenter,
|
|
165
172
|
latlng: data.latlng,
|
|
@@ -183,7 +190,7 @@ function mapDepartsToIotBody(data = {}) {
|
|
|
183
190
|
'departNo'
|
|
184
191
|
]),
|
|
185
192
|
code: data.code || data.departNo || undefined,
|
|
186
|
-
parentId
|
|
193
|
+
parentId,
|
|
187
194
|
sortOrder: data.sortOrder != null ? data.sortOrder : data.sort,
|
|
188
195
|
isActive: data.isActive != null ? data.isActive : data.status,
|
|
189
196
|
floorPlan: normalizeHierarchyFloorPlan(data),
|
|
@@ -297,6 +304,136 @@ function mapDeviceEasyListRequest(data = {}) {
|
|
|
297
304
|
})
|
|
298
305
|
}
|
|
299
306
|
|
|
307
|
+
function normalizeLegacyCurrentValue(value) {
|
|
308
|
+
if (value && typeof value === 'object') {
|
|
309
|
+
if (value.value !== undefined) {
|
|
310
|
+
return value.value
|
|
311
|
+
}
|
|
312
|
+
if (value.currentValue !== undefined) {
|
|
313
|
+
return value.currentValue
|
|
314
|
+
}
|
|
315
|
+
if (value.label !== undefined) {
|
|
316
|
+
return value.label
|
|
317
|
+
}
|
|
318
|
+
if (value.valueStr !== undefined) {
|
|
319
|
+
return value.valueStr
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return value
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function normalizeLegacyValueStr(value, fallback = '') {
|
|
327
|
+
if (fallback !== undefined && fallback !== null && fallback !== '') {
|
|
328
|
+
return String(fallback)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (value && typeof value === 'object') {
|
|
332
|
+
if (value.valueStr !== undefined && value.valueStr !== null) {
|
|
333
|
+
return String(value.valueStr)
|
|
334
|
+
}
|
|
335
|
+
if (value.label !== undefined && value.label !== null) {
|
|
336
|
+
return String(value.label)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return ''
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function normalizeLegacyPropLine(source = {}, prop = {}, row = {}) {
|
|
344
|
+
if (typeof source.line === 'boolean') {
|
|
345
|
+
return source.line
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (typeof prop.line === 'boolean') {
|
|
349
|
+
return prop.line
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (typeof source.pointLine === 'boolean') {
|
|
353
|
+
return source.pointLine
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (typeof row.line === 'boolean') {
|
|
357
|
+
return row.line
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return null
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function normalizeLegacyEasyListProp(source = {}, row = {}) {
|
|
364
|
+
const prop = withLegacyId(source.prop || {})
|
|
365
|
+
const propId = source.propId || source.devicePropertyId || prop._id || source._id || source.id
|
|
366
|
+
const value = prop.value !== undefined
|
|
367
|
+
? prop.value
|
|
368
|
+
: source.value !== undefined
|
|
369
|
+
? source.value
|
|
370
|
+
: normalizeLegacyCurrentValue(source.rawValue)
|
|
371
|
+
const valueStr = normalizeLegacyValueStr(
|
|
372
|
+
source.rawValue,
|
|
373
|
+
prop.valueStr !== undefined ? prop.valueStr : source.valueStr
|
|
374
|
+
)
|
|
375
|
+
const valueAt = prop.valueAt || source.valueAt || source.lastSyncAt || source.lastUpdateAt || row.lineTime || ''
|
|
376
|
+
const interval = prop.interval || source.interval || source.valueMap || ''
|
|
377
|
+
const line = normalizeLegacyPropLine(source, prop, row)
|
|
378
|
+
const isMain = Boolean(source.isMain)
|
|
379
|
+
const isStatus = Boolean(source.isStatus)
|
|
380
|
+
const isNumber = Boolean(source.isNumber)
|
|
381
|
+
const isImport = Boolean(source.isImport || isMain || isStatus || isNumber)
|
|
382
|
+
|
|
383
|
+
const legacyProp = removeUndefinedFields({
|
|
384
|
+
...prop,
|
|
385
|
+
_id: propId,
|
|
386
|
+
deviceId: prop.deviceId || source.deviceId || '',
|
|
387
|
+
key: prop.key || source.propertyKey,
|
|
388
|
+
name: prop.name || source.propName || source.name || source.code || source.propertyKey,
|
|
389
|
+
shortAddress: prop.shortAddress || source.shortAddress,
|
|
390
|
+
line,
|
|
391
|
+
value,
|
|
392
|
+
valueStr,
|
|
393
|
+
unit: prop.unit != null ? prop.unit : source.unit,
|
|
394
|
+
company: prop.company || source.company,
|
|
395
|
+
valueMap: prop.valueMap !== undefined ? prop.valueMap : source.valueMap,
|
|
396
|
+
interval,
|
|
397
|
+
thresholdRules: prop.thresholdRules !== undefined ? prop.thresholdRules : source.thresholdRules,
|
|
398
|
+
valueAt,
|
|
399
|
+
sort: prop.sort !== undefined ? prop.sort : source.sort,
|
|
400
|
+
parent: prop.parent !== undefined ? prop.parent : source.parent,
|
|
401
|
+
parentName: prop.parentName || source.parentName
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
return removeUndefinedFields({
|
|
405
|
+
...source,
|
|
406
|
+
_id: source._id || source.id,
|
|
407
|
+
propId,
|
|
408
|
+
devicePropertyId: source.devicePropertyId || propId,
|
|
409
|
+
code: source.code || source.name || source.propertyKey,
|
|
410
|
+
propName: source.propName || source.name || prop.name || source.code || source.propertyKey,
|
|
411
|
+
isImport,
|
|
412
|
+
isMain,
|
|
413
|
+
isStatus,
|
|
414
|
+
isNumber,
|
|
415
|
+
line,
|
|
416
|
+
value,
|
|
417
|
+
valueStr,
|
|
418
|
+
interval,
|
|
419
|
+
valueAt,
|
|
420
|
+
prop: legacyProp
|
|
421
|
+
})
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function normalizeLegacyEasyListRow(item = {}) {
|
|
425
|
+
const row = withLegacyId(item)
|
|
426
|
+
const props = Array.isArray(row.props)
|
|
427
|
+
? row.props.map(prop => normalizeLegacyEasyListProp(prop, row))
|
|
428
|
+
: []
|
|
429
|
+
|
|
430
|
+
return removeUndefinedFields({
|
|
431
|
+
...row,
|
|
432
|
+
props,
|
|
433
|
+
lineTime: row.lineTime || props.find(prop => prop.isImport && prop.valueAt)?.valueAt || row.updatedAt || null
|
|
434
|
+
})
|
|
435
|
+
}
|
|
436
|
+
|
|
300
437
|
function hasOwn(value, key) {
|
|
301
438
|
return Object.prototype.hasOwnProperty.call(value || {}, key)
|
|
302
439
|
}
|
|
@@ -337,7 +474,7 @@ function normalizeLegacyUiRelation(relation = {}, fallbackType = 'ba_card') {
|
|
|
337
474
|
})
|
|
338
475
|
}
|
|
339
476
|
|
|
340
|
-
function
|
|
477
|
+
function resolveDigitalTwinTypeUiRelation(data = {}) {
|
|
341
478
|
if (hasOwn(data, 'uiId')) {
|
|
342
479
|
return data.uiId == null ? null : normalizeLegacyUiRelation({ uiId: data.uiId, ui: data.ui })
|
|
343
480
|
}
|
|
@@ -597,7 +734,7 @@ export const iotModuleSpecs = {
|
|
|
597
734
|
code: 0,
|
|
598
735
|
data: {
|
|
599
736
|
total: Number(data?.total ?? rows.length ?? 0),
|
|
600
|
-
rows: rows.map(item =>
|
|
737
|
+
rows: rows.map(item => normalizeLegacyEasyListRow(item))
|
|
601
738
|
}
|
|
602
739
|
}
|
|
603
740
|
}
|
|
@@ -93,3 +93,135 @@ describe('iotModuleSpecs deviceClass UI compatibility', () => {
|
|
|
93
93
|
])
|
|
94
94
|
})
|
|
95
95
|
})
|
|
96
|
+
|
|
97
|
+
describe('iotModuleSpecs departs hierarchy compatibility', () => {
|
|
98
|
+
const departs = iotModuleSpecs.departs.operations
|
|
99
|
+
|
|
100
|
+
test('does not send parentId for partial relationInfo updates', () => {
|
|
101
|
+
const request = departs.updateOne.toRequest({
|
|
102
|
+
_id: 'e245a3f6-d2c7-4ce1-9e02-ba9bbb347ed7',
|
|
103
|
+
relationInfo: {
|
|
104
|
+
image: {
|
|
105
|
+
imagePath: 'upload/2026/4/25/upload.svg'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
expect(request.url).toBe('/hierarchies/e245a3f6-d2c7-4ce1-9e02-ba9bbb347ed7')
|
|
111
|
+
expect(request.method).toBe('patch')
|
|
112
|
+
expect(request.data.parentId).toBeUndefined()
|
|
113
|
+
expect(request.data.relationInfo).toEqual({
|
|
114
|
+
image: {
|
|
115
|
+
imagePath: 'upload/2026/4/25/upload.svg'
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
test('keeps explicit legacy father null as root move', () => {
|
|
121
|
+
const request = departs.updateOne.toRequest({
|
|
122
|
+
_id: 'e245a3f6-d2c7-4ce1-9e02-ba9bbb347ed7',
|
|
123
|
+
father: null
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
expect(request.data.parentId).toBeNull()
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
describe('iotModuleSpecs devices easyList legacy compatibility', () => {
|
|
131
|
+
const easyList = iotModuleSpecs.devices.operations.easyList
|
|
132
|
+
|
|
133
|
+
test('normalizes iot easyList properties to the legacy BMS prop shape', () => {
|
|
134
|
+
const response = easyList.fromResponse({
|
|
135
|
+
code: 0,
|
|
136
|
+
data: {
|
|
137
|
+
total: 1,
|
|
138
|
+
rows: [
|
|
139
|
+
{
|
|
140
|
+
id: 'twin-1',
|
|
141
|
+
name: '会议室空调',
|
|
142
|
+
line: false,
|
|
143
|
+
props: [
|
|
144
|
+
{
|
|
145
|
+
id: 'twin-prop-mode',
|
|
146
|
+
propId: 'device-prop-mode',
|
|
147
|
+
propertyKey: 'mode',
|
|
148
|
+
name: '模式设定',
|
|
149
|
+
isStatus: true,
|
|
150
|
+
line: true,
|
|
151
|
+
value: 1,
|
|
152
|
+
valueStr: '制热',
|
|
153
|
+
interval: '[["制冷","制热"],[0,1]]',
|
|
154
|
+
valueAt: '2026-04-25T06:30:00.000Z',
|
|
155
|
+
prop: {
|
|
156
|
+
id: 'device-prop-mode'
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: 'twin-prop-electric',
|
|
161
|
+
propId: 'device-prop-electric',
|
|
162
|
+
propertyKey: 'electricA',
|
|
163
|
+
code: '电流有效值',
|
|
164
|
+
isMain: true,
|
|
165
|
+
isNumber: true,
|
|
166
|
+
line: true,
|
|
167
|
+
value: 0.043,
|
|
168
|
+
company: 'A',
|
|
169
|
+
valueAt: '2026-04-25T06:31:00.000Z',
|
|
170
|
+
prop: {
|
|
171
|
+
id: 'device-prop-electric'
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
const row = response.data.rows[0]
|
|
181
|
+
const modeProp = row.props[0]
|
|
182
|
+
const electricProp = row.props[1]
|
|
183
|
+
|
|
184
|
+
expect(row._id).toBe('twin-1')
|
|
185
|
+
expect(modeProp).toEqual(
|
|
186
|
+
expect.objectContaining({
|
|
187
|
+
_id: 'twin-prop-mode',
|
|
188
|
+
propId: 'device-prop-mode',
|
|
189
|
+
isStatus: true,
|
|
190
|
+
isImport: true,
|
|
191
|
+
line: true,
|
|
192
|
+
value: 1,
|
|
193
|
+
valueStr: '制热',
|
|
194
|
+
interval: '[["制冷","制热"],[0,1]]',
|
|
195
|
+
valueAt: '2026-04-25T06:30:00.000Z'
|
|
196
|
+
})
|
|
197
|
+
)
|
|
198
|
+
expect(modeProp.prop).toEqual(
|
|
199
|
+
expect.objectContaining({
|
|
200
|
+
_id: 'device-prop-mode',
|
|
201
|
+
line: true,
|
|
202
|
+
value: 1,
|
|
203
|
+
valueStr: '制热',
|
|
204
|
+
interval: '[["制冷","制热"],[0,1]]',
|
|
205
|
+
valueAt: '2026-04-25T06:30:00.000Z'
|
|
206
|
+
})
|
|
207
|
+
)
|
|
208
|
+
expect(electricProp).toEqual(
|
|
209
|
+
expect.objectContaining({
|
|
210
|
+
isMain: true,
|
|
211
|
+
isNumber: true,
|
|
212
|
+
isImport: true,
|
|
213
|
+
line: true,
|
|
214
|
+
value: 0.043,
|
|
215
|
+
valueAt: '2026-04-25T06:31:00.000Z'
|
|
216
|
+
})
|
|
217
|
+
)
|
|
218
|
+
expect(electricProp.prop).toEqual(
|
|
219
|
+
expect.objectContaining({
|
|
220
|
+
line: true,
|
|
221
|
+
value: 0.043,
|
|
222
|
+
company: 'A',
|
|
223
|
+
valueAt: '2026-04-25T06:31:00.000Z'
|
|
224
|
+
})
|
|
225
|
+
)
|
|
226
|
+
})
|
|
227
|
+
})
|