python-aidot-cameras 1.0.0rc15__tar.gz → 1.0.0rc16__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.
Files changed (297) hide show
  1. {python_aidot_cameras-1.0.0rc15/python_aidot_cameras.egg-info → python_aidot_cameras-1.0.0rc16}/PKG-INFO +1 -1
  2. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/controls.py +74 -1
  3. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/models.py +28 -1
  4. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/pyproject.toml +1 -1
  5. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16/python_aidot_cameras.egg-info}/PKG-INFO +1 -1
  6. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/python_aidot_cameras.egg-info/SOURCES.txt +1 -0
  7. python_aidot_cameras-1.0.0rc16/tests/test_auto_light_settings.py +143 -0
  8. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/LICENSE +0 -0
  9. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/MANIFEST.in +0 -0
  10. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/README.md +0 -0
  11. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/__init__.py +0 -0
  12. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/__main__.py +0 -0
  13. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_upstream.py +0 -0
  14. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/__init__.py +0 -0
  15. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/LICENSE +0 -0
  16. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/__init__.py +0 -0
  17. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/clock.py +0 -0
  18. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/codecs/__init__.py +0 -0
  19. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/codecs/base.py +0 -0
  20. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/codecs/g711.py +0 -0
  21. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/codecs/g722.py +0 -0
  22. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/codecs/h264.py +0 -0
  23. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/codecs/opus.py +0 -0
  24. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/codecs/vpx.py +0 -0
  25. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/contrib/__init__.py +0 -0
  26. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/contrib/media.py +0 -0
  27. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/contrib/signaling.py +0 -0
  28. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/events.py +0 -0
  29. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/exceptions.py +0 -0
  30. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/jitterbuffer.py +0 -0
  31. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/mediastreams.py +0 -0
  32. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rate.py +0 -0
  33. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcconfiguration.py +0 -0
  34. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcdatachannel.py +0 -0
  35. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcdtlstransport.py +0 -0
  36. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcicetransport.py +0 -0
  37. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcpeerconnection.py +0 -0
  38. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcrtpparameters.py +0 -0
  39. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcrtpreceiver.py +0 -0
  40. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcrtpsender.py +0 -0
  41. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcrtptransceiver.py +0 -0
  42. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcsctptransport.py +0 -0
  43. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtcsessiondescription.py +0 -0
  44. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/rtp.py +0 -0
  45. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/sdp.py +0 -0
  46. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/stats.py +0 -0
  47. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/_vendor/aiortc/utils.py +0 -0
  48. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/ble_gateway.py +0 -0
  49. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/__init__.py +0 -0
  50. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/client.py +0 -0
  51. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/constants.py +0 -0
  52. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/go2rtc.py +0 -0
  53. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/hwaccel.py +0 -0
  54. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/lan_control.py +0 -0
  55. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/playback.py +0 -0
  56. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/protocol.py +0 -0
  57. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/sd_events.py +0 -0
  58. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/sd_listing.py +0 -0
  59. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/sd_playback.py +0 -0
  60. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/sdes.py +0 -0
  61. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/sdes_open.py +0 -0
  62. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/tutk.py +0 -0
  63. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/webrtc.py +0 -0
  64. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/camera/webrtc_open.py +0 -0
  65. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/client.py +0 -0
  66. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/cloud_auth.py +0 -0
  67. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/const.py +0 -0
  68. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/credentials.py +0 -0
  69. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/crypto.py +0 -0
  70. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/device_client.py +0 -0
  71. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/discover.py +0 -0
  72. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/exceptions.py +0 -0
  73. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/g711.py +0 -0
  74. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/lan_retry.py +0 -0
  75. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/aidot_cameras/py.typed +0 -0
  76. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/python_aidot_cameras.egg-info/dependency_links.txt +0 -0
  77. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/python_aidot_cameras.egg-info/entry_points.txt +0 -0
  78. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/python_aidot_cameras.egg-info/requires.txt +0 -0
  79. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/python_aidot_cameras.egg-info/top_level.txt +0 -0
  80. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/setup.cfg +0 -0
  81. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_abandoned_attempt_skips_the_doomed_serve.py +0 -0
  82. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_abandoned_wait_still_maps_audio.py +0 -0
  83. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_aioice_compat.py +0 -0
  84. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_alarm_event.py +0 -0
  85. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_answer_pt_kinds.py +0 -0
  86. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_answer_sdp_video_pt.py +0 -0
  87. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_answer_section_selection.py +0 -0
  88. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_audio_mux_offline.py +0 -0
  89. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_auto_alarm.py +0 -0
  90. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_avio_ctrl_uses_the_session_dseq.py +0 -0
  91. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_avio_request.py +0 -0
  92. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_avio_response_parse.py +0 -0
  93. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_avio_response_router.py +0 -0
  94. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_backoff.py +0 -0
  95. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_battery_detection.py +0 -0
  96. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_battery_evidence_corroboration.py +0 -0
  97. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_battery_skip_turn.py +0 -0
  98. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_battery_stale_offer_is_abandoned_early.py +0 -0
  99. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_battery_wake_gate_app_parity.py +0 -0
  100. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_bitrate_campaign_arms.py +0 -0
  101. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_ble_gateway.py +0 -0
  102. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_bridge_state_sentinels.py +0 -0
  103. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_busy_backoff.py +0 -0
  104. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_camera_properties.py +0 -0
  105. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_canary_log_names_the_camera.py +0 -0
  106. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_cloud_count.py +0 -0
  107. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_cloud_plan.py +0 -0
  108. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_constants_imports_resolve.py +0 -0
  109. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_control_verdicts.py +0 -0
  110. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_deferred_hardening.py +0 -0
  111. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_detection_types.py +0 -0
  112. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_device_cmd_seq_match.py +0 -0
  113. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_device_login_guard.py +0 -0
  114. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_device_user_info_cache.py +0 -0
  115. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_direct_ts_keyframe_signal.py +0 -0
  116. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_direct_ts_serve.py +0 -0
  117. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dormant_camera_cleanup.py +0 -0
  118. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_drain_is_cancellable.py +0 -0
  119. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_mux_terminal_write.py +0 -0
  120. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_not_ready_burst.py +0 -0
  121. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_pinning.py +0 -0
  122. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_resolution_ack.py +0 -0
  123. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_serve_decode_skip.py +0 -0
  124. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_serve_ice_wait.py +0 -0
  125. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_serve_open_timeout.py +0 -0
  126. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_skip_signaling_wait.py +0 -0
  127. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_slow_probe.py +0 -0
  128. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_stdout_producer.py +0 -0
  129. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_dtls_video_presence.py +0 -0
  130. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_egress_guard.py +0 -0
  131. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_env_seams.py +0 -0
  132. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_feature_probe_needs_a_live_session.py +0 -0
  133. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_ffmpeg_signal_exit_is_not_a_crash.py +0 -0
  134. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_futile_keepalive.py +0 -0
  135. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_gate_requires_a_decoded_frame.py +0 -0
  136. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_go2rtc.py +0 -0
  137. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_go2rtc_cli.py +0 -0
  138. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_h264_decode_rate_limit.py +0 -0
  139. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_highport_nomination.py +0 -0
  140. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_hwaccel_probe.py +0 -0
  141. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_ice_config_cache.py +0 -0
  142. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_ice_credentials_match_the_app.py +0 -0
  143. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_ice_peer_reflexive.py +0 -0
  144. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_idle_release_both_loops.py +0 -0
  145. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_keepalive_renew.py +0 -0
  146. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_key_restart_sdp.py +0 -0
  147. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_keyframe_prompter.py +0 -0
  148. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_lan_control.py +0 -0
  149. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_lan_retry_reaches_the_storming_devices.py +0 -0
  150. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_late_repeats_are_dropped.py +0 -0
  151. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_light_active_color_mode.py +0 -0
  152. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_live_session_carries_talk.py +0 -0
  153. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_live_stream_param.py +0 -0
  154. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_live_validate_policy.py +0 -0
  155. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_live_video_canary.py +0 -0
  156. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_liveplay_echo_timeout.py +0 -0
  157. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_local_only_controls.py +0 -0
  158. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_logging_caps.py +0 -0
  159. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_login_connect_deadline.py +0 -0
  160. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_login_reconnect_backoff.py +0 -0
  161. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_media_counted_only_when_plaintext.py +0 -0
  162. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_media_path_is_reported.py +0 -0
  163. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_media_socket_rcvbuf.py +0 -0
  164. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_media_wait_floor.py +0 -0
  165. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_motion_poll.py +0 -0
  166. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_mqtt_client_id_is_exact.py +0 -0
  167. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_mqtt_credential_refetch.py +0 -0
  168. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_mqtt_credential_self_heal.py +0 -0
  169. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_mqtt_password_not_persisted.py +0 -0
  170. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_mqtt_session_reconnect.py +0 -0
  171. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_mqtt_thread_not_orphaned.py +0 -0
  172. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_nack.py +0 -0
  173. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_nack_cannot_add_load_in_a_burst.py +0 -0
  174. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_narrow_pc_ice.py +0 -0
  175. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_no_key_material_in_logs.py +0 -0
  176. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_no_self_referential_go2rtc.py +0 -0
  177. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_no_unbounded_hex_dumps.py +0 -0
  178. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_no_undefined_names.py +0 -0
  179. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_nominates_as_soon_as_the_answer_lands.py +0 -0
  180. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_off_subnet_candidate.py +0 -0
  181. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_offer_bandwidth_line.py +0 -0
  182. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_offer_keeps_rtcp_feedback.py +0 -0
  183. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_offline_keepalive_pause.py +0 -0
  184. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_on_frame_is_an_av_frame.py +0 -0
  185. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_open_fail_logger.py +0 -0
  186. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_open_gate_delay.py +0 -0
  187. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_peer_id_class_env.py +0 -0
  188. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_peer_id_client_type.py +0 -0
  189. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_peerid_reuse.py +0 -0
  190. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_persistent_mqtt.py +0 -0
  191. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_persistent_mqtt_robustness.py +0 -0
  192. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_playback_tls.py +0 -0
  193. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_post_merge_hardening.py +0 -0
  194. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_ptz_probe_reads_what_it_is_told.py +0 -0
  195. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_public_signature_matches_impl.py +0 -0
  196. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_publish_target_readiness.py +0 -0
  197. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_quality_campaign_in_session.py +0 -0
  198. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_reboot_action.py +0 -0
  199. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_recent_recordings.py +0 -0
  200. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_remb.py +0 -0
  201. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_remb_goes_out_the_relay_aware_sender.py +0 -0
  202. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_resent_frames_are_dropped.py +0 -0
  203. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_resolution_persists.py +0 -0
  204. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_restart_cycle.py +0 -0
  205. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_retry_policy.py +0 -0
  206. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_scripts_importable.py +0 -0
  207. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sctp_init_ack_tsn.py +0 -0
  208. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sctp_reassembly.py +0 -0
  209. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sctp_sack.py +0 -0
  210. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sd_card_presence.py +0 -0
  211. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sd_event_decode.py +0 -0
  212. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sd_event_probe_payloads.py +0 -0
  213. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sd_listing.py +0 -0
  214. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sd_playback.py +0 -0
  215. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_adaptive.py +0 -0
  216. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_avio_dispatch.py +0 -0
  217. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_bridge_break_gate.py +0 -0
  218. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_connection_mode.py +0 -0
  219. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_echo_wait_is_not_dead_time.py +0 -0
  220. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_fast_liveplay.py +0 -0
  221. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_ffmpeg_stderr_log.py +0 -0
  222. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_first_media_stall_report.py +0 -0
  223. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_ice_teardown.py +0 -0
  224. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_idle_release.py +0 -0
  225. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_nack_bridge.py +0 -0
  226. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_offer_video_order.py +0 -0
  227. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_offer_video_pin.py +0 -0
  228. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_open_cleanup.py +0 -0
  229. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_sctp_abort.py +0 -0
  230. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_serve_audio.py +0 -0
  231. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_serve_cmd.py +0 -0
  232. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_serve_stderr_drain.py +0 -0
  233. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_session_cap.py +0 -0
  234. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_sprop.py +0 -0
  235. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_talk.py +0 -0
  236. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_teardown_exit_log.py +0 -0
  237. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_terminal_ack.py +0 -0
  238. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_terminal_ack_latency.py +0 -0
  239. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_tmmbr_bridge.py +0 -0
  240. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdes_watchdog.py +0 -0
  241. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdp_narrowing_properties.py +0 -0
  242. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sdp_payload_type_narrowing.py +0 -0
  243. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_security_hardening.py +0 -0
  244. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_self_peer_is_an_address_not_an_ip.py +0 -0
  245. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_serializable_login_info.py +0 -0
  246. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_serve_input_timeout.py +0 -0
  247. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_serve_loss_tolerance.py +0 -0
  248. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_serve_pt_respects_the_pin.py +0 -0
  249. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_serve_relay.py +0 -0
  250. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_serve_stderr_keeps_the_reason.py +0 -0
  251. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_session_stats.py +0 -0
  252. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_shared_house_seam.py +0 -0
  253. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_signalling_is_attributable_to_a_camera.py +0 -0
  254. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_snapshot_cancellation.py +0 -0
  255. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_speak.py +0 -0
  256. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sprop_capture_gate.py +0 -0
  257. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sprop_staleness.py +0 -0
  258. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sprop_unstable_public.py +0 -0
  259. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_sprop_write_is_reported_truthfully.py +0 -0
  260. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_srtp_rx_rekey.py +0 -0
  261. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_srtp_tx_key_note.py +0 -0
  262. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stable_terminal_id.py +0 -0
  263. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stall_nudge_policy.py +0 -0
  264. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stall_report_says_what_the_answer_carried.py +0 -0
  265. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stall_report_says_whether_the_trigger_was_answered.py +0 -0
  266. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stall_report_separates_silence_from_undecryptable.py +0 -0
  267. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stall_report_survives_a_caller_giving_up.py +0 -0
  268. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stall_reports_reach_the_artifact.py +0 -0
  269. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_status_and_trace_channels.py +0 -0
  270. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stream_cap.py +0 -0
  271. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stream_drain_ownership.py +0 -0
  272. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stream_idle.py +0 -0
  273. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stream_slot_cap.py +0 -0
  274. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_stream_teardown.py +0 -0
  275. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_talk.py +0 -0
  276. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_talk_reports_a_speaker_that_never_opened.py +0 -0
  277. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_tap_to_mux_end_to_end.py +0 -0
  278. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_terminal_ack.py +0 -0
  279. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_tmmbr.py +0 -0
  280. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_token_file_robustness.py +0 -0
  281. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_token_refresh.py +0 -0
  282. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_transport_failure_reporting.py +0 -0
  283. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_turn_create_permission.py +0 -0
  284. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_tutk_path_is_out_of_reach.py +0 -0
  285. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_unbuildable_summary_repeats_at_debug.py +0 -0
  286. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_upstream_compat.py +0 -0
  287. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_validator_shares_one_token.py +0 -0
  288. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_video_profile_log.py +0 -0
  289. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_video_pts_dts.py +0 -0
  290. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_video_ts_unwrap.py +0 -0
  291. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_viewer_check_throttle.py +0 -0
  292. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_viewer_presence.py +0 -0
  293. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_viewer_present_push_mode.py +0 -0
  294. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_wait_or_event.py +0 -0
  295. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_wake_gate_camera_evidence.py +0 -0
  296. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_wake_readiness_retry.py +0 -0
  297. {python_aidot_cameras-1.0.0rc15 → python_aidot_cameras-1.0.0rc16}/tests/test_webrtc_answer_race.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot-cameras
