nayota-show-sdk 1.3.74 → 1.3.76
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 +65 -3
- package/utils/iot-module-specs.test.js +54 -10
package/package.json
CHANGED
|
@@ -215,12 +215,16 @@ function mapIotDepartsToLegacy(item = {}) {
|
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
function mapDevicesToIotQuery(query = {}) {
|
|
218
|
+
const digitalTwinTypeId = query.digitalTwinTypeId != null && query.digitalTwinTypeId !== ''
|
|
219
|
+
? query.digitalTwinTypeId
|
|
220
|
+
: resolveLegacyReference(query.deviceClass) || undefined
|
|
221
|
+
|
|
218
222
|
return removeUndefinedFields({
|
|
219
223
|
...omitKeys(query, ['_id', 'depart', 'area', 'deviceClass', 'cloudType', 'status', 'sort']),
|
|
220
224
|
id: query.id || query._id,
|
|
221
225
|
hierarchyId: query.hierarchyId || query.depart,
|
|
222
226
|
spaceId: query.spaceId || query.area,
|
|
223
|
-
digitalTwinTypeId
|
|
227
|
+
digitalTwinTypeId,
|
|
224
228
|
isActive: query.isActive != null ? query.isActive : (query.cloudType != null ? query.cloudType : query.status),
|
|
225
229
|
...parseLegacySort(query.sort, {
|
|
226
230
|
deviceClass: 'digitalTwinTypeId',
|
|
@@ -232,6 +236,10 @@ function mapDevicesToIotQuery(query = {}) {
|
|
|
232
236
|
}
|
|
233
237
|
|
|
234
238
|
function mapDevicesToIotBody(data = {}) {
|
|
239
|
+
const digitalTwinTypeId = data.digitalTwinTypeId != null && data.digitalTwinTypeId !== ''
|
|
240
|
+
? data.digitalTwinTypeId
|
|
241
|
+
: resolveLegacyReference(data.deviceClass) || undefined
|
|
242
|
+
|
|
235
243
|
const metadata = mergeMetadata(data.metadata, {
|
|
236
244
|
configDeviceId: data.n_device,
|
|
237
245
|
mapLatLng: data.mapLatLng,
|
|
@@ -268,7 +276,7 @@ function mapDevicesToIotBody(data = {}) {
|
|
|
268
276
|
twinId: data.twinId || data.n_device || fallbackCode(data.name || data._id, 'TWIN'),
|
|
269
277
|
hierarchyId: data.hierarchyId || data.depart,
|
|
270
278
|
spaceId: data.spaceId || data.area,
|
|
271
|
-
digitalTwinTypeId
|
|
279
|
+
digitalTwinTypeId,
|
|
272
280
|
isActive: data.isActive != null ? data.isActive : (data.cloudType != null ? data.cloudType : data.status),
|
|
273
281
|
metadata: Object.keys(metadata).length ? metadata : undefined
|
|
274
282
|
})
|
|
@@ -360,6 +368,60 @@ function normalizeLegacyPropLine(source = {}, prop = {}, row = {}) {
|
|
|
360
368
|
return null
|
|
361
369
|
}
|
|
362
370
|
|
|
371
|
+
const LEGACY_SWITCH_STATUS_KEYWORDS = [
|
|
372
|
+
'开关',
|
|
373
|
+
'电源',
|
|
374
|
+
'启停',
|
|
375
|
+
'启动',
|
|
376
|
+
'运行',
|
|
377
|
+
'switch',
|
|
378
|
+
'power'
|
|
379
|
+
]
|
|
380
|
+
|
|
381
|
+
const LEGACY_SWITCH_STATUS_EXCLUDE_KEYWORDS = [
|
|
382
|
+
'模式',
|
|
383
|
+
'温度',
|
|
384
|
+
'风速',
|
|
385
|
+
'设定',
|
|
386
|
+
'设置',
|
|
387
|
+
'锁屏',
|
|
388
|
+
'锁定',
|
|
389
|
+
'lock',
|
|
390
|
+
'mode',
|
|
391
|
+
'temp',
|
|
392
|
+
'speed',
|
|
393
|
+
'set'
|
|
394
|
+
]
|
|
395
|
+
|
|
396
|
+
function isLegacyBinaryInterval(interval) {
|
|
397
|
+
try {
|
|
398
|
+
const payload = typeof interval === 'string' ? JSON.parse(interval) : interval
|
|
399
|
+
return Array.isArray(payload) && Array.isArray(payload[0]) && payload[0].length === 2
|
|
400
|
+
} catch {
|
|
401
|
+
return false
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function isLegacySwitchOperateStatus(source = {}, interval = '') {
|
|
406
|
+
if (source.propType !== 'Operate' || !isLegacyBinaryInterval(interval)) {
|
|
407
|
+
return false
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const normalized = [
|
|
411
|
+
source.propertyKey,
|
|
412
|
+
source.propName,
|
|
413
|
+
source.name,
|
|
414
|
+
source.code,
|
|
415
|
+
source.shortAddress
|
|
416
|
+
].filter(Boolean).join(' ').toLowerCase()
|
|
417
|
+
|
|
418
|
+
if (LEGACY_SWITCH_STATUS_EXCLUDE_KEYWORDS.some(keyword => normalized.includes(keyword))) {
|
|
419
|
+
return false
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return LEGACY_SWITCH_STATUS_KEYWORDS.some(keyword => normalized.includes(keyword))
|
|
423
|
+
}
|
|
424
|
+
|
|
363
425
|
function normalizeLegacyNumber(value) {
|
|
364
426
|
if (value === undefined || value === null || value === '') {
|
|
365
427
|
return null
|
|
@@ -468,7 +530,7 @@ function normalizeLegacyEasyListProp(source = {}, row = {}) {
|
|
|
468
530
|
const interval = prop.interval || source.interval || source.valueMap || ''
|
|
469
531
|
const line = normalizeLegacyPropLine(source, prop, row)
|
|
470
532
|
const isMain = Boolean(source.isMain)
|
|
471
|
-
const isStatus = Boolean(source.isStatus)
|
|
533
|
+
const isStatus = Boolean(source.isStatus || isLegacySwitchOperateStatus(source, interval))
|
|
472
534
|
const isNumber = Boolean(source.isNumber)
|
|
473
535
|
const isImport = Boolean(source.isImport || isMain || isStatus || isNumber)
|
|
474
536
|
|
|
@@ -127,6 +127,25 @@ describe('iotModuleSpecs departs hierarchy compatibility', () => {
|
|
|
127
127
|
})
|
|
128
128
|
})
|
|
129
129
|
|
|
130
|
+
describe('iotModuleSpecs devices write compatibility', () => {
|
|
131
|
+
const devices = iotModuleSpecs.devices.operations
|
|
132
|
+
|
|
133
|
+
test('does not send digitalTwinTypeId null for partial map coordinate updates', () => {
|
|
134
|
+
const request = devices.updateOne.toRequest({
|
|
135
|
+
_id: '77b8889e-7d3a-4efa-9fc9-858305468d6c',
|
|
136
|
+
digitalTwinTypeId: null,
|
|
137
|
+
spaceId: 'c13c121f-1a23-4656-be54-9e7488f43c55',
|
|
138
|
+
svgCoordinates: [891.4283167347667, 739.999788571489]
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
expect(request.url).toBe('/digital-twins/77b8889e-7d3a-4efa-9fc9-858305468d6c')
|
|
142
|
+
expect(request.method).toBe('patch')
|
|
143
|
+
expect(request.data.digitalTwinTypeId).toBeUndefined()
|
|
144
|
+
expect(request.data.spaceId).toBe('c13c121f-1a23-4656-be54-9e7488f43c55')
|
|
145
|
+
expect(request.data.svgCoordinates).toEqual([891.4283167347667, 739.999788571489])
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
|
|
130
149
|
describe('iotModuleSpecs devices easyList legacy compatibility', () => {
|
|
131
150
|
const easyList = iotModuleSpecs.devices.operations.easyList
|
|
132
151
|
|
|
@@ -168,14 +187,29 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
|
|
|
168
187
|
name: '模式设定',
|
|
169
188
|
isStatus: true,
|
|
170
189
|
line: true,
|
|
171
|
-
value:
|
|
172
|
-
valueStr: '
|
|
190
|
+
value: 0,
|
|
191
|
+
valueStr: '制冷',
|
|
173
192
|
interval: '[["制冷","制热"],[0,1]]',
|
|
174
193
|
valueAt: '2026-04-25T06:30:00.000Z',
|
|
175
194
|
prop: {
|
|
176
195
|
id: 'device-prop-mode'
|
|
177
196
|
}
|
|
178
197
|
},
|
|
198
|
+
{
|
|
199
|
+
id: 'twin-prop-switch',
|
|
200
|
+
propId: 'device-prop-switch',
|
|
201
|
+
propertyKey: 'powerSwitch',
|
|
202
|
+
name: '开关',
|
|
203
|
+
propType: 'Operate',
|
|
204
|
+
line: true,
|
|
205
|
+
value: 1,
|
|
206
|
+
valueStr: '开',
|
|
207
|
+
interval: '[["关","开"],[0,1]]',
|
|
208
|
+
valueAt: '2026-04-25T06:30:30.000Z',
|
|
209
|
+
prop: {
|
|
210
|
+
id: 'device-prop-switch'
|
|
211
|
+
}
|
|
212
|
+
},
|
|
179
213
|
{
|
|
180
214
|
id: 'twin-prop-electric',
|
|
181
215
|
propId: 'device-prop-electric',
|
|
@@ -199,14 +233,15 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
|
|
|
199
233
|
|
|
200
234
|
const row = response.data.rows[0]
|
|
201
235
|
const modeProp = row.props[1]
|
|
202
|
-
const
|
|
236
|
+
const switchProp = row.props[2]
|
|
237
|
+
const electricProp = row.props[3]
|
|
203
238
|
|
|
204
239
|
expect(row._id).toBe('twin-1')
|
|
205
240
|
expect(row.status).toEqual({
|
|
206
241
|
value: 1,
|
|
207
|
-
label: '
|
|
208
|
-
valueStr: '
|
|
209
|
-
total:
|
|
242
|
+
label: '开',
|
|
243
|
+
valueStr: '开',
|
|
244
|
+
total: 3,
|
|
210
245
|
open: 1
|
|
211
246
|
})
|
|
212
247
|
expect(modeProp).toEqual(
|
|
@@ -216,8 +251,8 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
|
|
|
216
251
|
isStatus: true,
|
|
217
252
|
isImport: true,
|
|
218
253
|
line: true,
|
|
219
|
-
value:
|
|
220
|
-
valueStr: '
|
|
254
|
+
value: 0,
|
|
255
|
+
valueStr: '制冷',
|
|
221
256
|
interval: '[["制冷","制热"],[0,1]]',
|
|
222
257
|
valueAt: '2026-04-25T06:30:00.000Z'
|
|
223
258
|
})
|
|
@@ -226,12 +261,21 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
|
|
|
226
261
|
expect.objectContaining({
|
|
227
262
|
_id: 'device-prop-mode',
|
|
228
263
|
line: true,
|
|
229
|
-
value:
|
|
230
|
-
valueStr: '
|
|
264
|
+
value: 0,
|
|
265
|
+
valueStr: '制冷',
|
|
231
266
|
interval: '[["制冷","制热"],[0,1]]',
|
|
232
267
|
valueAt: '2026-04-25T06:30:00.000Z'
|
|
233
268
|
})
|
|
234
269
|
)
|
|
270
|
+
expect(switchProp).toEqual(
|
|
271
|
+
expect.objectContaining({
|
|
272
|
+
propType: 'Operate',
|
|
273
|
+
isStatus: true,
|
|
274
|
+
isImport: true,
|
|
275
|
+
value: 1,
|
|
276
|
+
valueStr: '开'
|
|
277
|
+
})
|
|
278
|
+
)
|
|
235
279
|
expect(electricProp).toEqual(
|
|
236
280
|
expect.objectContaining({
|
|
237
281
|
isMain: true,
|