nayota-show-sdk 1.3.73 → 1.3.75

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nayota-show-sdk",
3
- "version": "1.3.73",
3
+ "version": "1.3.75",
4
4
  "description": "nayota-show-server rest-api",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -360,6 +360,60 @@ function normalizeLegacyPropLine(source = {}, prop = {}, row = {}) {
360
360
  return null
361
361
  }
362
362
 
363
+ const LEGACY_SWITCH_STATUS_KEYWORDS = [
364
+ '开关',
365
+ '电源',
366
+ '启停',
367
+ '启动',
368
+ '运行',
369
+ 'switch',
370
+ 'power'
371
+ ]
372
+
373
+ const LEGACY_SWITCH_STATUS_EXCLUDE_KEYWORDS = [
374
+ '模式',
375
+ '温度',
376
+ '风速',
377
+ '设定',
378
+ '设置',
379
+ '锁屏',
380
+ '锁定',
381
+ 'lock',
382
+ 'mode',
383
+ 'temp',
384
+ 'speed',
385
+ 'set'
386
+ ]
387
+
388
+ function isLegacyBinaryInterval(interval) {
389
+ try {
390
+ const payload = typeof interval === 'string' ? JSON.parse(interval) : interval
391
+ return Array.isArray(payload) && Array.isArray(payload[0]) && payload[0].length === 2
392
+ } catch {
393
+ return false
394
+ }
395
+ }
396
+
397
+ function isLegacySwitchOperateStatus(source = {}, interval = '') {
398
+ if (source.propType !== 'Operate' || !isLegacyBinaryInterval(interval)) {
399
+ return false
400
+ }
401
+
402
+ const normalized = [
403
+ source.propertyKey,
404
+ source.propName,
405
+ source.name,
406
+ source.code,
407
+ source.shortAddress
408
+ ].filter(Boolean).join(' ').toLowerCase()
409
+
410
+ if (LEGACY_SWITCH_STATUS_EXCLUDE_KEYWORDS.some(keyword => normalized.includes(keyword))) {
411
+ return false
412
+ }
413
+
414
+ return LEGACY_SWITCH_STATUS_KEYWORDS.some(keyword => normalized.includes(keyword))
415
+ }
416
+
363
417
  function normalizeLegacyNumber(value) {
364
418
  if (value === undefined || value === null || value === '') {
365
419
  return null
@@ -370,15 +424,85 @@ function normalizeLegacyNumber(value) {
370
424
  return Number.isFinite(num) ? num : null
371
425
  }
372
426
 
427
+ const LEGACY_OPEN_STATUS_KEYWORDS = ['开', '开启', '运行', '启动']
428
+
429
+ function normalizeLegacyStatusText(value) {
430
+ if (value === undefined || value === null) {
431
+ return ''
432
+ }
433
+
434
+ if (value && typeof value === 'object') {
435
+ return String(value.valueStr ?? value.label ?? value.name ?? value.value ?? '').trim()
436
+ }
437
+
438
+ return String(value).trim()
439
+ }
440
+
441
+ function isLegacyOpenStatusText(value) {
442
+ const text = normalizeLegacyStatusText(value)
443
+ if (!text) return false
444
+
445
+ return LEGACY_OPEN_STATUS_KEYWORDS.some(keyword => text.includes(keyword))
446
+ }
447
+
448
+ function isLegacyOpenStatusProp(prop = {}) {
449
+ return (
450
+ normalizeLegacyNumber(prop.rawValue) === 1 ||
451
+ normalizeLegacyNumber(prop.value) === 1 ||
452
+ normalizeLegacyNumber(prop.prop?.value) === 1 ||
453
+ isLegacyOpenStatusText(prop.rawValue) ||
454
+ isLegacyOpenStatusText(prop.value) ||
455
+ isLegacyOpenStatusText(prop.valueStr) ||
456
+ isLegacyOpenStatusText(prop.prop?.valueStr)
457
+ )
458
+ }
459
+
373
460
  function getLegacyStatusCounts(props = []) {
374
461
  const statusProps = props.filter(prop => prop && prop.isStatus)
375
462
  return {
376
463
  total: statusProps.length,
377
- open: statusProps.filter(prop =>
378
- normalizeLegacyNumber(prop.rawValue) === 1 ||
379
- normalizeLegacyNumber(prop.value) === 1 ||
380
- normalizeLegacyNumber(prop.prop?.value) === 1
381
- ).length
464
+ open: statusProps.filter(prop => isLegacyOpenStatusProp(prop)).length
465
+ }
466
+ }
467
+
468
+ function getLegacyOpenStatusProp(props = []) {
469
+ return props.find(prop => prop && prop.isStatus && isLegacyOpenStatusProp(prop))
470
+ }
471
+
472
+ function normalizeLegacyStatus(status, props = []) {
473
+ if (!status) {
474
+ return undefined
475
+ }
476
+
477
+ const statusCounts = getLegacyStatusCounts(props)
478
+ const openStatusProp = getLegacyOpenStatusProp(props)
479
+ const shouldUseOpenStatus =
480
+ statusCounts.open > 0 &&
481
+ normalizeLegacyNumber(status.value) !== 1 &&
482
+ openStatusProp
483
+
484
+ const displayStatus = shouldUseOpenStatus
485
+ ? {
486
+ value: 1,
487
+ label:
488
+ openStatusProp.prop?.valueStr ||
489
+ openStatusProp.valueStr ||
490
+ openStatusProp.name ||
491
+ openStatusProp.propName ||
492
+ '开',
493
+ valueStr:
494
+ openStatusProp.prop?.valueStr ||
495
+ openStatusProp.valueStr ||
496
+ openStatusProp.name ||
497
+ openStatusProp.propName ||
498
+ '开'
499
+ }
500
+ : status
501
+
502
+ return {
503
+ ...displayStatus,
504
+ total: status.total ?? statusCounts.total,
505
+ open: status.open ?? statusCounts.open
382
506
  }
383
507
  }
384
508
 
@@ -398,7 +522,7 @@ function normalizeLegacyEasyListProp(source = {}, row = {}) {
398
522
  const interval = prop.interval || source.interval || source.valueMap || ''
399
523
  const line = normalizeLegacyPropLine(source, prop, row)
400
524
  const isMain = Boolean(source.isMain)
401
- const isStatus = Boolean(source.isStatus)
525
+ const isStatus = Boolean(source.isStatus || isLegacySwitchOperateStatus(source, interval))
402
526
  const isNumber = Boolean(source.isNumber)
403
527
  const isImport = Boolean(source.isImport || isMain || isStatus || isNumber)
404
528
 
@@ -448,18 +572,11 @@ function normalizeLegacyEasyListRow(item = {}) {
448
572
  const props = Array.isArray(row.props)
449
573
  ? row.props.map(prop => normalizeLegacyEasyListProp(prop, row))
450
574
  : []
451
- const statusCounts = getLegacyStatusCounts(props)
452
575
 
453
576
  return removeUndefinedFields({
454
577
  ...row,
455
578
  props,
456
- status: row.status
457
- ? {
458
- ...row.status,
459
- total: row.status.total ?? statusCounts.total,
460
- open: row.status.open ?? statusCounts.open
461
- }
462
- : undefined,
579
+ status: normalizeLegacyStatus(row.status, props),
463
580
  lineTime: row.lineTime || props.find(prop => prop.isImport && prop.valueAt)?.valueAt || row.updatedAt || null
464
581
  })
465
582
  }
@@ -141,11 +141,26 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
141
141
  name: '会议室空调',
142
142
  line: false,
143
143
  status: {
144
- value: 1,
145
- label: '制热',
146
- valueStr: '制热'
144
+ value: 0,
145
+ label: '解锁',
146
+ valueStr: '解锁'
147
147
  },
148
148
  props: [
149
+ {
150
+ id: 'twin-prop-lock',
151
+ propId: 'device-prop-lock',
152
+ propertyKey: 'lock',
153
+ name: '锁屏',
154
+ isStatus: true,
155
+ line: true,
156
+ value: 0,
157
+ valueStr: '解锁',
158
+ interval: '[["解锁","锁屏"],[0,1]]',
159
+ valueAt: '2026-04-25T06:29:00.000Z',
160
+ prop: {
161
+ id: 'device-prop-lock'
162
+ }
163
+ },
149
164
  {
150
165
  id: 'twin-prop-mode',
151
166
  propId: 'device-prop-mode',
@@ -153,14 +168,29 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
153
168
  name: '模式设定',
154
169
  isStatus: true,
155
170
  line: true,
156
- value: 1,
157
- valueStr: '制热',
171
+ value: 0,
172
+ valueStr: '制冷',
158
173
  interval: '[["制冷","制热"],[0,1]]',
159
174
  valueAt: '2026-04-25T06:30:00.000Z',
160
175
  prop: {
161
176
  id: 'device-prop-mode'
162
177
  }
163
178
  },
179
+ {
180
+ id: 'twin-prop-switch',
181
+ propId: 'device-prop-switch',
182
+ propertyKey: 'powerSwitch',
183
+ name: '开关',
184
+ propType: 'Operate',
185
+ line: true,
186
+ value: 1,
187
+ valueStr: '开',
188
+ interval: '[["关","开"],[0,1]]',
189
+ valueAt: '2026-04-25T06:30:30.000Z',
190
+ prop: {
191
+ id: 'device-prop-switch'
192
+ }
193
+ },
164
194
  {
165
195
  id: 'twin-prop-electric',
166
196
  propId: 'device-prop-electric',
@@ -183,15 +213,16 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
183
213
  })
184
214
 
185
215
  const row = response.data.rows[0]
186
- const modeProp = row.props[0]
187
- const electricProp = row.props[1]
216
+ const modeProp = row.props[1]
217
+ const switchProp = row.props[2]
218
+ const electricProp = row.props[3]
188
219
 
189
220
  expect(row._id).toBe('twin-1')
190
221
  expect(row.status).toEqual({
191
222
  value: 1,
192
- label: '制热',
193
- valueStr: '制热',
194
- total: 1,
223
+ label: '',
224
+ valueStr: '',
225
+ total: 3,
195
226
  open: 1
196
227
  })
197
228
  expect(modeProp).toEqual(
@@ -201,8 +232,8 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
201
232
  isStatus: true,
202
233
  isImport: true,
203
234
  line: true,
204
- value: 1,
205
- valueStr: '制热',
235
+ value: 0,
236
+ valueStr: '制冷',
206
237
  interval: '[["制冷","制热"],[0,1]]',
207
238
  valueAt: '2026-04-25T06:30:00.000Z'
208
239
  })
@@ -211,12 +242,21 @@ describe('iotModuleSpecs devices easyList legacy compatibility', () => {
211
242
  expect.objectContaining({
212
243
  _id: 'device-prop-mode',
213
244
  line: true,
214
- value: 1,
215
- valueStr: '制热',
245
+ value: 0,
246
+ valueStr: '制冷',
216
247
  interval: '[["制冷","制热"],[0,1]]',
217
248
  valueAt: '2026-04-25T06:30:00.000Z'
218
249
  })
219
250
  )
251
+ expect(switchProp).toEqual(
252
+ expect.objectContaining({
253
+ propType: 'Operate',
254
+ isStatus: true,
255
+ isImport: true,
256
+ value: 1,
257
+ valueStr: '开'
258
+ })
259
+ )
220
260
  expect(electricProp).toEqual(
221
261
  expect.objectContaining({
222
262
  isMain: true,