3
- Version: 1.0.0rc15
3
+ Version: 1.0.0rc16
4
4
  Summary: Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)
5
5
  Author-email: cbrightly <chris.brightly@gmail.com>
6
6
  License-Expression: MIT
@@ -15,6 +15,24 @@ from .constants import _PTZ_DIR_CODES, _STREAM_QUALITY, SETSTREAMCTRL_CMD
15
15
 
16
16
  _LOGGER = logging.getLogger(__name__)
17
17
 
18
+ #: How the floodlight behaves when the camera sees someone, by the name the
19
+ #: vendor app prints against each value. From the cloud device profile
20
+ #: (LK.IPC.A001513): ``lightBehavior`` is an enum with allowedValues
21
+ #: ``Constant=0, Flash=1``, default 0.
22
+ LIGHT_BEHAVIORS = {"constant": 0, "flash": 1}
23
+
24
+ #: How long the floodlight stays on after it triggers, in seconds. The camera
25
+ #: enumerates exactly these four (``LingerDuration``, default 30) -- it is not a
26
+ #: free range, and a value outside the set is accepted on the wire and ignored,
27
+ #: which would leave a control reporting a setting the camera never applied.
28
+ LIGHT_LINGER_DURATIONS = (20, 30, 40, 50)
29
+
30
+ #: The floodlight level the camera accepts (``Dimming``: min 10, max 100).
31
+ #: The floor is 10, not 0: 0 is out of range rather than "off", and off is
32
+ #: LightOnOff.
33
+ LIGHT_BRIGHTNESS_MIN = 10
34
+ LIGHT_BRIGHTNESS_MAX = 100
35
+
18
36
  #: The camera's ack for SETSTREAMCTRL (800).
