pyimouapi 1.1.26__tar.gz → 1.2.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyimouapi
3
- Version: 1.1.26
3
+ Version: 1.2.0
4
4
  Summary: A package for imou open api
5
5
  Home-page: https://github.com/Imou-OpenPlatform/Py-Imou-Open-Api
6
6
  Author: Imou-OpenPlatform
@@ -21,6 +21,7 @@ API_ENDPOINT_IOT_DEVICE_CONTROL = "/openapi/iotDeviceControl"
21
21
  API_ENDPOINT_GET_DEVICE_POWER_INFO = "/openapi/getDevicePowerInfo"
22
22
  API_ENDPOINT_GET_PRODUCT_MODEL = "/openapi/getProductModel"
23
23
  API_ENDPOINT_GET_IOT_DEVICE_DETAIL_INFO = "/openapi/getIotDeviceDetailInfo"
24
+ API_ENDPOINT_WAKE_UP_DEVICE = "/openapi/wakeUpDevice"
24
25
 
25
26
  # error_codes
26
27
  ERROR_CODE_SUCCESS = "0"
@@ -31,6 +32,7 @@ ERROR_CODE_DEVICE_OFFLINE = "DV1007"
31
32
  ERROR_CODE_NO_STORAGE_MEDIUM = "DV1049"
32
33
  ERROR_CODE_LIVE_NOT_EXIST = "LV1002"
33
34
  ERROR_CODE_LIVE_ALREADY_EXIST = "LV1001"
35
+ ERROR_CODE_DEVICE_SLEEPING = "DV1030"
34
36
 
35
37
  # params key
36
38
  PARAM_APP_ID = "appId"
@@ -125,7 +127,6 @@ PARAM_ACCESS_TYPE = "accessType"
125
127
  PARAM_ABILITY = "ability"
126
128
  PARAM_FUNCTION_TYPE = "function_type"
127
129
 
128
-
129
130
  # Required capacity for various switch types