19
37
  SETSTREAMCTRL_RESP_CMD = 801
20
38
  #: Measured 0.01-0.03s; short so a control call never holds up a view.
@@ -56,10 +74,65 @@ class _CameraControlsMixin:
56
74
  return await self.async_set_device_attribute("OSDEnable", 1 if enabled else 0)
57
75
 
58
76
  async def async_set_auto_light(self, enabled: bool) -> bool:
59
- """Enable or disable floodlight automation (autoLightEnable)."""
77
+ """Turn the light-up-when-someone-appears automation on or off.
78
+
79
+ This is ``autoLightEnable``, which the vendor app labels "When Someone
80
+ Appears" (or "When Someone Appears at Night" on some models -- that is
81
+ which label the app prints for the model, not a separate setting).
82
+ """
60
83
  return await self.async_set_device_attribute(
61
84
  "autoLightEnable", 1 if enabled else 0)
62
85
 
86
+ async def async_set_light_behavior(self, behavior: str) -> bool:
87
+ """Set how the light behaves when it triggers: "constant" or "flash".
88
+
89
+ **This write acks and does not land.** Measured 2026-09-07 against an
90
+ A001513 (which declares ``lightBehavior`` in its profile) and an
91
+ A000088 (which does not): six attempts across both models, as int 1 and
92
+ as string "1", every one returning True and every read-back over the
93
+ following 20 s still reporting the old value. On the same camera in the
94
+ same session ``LingerDuration`` and ``Dimming`` both landed within 4 s,
95
+ so this is the attribute, not the camera being asleep or the cloud
96
+ lagging. The one hypothesis left untested is that the camera takes it
97
+ only while ``autoLightEnable`` is 1 -- untested because arming it makes
98
+ a real floodlight come on in someone's house.
99
+
100
+ The method is kept because the command is well-formed and a future
101
+ firmware may honour it, but **nothing should build a control on it**
102
+ until a read-back confirms one: a setting that reports a value the
103
+ camera never applied is worse than no setting. Same call as
104
+ ``async_set_resolution``.
105
+
106
+ Refuses a name the camera does not offer rather than sending it: the
107
+ attribute is an enum, and an out-of-range write is accepted silently.
108
+ """
109
+ try:
110
+ value = LIGHT_BEHAVIORS[behavior]
111
+ except KeyError:
112
+ raise ValueError(
113
+ f"unknown light behavior {behavior!r}; "
114
+ f"expected one of {sorted(LIGHT_BEHAVIORS)}") from None
115
+ return await self.async_set_device_attribute("lightBehavior", value)
116
+
117
+ async def async_set_light_linger_duration(self, seconds: int) -> bool:
118
+ """Set how long the light stays on after it triggers, in seconds."""
119
+ if seconds not in LIGHT_LINGER_DURATIONS:
120
+ raise ValueError(
121
+ f"unsupported linger duration {seconds!r}; "
122
+ f"the camera offers {list(LIGHT_LINGER_DURATIONS)}")
123
+ return await self.async_set_device_attribute("LingerDuration", seconds)
124
+
125
+ async def async_set_light_brightness(self, level: int) -> bool:
126
+ """Set the floodlight level (10-100), clamped to what the camera takes.
127
+
128
+ Separate from :meth:`async_set_floodlight`'s optional brightness, which
129
+ is part of turning the light on by hand; this is the level the camera
130
+ uses when its own automation fires.
131
+ """
132
+ return await self.async_set_device_attribute(
133
+ "Dimming",
134
+ max(LIGHT_BRIGHTNESS_MIN, min(LIGHT_BRIGHTNESS_MAX, int(level))))
135
+
63
136
  async def async_set_voice_prompts(self, enabled: bool) -> bool:
64
137
  """Enable or disable spoken prompts from the camera speaker (voiceEnable)."""
65
138
  return await self.async_set_device_attribute(
@@ -97,8 +97,18 @@ class CameraStatusData(DeviceStatusData):
97
97
  status_led: Optional[bool] = None
98
98
  #: Timestamp/OSD overlay burned into the video (OSDEnable).
99
99
  osd_timestamp: Optional[bool] = None
100
- #: Floodlight automation (autoLightEnable).
100
+ #: Floodlight automation (autoLightEnable). The vendor app labels this
101
+ #: "When Someone Appears" -- it is the person-triggered light, not a
102
+ #: generic schedule, and the three fields below are its settings.
101
103
  auto_light: Optional[bool] = None
104
+ #: How the light behaves when it triggers: "constant" or "flash"
105
+ #: (lightBehavior 0/1). An unmodelled number is carried through as itself.
106
+ light_behavior: Optional[str] = None
107
+ #: How long the light stays on after a trigger, in seconds (LingerDuration).
108
+ light_linger_duration: Optional[int] = None
109
+ #: Floodlight level 10-100 (Dimming). Kept apart from `dimming`, which is
110
+ #: the light platform's brightness -- see _LIGHT_ONLY_ATTR_KEYS.
111
+ light_brightness: Optional[int] = None
102
112
  #: Spoken prompts from the camera speaker (voiceEnable).
103
113
  voice_prompts: Optional[bool] = None
104
114
  #: HDR (HDRStatus).
@@ -153,6 +163,16 @@ class CameraStatusData(DeviceStatusData):
153
163
  self.osd_timestamp = b
154
164
  if (b := _as_bool(attr.get("autoLightEnable"))) is not None:
155
165
  self.auto_light = b
166
+ if (v := attr.get("lightBehavior")) is not None:
167
+ lb = _as_int(v)
168
+ # Same shape as nightVisionMode: name the values we know and carry
169
+ # anything else through, so a firmware that grows a third mode
170
+ # cannot be reported as one of the two we do know.
171
+ self.light_behavior = (
172
+ {0: "constant", 1: "flash"}.get(lb, str(lb))
173
+ if lb is not None else str(v))
174
+ if (i := _as_int(attr.get("LingerDuration"))) is not None:
175
+ self.light_linger_duration = i
156
176
  if (b := _as_bool(attr.get("voiceEnable"))) is not None:
157
177
  self.voice_prompts = b
158
178
  if (b := _as_bool(attr.get("HDRStatus"))) is not None:
@@ -201,6 +221,13 @@ class CameraStatusData(DeviceStatusData):
201
221
  ``properties`` dict - both share the same camera attribute keys
202
222
  (Battery_remaining, Occupancy, SDcardStatus, MotionDetection_*, ...).
203
223
  """
224
+ # Dimming is filtered out below because on a LIGHT it is the entity's
225
+ # brightness, and a camera's must never be read as one. On a camera it
226
+ # is nonetheless a real setting -- the floodlight's level, 10-100 in the
227
+ # device profile, and what the app's Brightness page writes -- so read
228
+ # it here into its own field rather than letting the filter lose it.
229
+ if (i := _as_int(attrs.get(CONF_DIMMING))) is not None:
230
+ self.light_brightness = i
204
231
  self.update({
205
232
  k: v for k, v in attrs.items()
206
233
  if k not in self._LIGHT_ONLY_ATTR_KEYS
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-aidot-cameras"
7
- version = "1.0.0rc15"
7
+ version = "1.0.0rc16"
8
8
  description = "Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot-cameras
3
- Version: 1.0.0rc15
3
+ Version: 1.0.0rc16
4
4
  Summary: Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)
5
5
  Author-email: cbrightly <chris.brightly@gmail.com>
6
6
  License-Expression: MIT
@@ -84,6 +84,7 @@ tests/test_answer_sdp_video_pt.py
84
84
  tests/test_answer_section_selection.py
85
85
  tests/test_audio_mux_offline.py
86
86
  tests/test_auto_alarm.py
87
+ tests/test_auto_light_settings.py
87
88
  tests/test_avio_ctrl_uses_the_session_dseq.py
88
89
  tests/test_avio_request.py
89
90
  tests/test_avio_response_parse.py
@@ -0,0 +1,143 @@
1
+ """The camera's "light up when someone appears" settings.
2
+
3
+ The vendor app calls the master toggle "When Someone Appears" and it is the
4
+ `autoLightEnable` attribute this library already exposes. The three settings
5
+ that sit UNDER it in the app were missing:
6
+
7
+ lightBehavior enum Constant=0, Flash=1 (default 0)
8
+ LingerDuration enum 20 / 30 / 40 / 50 seconds (default 30)
9
+ Dimming int 10..100 step 1 (default 100)
10
+
11
+ Read from the cloud device profile 2026-09-07 (LK.IPC.A001513, the L2), and
12
+ every one of the three is carried as a live property value by the L2 and by the
13
+ A000088 alike. Of the three, `LingerDuration` and `Dimming` were confirmed on
14
+ hardware to land (written, read back changed, restored); `lightBehavior` acks
15
+ and does NOT land on either model, so the library keeps the setter and Home
16
+ Assistant deliberately ships no control for it -- see
17
+ `async_set_light_behavior`. The A001064 has neither `lightBehavior` nor `LingerDuration` in
18
+ its profile or its properties, so those controls must stay absent there rather
19
+ than appear reading "unknown" -- which is why every getter here answers None
20
+ for a camera that never reported the key.
21
+ """
22
+
23
+ import asyncio
24
+
25
+ import pytest
26
+
27
+ from aidot_cameras.camera.controls import (
28
+ LIGHT_BEHAVIORS,
29
+ LIGHT_LINGER_DURATIONS,
30
+ _CameraControlsMixin,
31
+ )
32
+ from aidot_cameras.camera.models import CameraStatusData
33
+
34
+
35
+ class _Cam(_CameraControlsMixin):
36
+ device_id = "cam1"
37
+
38
+ def __init__(self):
39
+ self.attrs: list = []
40
+
41
+ async def async_set_device_attribute(self, attr, value, **kw):
42
+ self.attrs.append((attr, value))
43
+ return True
44
+
45
+
46
+ # --- reading -----------------------------------------------------------------
47
+
48
+ def test_light_behavior_reads_as_a_name_not_a_number():
49
+ s = CameraStatusData()
50
+ s.update_from_camera_attributes({"lightBehavior": "1"})
51
+ assert s.light_behavior == "flash"
52
+ s.update_from_camera_attributes({"lightBehavior": "0"})
53
+ assert s.light_behavior == "constant"
54
+
55
+
56
+ def test_an_unmodelled_behavior_value_is_carried_through_not_dropped():
57
+ """A firmware that grows a third mode must not read as one we know."""
58
+ s = CameraStatusData()
59
+ s.update_from_camera_attributes({"lightBehavior": "7"})
60
+ assert s.light_behavior == "7"
61
+
62
+
63
+ def test_linger_duration_reads_as_seconds():
64
+ s = CameraStatusData()
65
+ s.update_from_camera_attributes({"LingerDuration": "40"})
66
+ assert s.light_linger_duration == 40
67
+
68
+
69
+ def test_trigger_brightness_reads_from_dimming():
70
+ s = CameraStatusData()
71
+ s.update_from_camera_attributes({"Dimming": "80"})
72
+ assert s.light_brightness == 80
73
+
74
+
75
+ def test_dimming_still_does_not_become_the_light_entity_brightness():
76
+ """The camera's Dimming is its floodlight level, and it has its own field.
77
+
78
+ It must not leak into `dimming`, which is the LIGHT platform's brightness
79
+ and is why _LIGHT_ONLY_ATTR_KEYS filters the key in the first place.
80
+ """
81
+ s = CameraStatusData()
82
+ s.update_from_camera_attributes({"Dimming": "80"})
83
+ assert s.dimming is None
84
+
85
+
86
+ def test_a_camera_that_never_reported_them_is_unknown_not_defaulted():
87
+ s = CameraStatusData()
88
+ s.update_from_camera_attributes({"MotionDetection_Enable": "1"})
89
+ assert s.light_behavior is None
90
+ assert s.light_linger_duration is None
91
+ assert s.light_brightness is None
92
+
93
+
94
+ def test_a_partial_push_does_not_clear_what_a_full_poll_established():
95
+ s = CameraStatusData()
96
+ s.update_from_camera_attributes(
97
+ {"lightBehavior": "1", "LingerDuration": "50", "Dimming": "60"})
98
+ s.update_from_camera_attributes({"Occupancy": "1"})
99
+ assert (s.light_behavior, s.light_linger_duration, s.light_brightness) == (
100
+ "flash", 50, 60)
101
+
102
+
103
+ # --- writing -----------------------------------------------------------------
104
+
105
+ def test_setting_the_behavior_sends_the_camera_its_own_number():
106
+ cam = _Cam()
107
+ assert asyncio.run(cam.async_set_light_behavior("flash")) is True
108
+ assert cam.attrs == [("lightBehavior", 1)]
109
+
110
+
111
+ def test_an_unknown_behavior_is_refused_and_nothing_is_sent():
112
+ cam = _Cam()
113
+ with pytest.raises(ValueError):
114
+ asyncio.run(cam.async_set_light_behavior("strobe"))
115
+ assert cam.attrs == []
116
+
117
+
118
+ def test_setting_the_linger_duration_sends_seconds():
119
+ cam = _Cam()
120
+ assert asyncio.run(cam.async_set_light_linger_duration(20)) is True
121
+ assert cam.attrs == [("LingerDuration", 20)]
122
+
123
+
124
+ def test_a_duration_the_camera_does_not_offer_is_refused():
125
+ """The camera enumerates exactly four; 35 would be accepted and ignored."""
126
+ cam = _Cam()
127
+ with pytest.raises(ValueError):
128
+ asyncio.run(cam.async_set_light_linger_duration(35))
129
+ assert cam.attrs == []
130
+
131
+
132
+ def test_trigger_brightness_is_clamped_to_the_range_the_camera_declares():
133
+ """The profile's minimum is 10, not 0 -- 0 is not "off", it is out of range."""
134
+ cam = _Cam()
135
+ asyncio.run(cam.async_set_light_brightness(0))
136
+ asyncio.run(cam.async_set_light_brightness(150))
137
+ asyncio.run(cam.async_set_light_brightness(55))
138
+ assert cam.attrs == [("Dimming", 10), ("Dimming", 100), ("Dimming", 55)]
139
+
140
+
141
+ def test_the_offered_values_match_what_the_camera_profile_declares():
142
+ assert LIGHT_BEHAVIORS == {"constant": 0, "flash": 1}
143
+ assert LIGHT_LINGER_DURATIONS == (20, 30, 40, 50)