130
131
  SWITCH_TYPE_ABILITY = {
131
132
  "motion_detect": [
@@ -370,7 +371,7 @@ SELECT_TYPE_REF = {
370
371
  {
371
372
  "ref": "17400",
372
373
  "default": "0",
373
- "options": ["0", "1", "2", "3", "5"],
374
+ "options": ["0", "1", "2", "3"],
374
375
  "value_type": "int",
375
376
  },
376
377
  {
@@ -407,9 +408,9 @@ SENSOR_TYPE_REF = {
407
408
  "storage_used": [
408
409
  {
409
410
  "ref": "14600",
410
- "default": "-2",
411
+ "default": "e2",
411
412
  "ref_type": "properties",
412
- "expression": "('-1' if data['14603']==0 else '-2') if data['14603'] != 1 else int(data['14602'] / data['14601'] * 100)",
413
+ "expression": "('e1' if data['14603']==0 else 'e2') if data['14603'] != 1 else int(data['14602'] / data['14601'] * 100)",
413
414
  }
414
415
  ],
415
416
  "battery": [{"ref": "11600", "default": "15", "ref_type": "properties"}],
@@ -486,11 +487,16 @@ TEXT_TYPE_REF = {
486
487
  "default": "100",
487
488
  "ref_type": "properties",
488
489
  "value_type": "int",
490
+ },
491
+ {
492
+ "ref": "128900",
493
+ "default": "100",
494
+ "ref_type": "properties",
495
+ "value_type": "int",
489
496
  }
490
497
  ],
491
498
  }
492
499
 
493
-
494
500
  BUTTON_TYPE_PARAM_VALUE = {
495
501
  "ptz_up": 0,
496
502
  "ptz_down": 1,
@@ -52,7 +52,7 @@ from .const import (
52
52
  API_ENDPOINT_GET_IOT_DEVICE_DETAIL_INFO,
53
53
  PARAM_ABILITY_REFS,
54
54
  PARAM_CHANNELS,
55
- PARAM_ACCESS_TYPE,
55
+ PARAM_ACCESS_TYPE, API_ENDPOINT_WAKE_UP_DEVICE, PARAM_URL,
56
56
  )
57
57
  from .openapi import ImouOpenApiClient
58
58
 
@@ -484,6 +484,17 @@ class ImouDeviceManager:
484
484
  API_ENDPOINT_GET_DEVICE_POWER_INFO, params
485
485
  )
486
486
 
487
+ async def async_wake_up_device(self, device_id: str) -> None:
488
+ params = {
489
+ PARAM_DEVICE_ID: device_id,
490
+ PARAM_URL: "/device/wakeup",
491
+ }
492
+ await self._imou_api_client.async_request_api(
493
+ API_ENDPOINT_WAKE_UP_DEVICE, params
494
+ )
495
+
496
+
497
+
487
498
  async def async_get_product_model(self, product_id: str) -> dict[any, any]:
488
499
  params = {
489
500
  PARAM_PRODUCT_ID: product_id,
@@ -60,7 +60,7 @@ from .const import (
60
60
  TEXT_TYPE_REF,
61
61
  PARAM_VALUE_TYPE,
62
62
  PARAM_ABILITY,
63
- PARAM_FUNCTION_TYPE,
63
+ PARAM_FUNCTION_TYPE, ERROR_CODE_DEVICE_SLEEPING,
64
64
  )
65
65
  from .device import ImouDeviceManager, ImouDevice
66
66
  from .exceptions import RequestFailedException
@@ -75,16 +75,17 @@ NUMBER_TYPE = [
75
75
  PARAM_HUMIDITY_CURRENT,
76
76
  PARAM_BATTERY,
77
77
  ]
78
+ PRODUCT_MODEL_ILLEGAL_LIST = ["z76s20l415gnhhl1", "o8828zgeg1g9cfuz", "Q3YSZ54R", "BDHCWWPX"]
78
79
 
79
80
 
80
81
  class ImouHaDevice(object):
81
82
  def __init__(
82
- self,
83
- device_id: str,
84
- device_name: str,
85
- manufacturer: str,
86
- model: str,
87
- swversion: str,
83
+ self,
84
+ device_id: str,
85
+ device_name: str,
86
+ manufacturer: str,
87
+ model: str,
88
+ swversion: str,
88
89
  ):
89
90
  self._device_id = device_id
90
91
  self._device_name = device_name
@@ -296,16 +297,16 @@ class ImouHaDeviceManager(object):
296
297
  )
297
298
  device.sensors[PARAM_STORAGE_USED][PARAM_STATE] = str(percentage_used)
298
299
  else:
299
- device.sensors[PARAM_STORAGE_USED][PARAM_STATE] = "-2"
300
+ device.sensors[PARAM_STORAGE_USED][PARAM_STATE] = "e2"
300
301
  except RequestFailedException as exception:
301
302
  _LOGGER.error(f"_async_update_device_storage error: {exception}")
302
303
  if ERROR_CODE_NO_STORAGE_MEDIUM in exception.message:
303
- device.sensors[PARAM_STORAGE_USED][PARAM_STATE] = "-1"
304
+ device.sensors[PARAM_STORAGE_USED][PARAM_STATE] = "e1"
304
305
  else:
305
- device.sensors[PARAM_STORAGE_USED][PARAM_STATE] = "-2"
306
+ device.sensors[PARAM_STORAGE_USED][PARAM_STATE] = "e2"
306
307
 
307
308
  async def async_get_device_stream(
308
- self, device: ImouHaDevice, live_resolution: str, live_protocol: str
309
+ self, device: ImouHaDevice, live_resolution: str, live_protocol: str
309
310
  ):
310
311
  try:
311
312
  return await self._async_get_device_exist_stream(
@@ -328,7 +329,7 @@ class ImouHaDeviceManager(object):
328
329
  raise exception
329
330
 
330
331
  async def _async_get_device_exist_stream(
331
- self, device: ImouHaDevice, resolution: str, protocol: str
332
+ self, device: ImouHaDevice, resolution: str, protocol: str
332
333
  ):
333
334
  data = await self.delegate.async_get_stream_url(
334
335
  device.device_id, device.channel_id
@@ -336,7 +337,7 @@ class ImouHaDeviceManager(object):
336
337
  return await self.async_get_stream_url(data, resolution, protocol)
337
338
 
338
339
  async def _async_create_device_stream(
339
- self, device: ImouHaDevice, resolution: str, protocol: str
340
+ self, device: ImouHaDevice, resolution: str, protocol: str
340
341
  ):
341
342
  data = await self.delegate.async_create_stream_url(
342
343
  device.device_id, device.channel_id
@@ -436,7 +437,7 @@ class ImouHaDeviceManager(object):
436
437
  return imou_ha_device
437
438
 
438
439
  async def async_press_button(
439
- self, device: ImouHaDevice, button_type: str, duration: int
440
+ self, device: ImouHaDevice, button_type: str, duration: int
440
441
  ):
441
442
  if PARAM_RESTART_DEVICE == button_type:
442
443
  await self.delegate.async_restart_device(device.device_id)
@@ -452,7 +453,7 @@ class ImouHaDeviceManager(object):
452
453
  await self._async_press_button_by_ref(device, ref_id)
453
454
 
454
455
  async def async_set_text_value(
455
- self, device: ImouHaDevice, text_type: str, text_value: str
456
+ self, device: ImouHaDevice, text_type: str, text_value: str
456
457
  ):
457
458
  if device.texts[text_type].get(PARAM_REF):
458
459
  ref_id = device.texts[text_type].get(PARAM_REF)
@@ -464,11 +465,11 @@ class ImouHaDeviceManager(object):
464
465
  # 如果是配件,需要拼接设备id
465
466
  if device.parent_product_id is not None:
466
467
  device_id = (
467
- device_id
468
- + "_"
469
- + device.parent_device_id
470
- + "_"
471
- + device.parent_product_id
468
+ device_id
469
+ + "_"
470
+ + device.parent_device_id
471
+ + "_"
472
+ + device.parent_product_id
472
473
  )
473
474
  if "int" == value_type and text_value.isdigit():
474
475
  value = int(text_value)
@@ -485,7 +486,7 @@ class ImouHaDeviceManager(object):
485
486
  )
486
487
 
487
488
  async def async_switch_operation(
488
- self, device: ImouHaDevice, switch_type: str, enable: bool
489
+ self, device: ImouHaDevice, switch_type: str, enable: bool
489
490
  ):
490
491
  if device.switches[switch_type].get(PARAM_REF):
491
492
  ref_id = device.switches[switch_type].get(PARAM_REF)
@@ -517,22 +518,22 @@ class ImouHaDeviceManager(object):
517
518
  raise result[0]
518
519
 
519
520
  async def async_select_option(
520
- self,
521
- device: ImouHaDevice,
522
- select_type: str,
523
- option: str,
521
+ self,
522
+ device: ImouHaDevice,
523
+ select_type: str,
524
+ option: str,
524
525
  ):
525
526
  if device.selects[select_type].get(PARAM_REF):
526
527
  ref_id = device.selects[select_type].get(PARAM_REF)
527
528
  value_type = device.selects[select_type].get(PARAM_VALUE_TYPE)
528
529
  await self._async_select_option_by_ref(device, option, ref_id, value_type)
529
- if PARAM_NIGHT_VISION_MODE == select_type:
530
+ elif PARAM_NIGHT_VISION_MODE == select_type:
530
531
  await self.delegate.async_set_device_night_vision_mode(
531
532
  device.device_id, device.channel_id, option
532
533
  )
533
534
 
534
535
  async def _async_get_device_switch_status_by_ability(
535
- self, device: ImouHaDevice, ability_type: str
536
+ self, device: ImouHaDevice, ability_type: str
536
537
  ) -> bool:
537
538
  # Updating the interface requires capturing exceptions for two main purposes:
538
539
  # 1. To prevent the updater from failing to load due to exceptions;
@@ -546,14 +547,14 @@ class ImouHaDeviceManager(object):
546
547
  return False
547
548
 
548
549
  async def _async_set_device_switch_status_by_ability(
549
- self, device: ImouHaDevice, ability_type: str, enable: bool
550
+ self, device: ImouHaDevice, ability_type: str, enable: bool
550
551
  ) -> None:
551
552
  await self.delegate.async_set_device_status(
552
553
  device.device_id, device.channel_id, ability_type, enable
553
554
  )
554
555
 
555
556
  async def _async_update_device_select_status_by_type(
556
- self, device: ImouHaDevice, select_type: str
557
+ self, device: ImouHaDevice, select_type: str
557
558
  ):
558
559
  if select_type == PARAM_NIGHT_VISION_MODE:
559
560
  try:
@@ -580,10 +581,10 @@ class ImouHaDeviceManager(object):
580
581
 
581
582
  @staticmethod
582
583
  def configure_device_by_ability(
583
- channel_abilities: list[str],
584
- is_ipc: bool,
585
- device_abilities: list[str],
586
- imou_ha_device: ImouHaDevice,
584
+ channel_abilities: list[str],
585
+ is_ipc: bool,
586
+ device_abilities: list[str],
587
+ imou_ha_device: ImouHaDevice,
587
588
  ):
588
589
  # Determine which platform entity should be added, based on the ability
589
590
  ImouHaDeviceManager.configure_switch_by_ability(
@@ -619,21 +620,21 @@ class ImouHaDeviceManager(object):
619
620
 
620
621
  @staticmethod
621
622
  def configure_sensor_by_ability(
622
- channel_abilities: list[str],
623
- is_ipc: bool,
624
- device_abilities: list[str],
625
- imou_ha_device: ImouHaDevice,
623
+ channel_abilities: list[str],
624
+ is_ipc: bool,
625
+ device_abilities: list[str],
626
+ imou_ha_device: ImouHaDevice,
626
627
  ):
627
628
  for sensor_type, ability_list in SENSOR_TYPE_ABILITY.items():
628
629
  for ability in ability_list:
629
630
  if ImouHaDeviceManager.entity_need_add_to_device(
630
- ability,
631
- channel_abilities,
632
- device_abilities,
633
- is_ipc,
634
- imou_ha_device.channel_id,
635
- sensor_type,
636
- imou_ha_device.sensors,
631
+ ability,
632
+ channel_abilities,
633
+ device_abilities,
634
+ is_ipc,
635
+ imou_ha_device.channel_id,
636
+ sensor_type,
637
+ imou_ha_device.sensors,
637
638
  ):
638
639
  imou_ha_device.sensors[sensor_type] = {
639
640
  PARAM_STATE: "unknown"
@@ -643,21 +644,21 @@ class ImouHaDeviceManager(object):
643
644
 
644
645
  @staticmethod
645
646
  def configure_select_by_ability(
646
- channel_abilities: list[str],
647
- is_ipc: bool,
648
- device_abilities: list[str],
649
- imou_ha_device: ImouHaDevice,
647
+ channel_abilities: list[str],
648
+ is_ipc: bool,
649
+ device_abilities: list[str],
650
+ imou_ha_device: ImouHaDevice,
650
651
  ):
651
652
  for select_type, ability_list in SELECT_TYPE_ABILITY.items():
652
653
  for ability in ability_list:
653
654
  if ImouHaDeviceManager.entity_need_add_to_device(
654
- ability,
655
- channel_abilities,
656
- device_abilities,
657
- is_ipc,
658
- imou_ha_device.channel_id,
659
- select_type,
660
- imou_ha_device.selects,
655
+ ability,
656
+ channel_abilities,
657
+ device_abilities,
658
+ is_ipc,
659
+ imou_ha_device.channel_id,
660
+ select_type,
661
+ imou_ha_device.selects,
661
662
  ):
662
663
  imou_ha_device.selects[select_type] = {
663
664
  PARAM_CURRENT_OPTION: "",
@@ -666,41 +667,41 @@ class ImouHaDeviceManager(object):
666
667
 
667
668
  @staticmethod
668
669
  def configure_button_by_ability(
669
- channel_abilities: list[str],
670
- is_ipc: bool,
671
- device_abilities: list[str],
672
- imou_ha_device: ImouHaDevice,
670
+ channel_abilities: list[str],
671
+ is_ipc: bool,
672
+ device_abilities: list[str],
673
+ imou_ha_device: ImouHaDevice,
673
674
  ):
674
675
  for button_type, ability_list in BUTTON_TYPE_ABILITY.items():
675
676
  for ability in ability_list:
676
677
  if ImouHaDeviceManager.entity_need_add_to_device(
677
- ability,
678
- channel_abilities,
679
- device_abilities,
680
- is_ipc,
681
- imou_ha_device.channel_id,
682
- button_type,
683
- imou_ha_device.buttons,
678
+ ability,
679
+ channel_abilities,
680
+ device_abilities,
681
+ is_ipc,
682
+ imou_ha_device.channel_id,
683
+ button_type,
684
+ imou_ha_device.buttons,
684
685
  ):
685
686
  imou_ha_device.buttons[button_type] = {}
686
687
 
687
688
  @staticmethod
688
689
  def configure_switch_by_ability(
689
- channel_abilities: list[str],
690
- is_ipc: bool,
691
- device_abilities: list[str],
692
- imou_ha_device: ImouHaDevice,
690
+ channel_abilities: list[str],
691
+ is_ipc: bool,
692
+ device_abilities: list[str],
693
+ imou_ha_device: ImouHaDevice,
693
694
  ):
694
695
  for switch_type, ability_list in SWITCH_TYPE_ABILITY.items():
695
696
  for ability in ability_list:
696
697
  if ImouHaDeviceManager.entity_need_add_to_device(
697
- ability.get(PARAM_ABILITY),
698
- channel_abilities,
699
- device_abilities,
700
- is_ipc,
701
- imou_ha_device.channel_id,
702
- switch_type,
703
- imou_ha_device.switches,
698
+ ability.get(PARAM_ABILITY),
699
+ channel_abilities,
700
+ device_abilities,
701
+ is_ipc,
702
+ imou_ha_device.channel_id,
703
+ switch_type,
704
+ imou_ha_device.switches,
704
705
  ):
705
706
  imou_ha_device.switches[switch_type] = {
706
707
  PARAM_STATE: ability.get(PARAM_DEFAULT),
@@ -712,8 +713,8 @@ class ImouHaDeviceManager(object):
712
713
  if data.get(PARAM_STREAMS):
713
714
  for stream in data[PARAM_STREAMS]:
714
715
  if (
715
- stream[PARAM_HLS].startswith(protocol + ":")
716
- and (0 if resolution == PARAM_HD else 1) == stream[PARAM_STREAM_ID]
716
+ stream[PARAM_HLS].startswith(protocol + ":")
717
+ and (0 if resolution == PARAM_HD else 1) == stream[PARAM_STREAM_ID]
717
718
  ):
718
719
  _LOGGER.debug(f"get_device_stream {stream[PARAM_HLS]}")
719
720
  return stream[PARAM_HLS]
@@ -721,11 +722,11 @@ class ImouHaDeviceManager(object):
721
722
  return ""
722
723
 
723
724
  async def _async_configure_device_by_ref(
724
- self,
725
- channel_ability_refs: list[str],
726
- is_ipc: bool,
727
- device_ability_refs: list[str],
728
- imou_ha_device: ImouHaDevice,
725
+ self,
726
+ channel_ability_refs: list[str],
727
+ is_ipc: bool,
728
+ device_ability_refs: list[str],
729
+ imou_ha_device: ImouHaDevice,
729
730
  ):
730
731
  self.configure_switch_by_ref(
731
732
  channel_ability_refs,
@@ -766,70 +767,70 @@ class ImouHaDeviceManager(object):
766
767
 
767
768
  @staticmethod
768
769
  def entity_need_add_to_device(
769
- ability_or_ref: str,
770
- channel_abilities_or_refs: list[str],
771
- device_abilities_or_refs: list[str],
772
- is_ipc: bool,
773
- channel_id: str,
774
- entity_type: str,
775
- exists_entities: dict[str, any],
770
+ ability_or_ref: str,
771
+ channel_abilities_or_refs: list[str],
772
+ device_abilities_or_refs: list[str],
773
+ is_ipc: bool,
774
+ channel_id: str,
775
+ entity_type: str,
776
+ exists_entities: dict[str, any],
776
777
  ) -> bool:
777
778
  return (
778
- channel_id is None
779
- and ability_or_ref in device_abilities_or_refs
780
- or ability_or_ref in channel_abilities_or_refs
781
- or (
782
- is_ipc
783
- and channel_id is not None
784
- and channel_id == "0"
779
+ channel_id is None
785
780
  and ability_or_ref in device_abilities_or_refs
786
- )
781
+ or ability_or_ref in channel_abilities_or_refs
782
+ or (
783
+ is_ipc
784
+ and channel_id is not None
785
+ and channel_id == "0"
786
+ and ability_or_ref in device_abilities_or_refs
787
+ )
787
788
  ) and entity_type not in exists_entities
788
789
 
789
790
  @staticmethod
790
791
  def entity_need_add_to_device_by_ref(
791
- ref_id: str,
792
- channel_ability_refs: list[str],
793
- device_ability_refs: list[str],
794
- is_ipc: bool,
795
- channel_id: str,
796
- entity_type: str,
797
- exists_entities: dict[str, any],
798
- product_id: str,
799
- except_product_ids: list[str],
792
+ ref_id: str,
793
+ channel_ability_refs: list[str],
794
+ device_ability_refs: list[str],
795
+ is_ipc: bool,
796
+ channel_id: str,
797
+ entity_type: str,
798
+ exists_entities: dict[str, any],
799
+ product_id: str,
800
+ except_product_ids: list[str],
800
801
  ) -> bool:
801
802
  return (
802
- product_id not in except_product_ids
803
- and ImouHaDeviceManager.entity_need_add_to_device(
804
- ref_id,
805
- channel_ability_refs,
806
- device_ability_refs,
807
- is_ipc,
808
- channel_id,
809
- entity_type,
810
- exists_entities,
811
- )
803
+ product_id not in except_product_ids
804
+ and ImouHaDeviceManager.entity_need_add_to_device(
805
+ ref_id,
806
+ channel_ability_refs,
807
+ device_ability_refs,
808
+ is_ipc,
809
+ channel_id,
810
+ entity_type,
811
+ exists_entities,
812
+ )
812
813
  )
813
814
 
814
815
  @staticmethod
815
816
  def configure_switch_by_ref(
816
- channel_ability_refs: list[str],
817
- is_ipc: bool,
818
- device_ability_refs: list[str],
819
- imou_ha_device: ImouHaDevice,
817
+ channel_ability_refs: list[str],
818
+ is_ipc: bool,
819
+ device_ability_refs: list[str],
820
+ imou_ha_device: ImouHaDevice,
820
821
  ):
821
822
  for switch_type, ref_list in SWITCH_TYPE_REF.items():
822
823
  for ref in ref_list:
823
824
  if ImouHaDeviceManager.entity_need_add_to_device_by_ref(
824
- ref[PARAM_REF],
825
- channel_ability_refs,
826
- device_ability_refs,
827
- is_ipc,
828
- imou_ha_device.channel_id,
829
- switch_type,
830
- imou_ha_device.switches,
831
- imou_ha_device.product_id,
832
- ref.get(PARAM_EXCEPTS, []),
825
+ ref[PARAM_REF],
826
+ channel_ability_refs,
827
+ device_ability_refs,
828
+ is_ipc,
829
+ imou_ha_device.channel_id,
830
+ switch_type,
831
+ imou_ha_device.switches,
832
+ imou_ha_device.product_id,
833
+ ref.get(PARAM_EXCEPTS, []),
833
834
  ):
834
835
  imou_ha_device.switches[switch_type] = {
835
836
  PARAM_STATE: ref[PARAM_DEFAULT],
@@ -839,23 +840,23 @@ class ImouHaDeviceManager(object):
839
840
 
840
841
  @staticmethod
841
842
  def configure_button_by_ref(
842
- channel_ability_refs: list[str],
843
- is_ipc: bool,
844
- device_ability_refs: list[str],
845
- imou_ha_device: ImouHaDevice,
843
+ channel_ability_refs: list[str],
844
+ is_ipc: bool,
845
+ device_ability_refs: list[str],
846
+ imou_ha_device: ImouHaDevice,
846
847
  ):
847
848
  for button_type, ref_list in BUTTON_TYPE_REF.items():
848
849
  for ref in ref_list:
849
850
  if ImouHaDeviceManager.entity_need_add_to_device_by_ref(
850
- ref[PARAM_REF],
851
- channel_ability_refs,
852
- device_ability_refs,
853
- is_ipc,
854
- imou_ha_device.channel_id,
855
- button_type,
856
- imou_ha_device.buttons,
857
- imou_ha_device.product_id,
858
- ref.get(PARAM_EXCEPTS, []),
851
+ ref[PARAM_REF],
852
+ channel_ability_refs,
853
+ device_ability_refs,
854
+ is_ipc,
855
+ imou_ha_device.channel_id,
856
+ button_type,
857
+ imou_ha_device.buttons,
858
+ imou_ha_device.product_id,
859
+ ref.get(PARAM_EXCEPTS, []),
859
860
  ):
860
861
  imou_ha_device.buttons[button_type] = {
861
862
  PARAM_REF: ref[PARAM_REF],
@@ -864,23 +865,23 @@ class ImouHaDeviceManager(object):
864
865
 
865
866
  @staticmethod
866
867
  def configure_select_by_ref(
867
- channel_ability_refs: list[str],
868
- is_ipc: bool,
869
- device_ability_refs: list[str],
870
- imou_ha_device: ImouHaDevice,
868
+ channel_ability_refs: list[str],
869
+ is_ipc: bool,
870
+ device_ability_refs: list[str],
871
+ imou_ha_device: ImouHaDevice,
871
872
  ):
872
873
  for select_type, ref_list in SELECT_TYPE_REF.items():
873
874
  for ref in ref_list:
874
875
  if ImouHaDeviceManager.entity_need_add_to_device_by_ref(
875
- ref[PARAM_REF],
876
- channel_ability_refs,
877
- device_ability_refs,
878
- is_ipc,
879
- imou_ha_device.channel_id,
880
- select_type,
881
- imou_ha_device.selects,
882
- imou_ha_device.product_id,
883
- ref.get(PARAM_EXCEPTS, []),
876
+ ref[PARAM_REF],
877
+ channel_ability_refs,
878
+ device_ability_refs,
879
+ is_ipc,
880
+ imou_ha_device.channel_id,
881
+ select_type,
882
+ imou_ha_device.selects,
883
+ imou_ha_device.product_id,
884
+ ref.get(PARAM_EXCEPTS, []),
884
885
  ):
885
886
  imou_ha_device.selects[select_type] = {
886
887
  PARAM_REF: ref[PARAM_REF],
@@ -892,23 +893,23 @@ class ImouHaDeviceManager(object):
892
893
 
893
894
  @staticmethod
894
895
  def configure_sensor_by_ref(
895
- channel_ability_refs: list[str],
896
- is_ipc: bool,
897
- device_ability_refs: list[str],
898
- imou_ha_device: ImouHaDevice,
896
+ channel_ability_refs: list[str],
897
+ is_ipc: bool,
898
+ device_ability_refs: list[str],
899
+ imou_ha_device: ImouHaDevice,
899
900
  ):
900
901
  for sensor_type, ref_list in SENSOR_TYPE_REF.items():
901
902
  for ref in ref_list:
902
903
  if ImouHaDeviceManager.entity_need_add_to_device_by_ref(
903
- ref[PARAM_REF],
904
- channel_ability_refs,
905
- device_ability_refs,
906
- is_ipc,
907
- imou_ha_device.channel_id,
908
- sensor_type,
909
- imou_ha_device.sensors,
910
- imou_ha_device.product_id,
911
- ref.get(PARAM_EXCEPTS, []),
904
+ ref[PARAM_REF],
905
+ channel_ability_refs,
906
+ device_ability_refs,
907
+ is_ipc,
908
+ imou_ha_device.channel_id,
909
+ sensor_type,
910
+ imou_ha_device.sensors,
911
+ imou_ha_device.product_id,
912
+ ref.get(PARAM_EXCEPTS, []),
912
913
  ):
913
914
  imou_ha_device.sensors[sensor_type] = {
914
915
  PARAM_REF: ref[PARAM_REF],
@@ -920,23 +921,23 @@ class ImouHaDeviceManager(object):
920
921
 
921
922
  @staticmethod
922
923
  def configure_binary_sensor_by_ref(
923
- channel_ability_refs: list[str],
924
- is_ipc: bool,
925
- device_ability_refs: list[str],
926
- imou_ha_device: ImouHaDevice,
924
+ channel_ability_refs: list[str],
925
+ is_ipc: bool,
926
+ device_ability_refs: list[str],
927
+ imou_ha_device: ImouHaDevice,
927
928
  ):
928
929
  for binary_sensor_type, ref_list in BINARY_SENSOR_TYPE_REF.items():
929
930
  for ref in ref_list:
930
931
  if ImouHaDeviceManager.entity_need_add_to_device_by_ref(
931
- ref[PARAM_REF],
932
- channel_ability_refs,
933
- device_ability_refs,
934
- is_ipc,
935
- imou_ha_device.channel_id,
936
- binary_sensor_type,
937
- imou_ha_device.binary_sensors,
938
- imou_ha_device.product_id,
939
- ref.get(PARAM_EXCEPTS, []),
932
+ ref[PARAM_REF],
933
+ channel_ability_refs,
934
+ device_ability_refs,
935
+ is_ipc,
936
+ imou_ha_device.channel_id,
937
+ binary_sensor_type,
938
+ imou_ha_device.binary_sensors,
939
+ imou_ha_device.product_id,
940
+ ref.get(PARAM_EXCEPTS, []),
940
941
  ):
941
942
  imou_ha_device.binary_sensors[binary_sensor_type] = {
942
943
  PARAM_REF: ref[PARAM_REF],
@@ -945,41 +946,41 @@ class ImouHaDeviceManager(object):
945
946
  break
946
947
 
947
948
  async def _async_update_device_switch_status_by_ref(
948
- self, device: ImouHaDevice, switch_type: str, ref: str
949
+ self, device: ImouHaDevice, switch_type: str, ref: str
949
950
  ):
950
951
  try:
951
952
  device_id = device.device_id
952
953
  # 如果是配件,需要拼接设备id
953
954
  if device.parent_product_id is not None:
954
955
  device_id = (
955
- device_id
956
- + "_"
957
- + device.parent_device_id
958
- + "_"
959
- + device.parent_product_id
956
+ device_id
957
+ + "_"
958
+ + device.parent_device_id
959
+ + "_"
960
+ + device.parent_product_id
960
961
  )
961
962
  data = await self.delegate.async_get_iot_device_properties(
962
963
  device_id, device.channel_id, device.product_id, [ref]
963
964
  )
964
965
  if ref in data[PARAM_PROPERTIES]:
965
966
  device.switches[switch_type][PARAM_STATE] = (
966
- data[PARAM_PROPERTIES][ref] == 1
967
+ data[PARAM_PROPERTIES][ref] == 1
967
968
  )
968
969
  except Exception as e:
969
970
  _LOGGER.error(f"_async_update_device_switch_status_by_ref fail:{e}")
970
971
 
971
972
  async def _async_update_device_select_status_by_ref(
972
- self, device: ImouHaDevice, select_type: str, ref: str
973
+ self, device: ImouHaDevice, select_type: str, ref: str
973
974
  ):
974
975
  try:
975
976
  device_id = device.device_id
976
977
  if device.parent_product_id is not None:
977
978
  device_id = (
978
- device_id
979
- + "_"
980
- + device.parent_device_id
981
- + "_"
982
- + device.parent_product_id
979
+ device_id
980
+ + "_"
981
+ + device.parent_device_id
982
+ + "_"
983
+ + device.parent_product_id
983
984
  )
984
985
  data = await self.delegate.async_get_iot_device_properties(
985
986
  device_id, device.channel_id, device.product_id, [ref]
@@ -994,21 +995,21 @@ class ImouHaDeviceManager(object):
994
995
  _LOGGER.error(f"Error while updating device select status: {e}")
995
996
 
996
997
  async def _async_update_device_sensor_status_by_ref(
997
- self,
998
- device: ImouHaDevice,
999
- sensor_type: str,
1000
- value: dict[str, any],
998
+ self,
999
+ device: ImouHaDevice,
1000
+ sensor_type: str,
1001
+ value: dict[str, any],
1001
1002
  ):
1002
1003
  try:
1003
1004
  device_id = device.device_id
1004
1005
  # 如果是配件,需要拼接设备id
1005
1006
  if device.parent_product_id is not None:
1006
1007
  device_id = (
1007
- device_id
1008
- + "_"
1009
- + device.parent_device_id
1010
- + "_"
1011
- + device.parent_product_id
1008
+ device_id
1009
+ + "_"
1010
+ + device.parent_device_id
1011
+ + "_"
1012
+ + device.parent_product_id
1012
1013
  )
1013
1014
  state = await self._get_state_from_properties_or_services(
1014
1015
  device, device_id, value
@@ -1020,7 +1021,7 @@ class ImouHaDeviceManager(object):
1020
1021
  _LOGGER.error(f"_async_update_device_sensor_status_by_ref fail:{e}")
1021
1022
 
1022
1023
  async def _get_state_from_properties_or_services(
1023
- self, device: ImouHaDevice, device_id: str, value: dict
1024
+ self, device: ImouHaDevice, device_id: str, value: dict
1024
1025
  ):
1025
1026
  if value.get(PARAM_REF_TYPE, PARAM_PROPERTIES) == PARAM_SERVICES:
1026
1027
  result = await self.delegate.async_iot_device_control(
@@ -1042,33 +1043,33 @@ class ImouHaDeviceManager(object):
1042
1043
  device_id = device.device_id
1043
1044
  if device.parent_product_id is not None:
1044
1045
  device_id = (
1045
- device_id
1046
- + "_"
1047
- + device.parent_device_id
1048
- + "_"
1049
- + device.parent_product_id
1046
+ device_id
1047
+ + "_"
1048
+ + device.parent_device_id
1049
+ + "_"
1050
+ + device.parent_product_id
1050
1051
  )
1051
1052
  await self.delegate.async_iot_device_control(
1052
1053
  device_id, device.product_id, ref, {}
1053
1054
  )
1054
1055
 
1055
1056
  async def _async_select_option_by_ref(
1056
- self, device: ImouHaDevice, option: str, ref: str, value_type: str
1057
+ self, device: ImouHaDevice, option: str, ref: str, value_type: str
1057
1058
  ):
1058
1059
  device_id = device.device_id
1059
1060
  # 如果是配件,需要拼接设备id
1060
1061
  if device.parent_product_id is not None:
1061
1062
  device_id = (
1062
- device_id
1063
- + "_"
1064
- + device.parent_device_id
1065
- + "_"
1066
- + device.parent_product_id
1063
+ device_id
1064
+ + "_"
1065
+ + device.parent_device_id
1066
+ + "_"
1067
+ + device.parent_product_id
1067
1068
  )
1068
1069
  if "int" == value_type and (
1069
- ref != "15400"
1070
- or device.product_id
1071
- not in ["z76s20l415gnhhl1", "o8828zgeg1g9cfuz", "Q3YSZ54R", "BDHCWWPX"]
1070
+ ref != "15400"
1071
+ or device.product_id
1072
+ not in PRODUCT_MODEL_ILLEGAL_LIST
1072
1073
  ):
1073
1074
  value = int(option)
1074
1075
  else:
@@ -1082,16 +1083,16 @@ class ImouHaDeviceManager(object):
1082
1083
  )
1083
1084
 
1084
1085
  async def _async_switch_operation_by_ref(
1085
- self, device: ImouHaDevice, switch_type: str, enable: bool, ref: str
1086
+ self, device: ImouHaDevice, switch_type: str, enable: bool, ref: str
1086
1087
  ):
1087
1088
  device_id = device.device_id
1088
1089
  if device.parent_product_id is not None:
1089
1090
  device_id = (
1090
- device_id
1091
- + "_"
1092
- + device.parent_device_id
1093
- + "_"
1094
- + device.parent_product_id
1091
+ device_id
1092
+ + "_"
1093
+ + device.parent_device_id
1094
+ + "_"
1095
+ + device.parent_product_id
1095
1096
  )
1096
1097
  await self.delegate.async_set_iot_device_properties(
1097
1098
  device_id, device.channel_id, device.product_id, {ref: 1 if enable else 0}
@@ -1105,21 +1106,21 @@ class ImouHaDeviceManager(object):
1105
1106
 
1106
1107
  @staticmethod
1107
1108
  def configure_binary_sensor_by_ability(
1108
- channel_abilities: list[str],
1109
- is_ipc: bool,
1110
- device_abilities: list[str],
1111
- imou_ha_device: ImouHaDevice,
1109
+ channel_abilities: list[str],
1110
+ is_ipc: bool,
1111
+ device_abilities: list[str],
1112
+ imou_ha_device: ImouHaDevice,
1112
1113
  ):
1113
1114
  for binary_sensor_type, ability_list in BINARY_SENSOR_TYPE_ABILITY.items():
1114
1115
  for ability in ability_list:
1115
1116
  if ImouHaDeviceManager.entity_need_add_to_device(
1116
- ability,
1117
- channel_abilities,
1118
- device_abilities,
1119
- is_ipc,
1120
- imou_ha_device.channel_id,
1121
- binary_sensor_type,
1122
- imou_ha_device.binary_sensors,
1117
+ ability,
1118
+ channel_abilities,
1119
+ device_abilities,
1120
+ is_ipc,
1121
+ imou_ha_device.channel_id,
1122
+ binary_sensor_type,
1123
+ imou_ha_device.binary_sensors,
1123
1124
  ):
1124
1125
  imou_ha_device.binary_sensors[binary_sensor_type] = {
1125
1126
  PARAM_STATE: False
@@ -1134,32 +1135,32 @@ class ImouHaDeviceManager(object):
1134
1135
  )
1135
1136
 
1136
1137
  async def _async_update_device_binary_sensor_status_by_ref(
1137
- self, device: ImouHaDevice, binary_sensor_type: str, ref: str
1138
+ self, device: ImouHaDevice, binary_sensor_type: str, ref: str
1138
1139
  ):
1139
1140
  try:
1140
1141
  device_id = device.device_id
1141
1142
  # 如果是配件,需要拼接设备id
1142
1143
  if device.parent_product_id is not None:
1143
1144
  device_id = (
1144
- device_id
1145
- + "_"
1146
- + device.parent_device_id
1147
- + "_"
1148
- + device.parent_product_id
1145
+ device_id
1146
+ + "_"
1147
+ + device.parent_device_id
1148
+ + "_"
1149
+ + device.parent_product_id
1149
1150
  )
1150
1151
  data = await self.delegate.async_get_iot_device_properties(
1151
1152
  device_id, device.channel_id, device.product_id, [ref]
1152
1153
  )
1153
1154
  if ref in data[PARAM_PROPERTIES]:
1154
1155
  device.binary_sensors[binary_sensor_type][PARAM_STATE] = (
1155
- data[PARAM_PROPERTIES][ref] == 1
1156
+ data[PARAM_PROPERTIES][ref] == 1
1156
1157
  )
1157
1158
  except Exception as e:
1158
1159
  _LOGGER.warning(
1159
1160
  f"_async_update_device_binary_sensor_status_by_ref fail:{e}"
1160
1161
  )
1161
1162
 
1162
- async def _async_update_device_battery(self, device):
1163
+ async def _async_update_device_battery(self, device, retry: bool = False):
1163
1164
  try:
1164
1165
  data = await self.delegate.async_get_device_power_info(device.device_id)
1165
1166
  if data.get(PARAM_ELECTRICITYS):
@@ -1177,30 +1178,39 @@ class ImouHaDeviceManager(object):
1177
1178
  electricity[PARAM_ELECTRIC]
1178
1179
  )
1179
1180
  else:
1180
- device.sensors[PARAM_BATTERY] = "0"
1181
+ device.sensors[PARAM_BATTERY][PARAM_STATE] = "0"
1181
1182
  except RequestFailedException as exception:
1182
- _LOGGER.error(f"_async_update_device_battery error: {exception}")
1183
- device.sensors[PARAM_BATTERY] = "0"
1183
+ # 如果在休眠,则唤醒设备后重试一次
1184
+ if ERROR_CODE_DEVICE_SLEEPING in exception.message and not retry:
1185
+ try:
1186
+ await self.delegate.async_wake_up_device(device.device_id)
1187
+ await self._async_update_device_battery(device, True)
1188
+ except RequestFailedException as e:
1189
+ _LOGGER.error(f"_async_update_device_battery error: {e}")
1190
+ device.sensors[PARAM_BATTERY][PARAM_STATE] = "0"
1191
+ else:
1192
+ _LOGGER.error(f"_async_update_device_battery error: {exception}")
1193
+ device.sensors[PARAM_BATTERY][PARAM_STATE] = "0"
1184
1194
 
1185
1195
  @staticmethod
1186
1196
  def configure_text_by_ref(
1187
- channel_ability_refs: list[str],
1188
- is_ipc: bool,
1189
- device_ability_refs: list[str],
1190
- imou_ha_device: ImouHaDevice,
1197
+ channel_ability_refs: list[str],
1198
+ is_ipc: bool,
1199
+ device_ability_refs: list[str],
1200
+ imou_ha_device: ImouHaDevice,
1191
1201
  ):
1192
1202
  for text_type, ref_list in TEXT_TYPE_REF.items():
1193
1203
  for ref in ref_list:
1194
1204
  if ImouHaDeviceManager.entity_need_add_to_device_by_ref(
1195
- ref[PARAM_REF],
1196
- channel_ability_refs,
1197
- device_ability_refs,
1198
- is_ipc,
1199
- imou_ha_device.channel_id,
1200
- text_type,
1201
- imou_ha_device.texts,
1202
- imou_ha_device.product_id,
1203
- ref.get(PARAM_EXCEPTS, []),
1205
+ ref[PARAM_REF],
1206
+ channel_ability_refs,
1207
+ device_ability_refs,
1208
+ is_ipc,
1209
+ imou_ha_device.channel_id,
1210
+ text_type,
1211
+ imou_ha_device.texts,
1212
+ imou_ha_device.product_id,
1213
+ ref.get(PARAM_EXCEPTS, []),
1204
1214
  ):
1205
1215
  imou_ha_device.texts[text_type] = {
1206
1216
  PARAM_REF: ref[PARAM_REF],
@@ -1219,21 +1229,21 @@ class ImouHaDeviceManager(object):
1219
1229
  )
1220
1230
 
1221
1231
  async def _async_update_device_text_status_by_ref(
1222
- self,
1223
- device: ImouHaDevice,
1224
- text_type: str,
1225
- value: dict[str, any],
1232
+ self,
1233
+ device: ImouHaDevice,
1234
+ text_type: str,
1235
+ value: dict[str, any],
1226
1236
  ):
1227
1237
  try:
1228
1238
  device_id = device.device_id
1229
1239
  # 如果是配件,需要拼接设备id
1230
1240
  if device.parent_product_id is not None:
1231
1241
  device_id = (
1232
- device_id
1233
- + "_"
1234
- + device.parent_device_id
1235
- + "_"
1236
- + device.parent_product_id
1242
+ device_id
1243
+ + "_"
1244
+ + device.parent_device_id
1245
+ + "_"
1246
+ + device.parent_product_id
1237
1247
  )
1238
1248
  state = await self._get_state_from_properties_or_services(
1239
1249
  device, device_id, value
@@ -1245,17 +1255,17 @@ class ImouHaDeviceManager(object):
1245
1255
  _LOGGER.error(f"_async_update_device_text_status_by_ref fail:{e}")
1246
1256
 
1247
1257
  async def _async_set_count_down_switch_time(
1248
- self, device: ImouHaDevice, text_value: str
1258
+ self, device: ImouHaDevice, text_value: str
1249
1259
  ):
1250
1260
  device_id = device.device_id
1251
1261
  # 如果是配件,需要拼接设备id
1252
1262
  if device.parent_product_id is not None:
1253
1263
  device_id = (
1254
- device_id
1255
- + "_"
1256
- + device.parent_device_id
1257
- + "_"
1258
- + device.parent_product_id
1264
+ device_id
1265
+ + "_"
1266
+ + device.parent_device_id
1267
+ + "_"
1268
+ + device.parent_product_id
1259
1269
  )
1260
1270
  # 首先查询当前开关状态
1261
1271
  switch_type = "switch"
@@ -1270,6 +1280,7 @@ class ImouHaDeviceManager(object):
1270
1280
  # 如果是开的,则倒计时关闭
1271
1281
  param["28603"] = 0
1272
1282
  else:
1283
+ # 如果是关的,则倒计时打开
1273
1284
  param["28603"] = 1
1274
1285
  await self.delegate.async_iot_device_control(
1275
1286
  device_id, device.product_id, "28600", param
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyimouapi
3
- Version: 1.1.26
3
+ Version: 1.2.0
4
4
  Summary: A package for imou open api
5
5
  Home-page: https://github.com/Imou-OpenPlatform/Py-Imou-Open-Api
6
6
  Author: Imou-OpenPlatform
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="pyimouapi",
5
- version="1.1.26",
5
+ version="1.2.0",
6
6
  packages=find_packages(),
7
7
  description="A package for imou open api",
8
8
  long_description=open("README.md", encoding="utf-8").read(),
File without changes
File without changes
File without changes