python-aidot-cameras 0.13.1__tar.gz → 0.13.2__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.
- {python_aidot_cameras-0.13.1/python_aidot_cameras.egg-info → python_aidot_cameras-0.13.2}/PKG-INFO +1 -1
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/client.py +21 -9
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/pyproject.toml +1 -1
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2/python_aidot_cameras.egg-info}/PKG-INFO +1 -1
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/python_aidot_cameras.egg-info/SOURCES.txt +1 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_battery_detection.py +30 -3
- python_aidot_cameras-0.13.2/tests/test_battery_evidence_corroboration.py +139 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_live_validate_policy.py +55 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/LICENSE +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/MANIFEST.in +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/README.md +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/__init__.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/__main__.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_upstream.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/__init__.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/__init__.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/clock.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/codecs/__init__.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/codecs/base.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/codecs/g711.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/codecs/g722.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/codecs/h264.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/codecs/opus.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/codecs/vpx.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/contrib/__init__.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/contrib/media.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/contrib/signaling.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/events.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/exceptions.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/jitterbuffer.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/mediastreams.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rate.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcconfiguration.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcdatachannel.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcdtlstransport.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcicetransport.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcpeerconnection.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcrtpparameters.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcrtpreceiver.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcrtpsender.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcrtptransceiver.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcsctptransport.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtcsessiondescription.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtp.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/sdp.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/stats.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/utils.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/__init__.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/constants.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/controls.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/go2rtc.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/lan_control.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/models.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/playback.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/protocol.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/sdes.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/sdes_open.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/tutk.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/webrtc.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/webrtc_open.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/client.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/const.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/credentials.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/crypto.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/device_client.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/discover.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/exceptions.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/g711.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/py.typed +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/python_aidot_cameras.egg-info/dependency_links.txt +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/python_aidot_cameras.egg-info/entry_points.txt +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/python_aidot_cameras.egg-info/requires.txt +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/python_aidot_cameras.egg-info/top_level.txt +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/setup.cfg +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_aioice_compat.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_alarm_event.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_backoff.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_battery_skip_turn.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_constants_imports_resolve.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_deferred_hardening.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_device_login_guard.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_device_user_info_cache.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dormant_camera_cleanup.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_mux_terminal_write.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_not_ready_burst.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_pinning.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_serve_decode_skip.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_serve_open_timeout.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_skip_signaling_wait.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_slow_probe.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_egress_guard.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_go2rtc.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_go2rtc_cli.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_h264_decode_rate_limit.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_highport_nomination.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_ice_config_cache.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_ice_peer_reflexive.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_idle_release_both_loops.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_keepalive_renew.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_key_restart_sdp.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_keyframe_prompter.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_lan_control.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_light_active_color_mode.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_live_stream_param.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_logging_caps.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_motion_poll.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_mqtt_credential_refetch.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_mqtt_credential_self_heal.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_mqtt_password_not_persisted.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_mqtt_session_reconnect.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_narrow_pc_ice.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_no_self_referential_go2rtc.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_no_undefined_names.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_offline_keepalive_pause.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_open_fail_logger.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_open_gate_delay.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_peerid_reuse.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_persistent_mqtt.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_persistent_mqtt_robustness.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_playback_tls.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_post_merge_hardening.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_retry_policy.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_adaptive.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_bridge_break_gate.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_echo_wait_timeout.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_fast_liveplay.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_ffmpeg_stderr_log.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_idle_release.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_open_cleanup.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_serve_audio.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_serve_cmd.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_sprop.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_talk.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_teardown_exit_log.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_terminal_ack.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_watchdog.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdp_payload_type_narrowing.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_security_hardening.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_serializable_login_info.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_serve_relay.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_session_stats.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_shared_house_seam.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_speak.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_stream_cap.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_stream_drain_ownership.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_stream_idle.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_stream_slot_cap.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_stream_teardown.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_talk.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_terminal_ack.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_token_file_robustness.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_token_refresh.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_turn_create_permission.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_upstream_compat.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_viewer_check_throttle.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_viewer_presence.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_viewer_present_push_mode.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_wait_or_event.py +0 -0
- {python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_wake_readiness_retry.py +0 -0
{python_aidot_cameras-0.13.1/python_aidot_cameras.egg-info → python_aidot_cameras-0.13.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-aidot-cameras
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
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
|
|
@@ -960,15 +960,27 @@ class CameraMixin(_CameraControlsMixin, _WebRTCOpenMixin, _SdesOpenMixin):
|
|
|
960
960
|
for _key in ("Battery_remaining", "batteryRemaining", "batteryLevel"):
|
|
961
961
|
if _as_int(_props.get(_key)) is not None:
|
|
962
962
|
return True
|
|
963
|
-
# The low-power flag
|
|
964
|
-
#
|
|
965
|
-
#
|
|
966
|
-
#
|
|
967
|
-
#
|
|
968
|
-
#
|
|
969
|
-
#
|
|
970
|
-
#
|
|
971
|
-
|
|
963
|
+
# The low-power flag, but ONLY when corroborated. ``batteryMode=2`` on
|
|
964
|
+
# its own is not evidence: measured against the live cloud payload, every
|
|
965
|
+
# MAINS A000088 on this fleet reports ``batteryMode: '2'`` and nothing
|
|
966
|
+
# else battery-related, while a real battery model reports it alongside
|
|
967
|
+
# actual telemetry (``Battery_remaining``, ``lowPowerStatus``,
|
|
968
|
+
# ``charging``). Trusting it alone classified four mains cameras as
|
|
969
|
+
# battery, which put powerType=2 on their wire payload and gave them the
|
|
970
|
+
# battery idle window instead of the mains warm-hold.
|
|
971
|
+
#
|
|
972
|
+
# This is the same trap the paragraph below describes for ``powerType`` /
|
|
973
|
+
# ``p2pCache`` - a field that reads 2 on every camera - so it gets the
|
|
974
|
+
# same treatment rather than being taken at face value. Corroboration is
|
|
975
|
+
# kept (instead of dropping the flag) so a future battery model that
|
|
976
|
+
# names its level differently is still caught by the flag plus any one
|
|
977
|
+
# battery-only field.
|
|
978
|
+
_BATTERY_TELEMETRY = (
|
|
979
|
+
"Battery_remaining", "batteryRemaining", "batteryLevel",
|
|
980
|
+
"lowPowerStatus", "charging",
|
|
981
|
+
)
|
|
982
|
+
if (_as_int(_props.get("batteryMode")) == 2
|
|
983
|
+
and any(_props.get(k) is not None for k in _BATTERY_TELEMETRY)):
|
|
972
984
|
return True
|
|
973
985
|
# Already-parsed status, for a camera refreshed from an attribute push
|
|
974
986
|
# rather than from a device-list dict.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-aidot-cameras"
|
|
7
|
-
version = "0.13.
|
|
7
|
+
version = "0.13.2"
|
|
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"
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2/python_aidot_cameras.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-aidot-cameras
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
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
|
|
@@ -71,6 +71,7 @@ tests/test_aioice_compat.py
|
|
|
71
71
|
tests/test_alarm_event.py
|
|
72
72
|
tests/test_backoff.py
|
|
73
73
|
tests/test_battery_detection.py
|
|
74
|
+
tests/test_battery_evidence_corroboration.py
|
|
74
75
|
tests/test_battery_skip_turn.py
|
|
75
76
|
tests/test_constants_imports_resolve.py
|
|
76
77
|
tests/test_deferred_hardening.py
|
|
@@ -91,9 +91,36 @@ def test_numeric_string_battery_level_counts():
|
|
|
91
91
|
assert _cam("LK.IPC.A009999", props={"Battery_remaining": "38"}).is_battery_camera
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
def
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
def test_battery_mode_two_alone_is_not_evidence():
|
|
95
|
+
"""REVISED 2026-08-02 against the live cloud payload.
|
|
96
|
+
|
|
97
|
+
This test used to assert that ``batteryMode=2`` alone proves a battery, on
|
|
98
|
+
the reasonable reading of the field's name. The account's actual device list
|
|
99
|
+
disproves it: every MAINS A000088 reports ``batteryMode: '2'`` and no other
|
|
100
|
+
battery field, while real battery models report it alongside real telemetry
|
|
101
|
+
(``Battery_remaining``, ``lowPowerStatus``, ``charging``).
|
|
102
|
+
|
|
103
|
+
Trusting it alone classified four mains cameras as battery, which put
|
|
104
|
+
powerType=2 on their wire payload and gave them the battery idle window
|
|
105
|
+
instead of the mains warm-hold - the same trap
|
|
106
|
+
``test_power_type_property_is_deliberately_not_evidence`` guards for
|
|
107
|
+
``powerType``/``p2pCache``, which also read 2 on every camera.
|
|
108
|
+
"""
|
|
109
|
+
for value in (2, "2"):
|
|
110
|
+
assert _cam("LK.IPC.A009999",
|
|
111
|
+
props={"batteryMode": value}).is_battery_camera is False
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_battery_mode_two_counts_when_corroborated():
|
|
115
|
+
"""The flag is still a signal - it just needs one real battery field.
|
|
116
|
+
|
|
117
|
+
Kept (rather than dropping the flag) so a battery model whose level field we
|
|
118
|
+
have not seen is still caught, provided it reports any battery-only field.
|
|
119
|
+
"""
|
|
120
|
+
for extra in ({"charging": "0"}, {"lowPowerStatus": "0"},
|
|
121
|
+
{"Battery_remaining": "100"}):
|
|
122
|
+
assert _cam("LK.IPC.A009999",
|
|
123
|
+
props={"batteryMode": "2", **extra}).is_battery_camera is True
|
|
97
124
|
|
|
98
125
|
|
|
99
126
|
def test_battery_mode_one_is_not_evidence():
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""``batteryMode=2`` alone must not make a mains camera look like a battery one.
|
|
2
|
+
|
|
3
|
+
Every property payload below is the REAL one from the live cloud account
|
|
4
|
+
(2026-08-02), not a construction. That matters: the bug was believing a field
|
|
5
|
+
meant what its name suggests, and only the actual payload disproves it.
|
|
6
|
+
|
|
7
|
+
A001513 (real battery): batteryMode=2, Battery_remaining, lowPowerStatus, charging
|
|
8
|
+
A000088 (MAINS): batteryMode=2 <- and nothing else
|
|
9
|
+
A001064 (mains PTZ): {}
|
|
10
|
+
|
|
11
|
+
Misclassification is costly in BOTH directions, which is why the corroboration
|
|
12
|
+
rule is "flag AND telemetry" rather than dropping the flag or trusting it:
|
|
13
|
+
|
|
14
|
+
* battery read as mains loses the SDES TURN pre-allocation (a cloud-woken
|
|
15
|
+
battery camera has no LAN host candidate, so the relay is its ONLY return
|
|
16
|
+
path), the keep-alive renew and the HTTP wake;
|
|
17
|
+
* mains read as battery puts powerType=2 on its wire payload and hands it the
|
|
18
|
+
battery idle window instead of the mains warm-hold - which is what shipped.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import types
|
|
22
|
+
|
|
23
|
+
import pytest
|
|
24
|
+
|
|
25
|
+
from aidot_cameras.camera.client import CameraMixin
|
|
26
|
+
|
|
27
|
+
# --- real payloads, verbatim from the cloud device list --------------------- #
|
|
28
|
+
L2_BATTERY = {"batteryMode": "2", "lowPowerStatus": "0",
|
|
29
|
+
"Battery_remaining": "100", "charging": "0"}
|
|
30
|
+
M3_PRO_MAINS = {"batteryMode": "2"}
|
|
31
|
+
PTZ_MAINS: dict = {}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class _Cam:
|
|
35
|
+
"""The real classification code on a minimal object.
|
|
36
|
+
|
|
37
|
+
The methods and properties are taken straight off CameraMixin rather than
|
|
38
|
+
reimplemented, so these tests exercise shipping logic; only the three
|
|
39
|
+
attributes it reads are stubbed.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
_BATTERY_MODELS = CameraMixin._BATTERY_MODELS
|
|
43
|
+
_battery_evidence = CameraMixin._battery_evidence
|
|
44
|
+
is_battery_camera = CameraMixin.is_battery_camera
|
|
45
|
+
live_power_type = CameraMixin.live_power_type
|
|
46
|
+
|
|
47
|
+
def __init__(self, props, model="LK.IPC.A000088"):
|
|
48
|
+
self._raw_device = {"properties": props}
|
|
49
|
+
self.info = types.SimpleNamespace(model_id=model)
|
|
50
|
+
self.status = None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _cam(props, model="LK.IPC.A000088"):
|
|
54
|
+
return _Cam(props, model)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# --------------------------------------------------------------------------- #
|
|
58
|
+
# the regression
|
|
59
|
+
# --------------------------------------------------------------------------- #
|
|
60
|
+
|
|
61
|
+
@pytest.mark.parametrize("name", ["M3 Pro_180", "Family Room Cam",
|
|
62
|
+
"Bedroom M3 Pro", "Deck"])
|
|
63
|
+
def test_mains_a000088_reporting_batterymode_is_not_a_battery_camera(name):
|
|
64
|
+
"""The shipped bug: four mains cameras classified as battery.
|
|
65
|
+
|
|
66
|
+
They report `batteryMode: '2'` and no other battery field. Trusting the flag
|
|
67
|
+
alone gave them powerType=2 and the battery idle window.
|
|
68
|
+
"""
|
|
69
|
+
cam = _cam(M3_PRO_MAINS, model="LK.IPC.A000088")
|
|
70
|
+
assert cam._battery_evidence() is None, name
|
|
71
|
+
assert cam.is_battery_camera is False, name
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_mains_ptz_with_no_battery_fields_stays_mains():
|
|
75
|
+
cam = _cam(PTZ_MAINS, model="LK.IPC.A001064")
|
|
76
|
+
assert cam.is_battery_camera is False
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# --------------------------------------------------------------------------- #
|
|
80
|
+
# the thing that must NOT regress
|
|
81
|
+
# --------------------------------------------------------------------------- #
|
|
82
|
+
|
|
83
|
+
def test_a_real_battery_camera_is_still_detected():
|
|
84
|
+
"""A001513 must stay battery - losing this costs it the TURN pre-alloc."""
|
|
85
|
+
cam = _cam(L2_BATTERY, model="LK.IPC.A001513")
|
|
86
|
+
assert cam._battery_evidence() is True
|
|
87
|
+
assert cam.is_battery_camera is True
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_battery_detection_does_not_lean_on_the_model_list_alone():
|
|
91
|
+
"""Evidence must carry it, so an unlisted battery revision still works."""
|
|
92
|
+
cam = _cam(L2_BATTERY, model="LK.IPC.A999999-2")
|
|
93
|
+
assert cam.is_battery_camera is True
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_a_listed_model_with_no_properties_is_still_battery():
|
|
97
|
+
"""The model list is the backstop when the payload carries nothing."""
|
|
98
|
+
cam = _cam({}, model="LK.IPC.A001513")
|
|
99
|
+
assert cam._battery_evidence() is None
|
|
100
|
+
assert cam.is_battery_camera is True
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# --------------------------------------------------------------------------- #
|
|
104
|
+
# the corroboration rule itself
|
|
105
|
+
# --------------------------------------------------------------------------- #
|
|
106
|
+
|
|
107
|
+
@pytest.mark.parametrize("corroborating", [
|
|
108
|
+
{"Battery_remaining": "55"},
|
|
109
|
+
{"batteryRemaining": "55"},
|
|
110
|
+
{"batteryLevel": "55"},
|
|
111
|
+
{"lowPowerStatus": "0"},
|
|
112
|
+
{"charging": "1"},
|
|
113
|
+
])
|
|
114
|
+
def test_batterymode_counts_when_any_battery_field_corroborates(corroborating):
|
|
115
|
+
"""The flag is kept as a signal, not discarded - it just needs backing.
|
|
116
|
+
|
|
117
|
+
This is what catches a future battery model whose level field we have not
|
|
118
|
+
seen, provided it reports any battery-only field at all.
|
|
119
|
+
"""
|
|
120
|
+
cam = _cam({"batteryMode": "2", **corroborating}, model="LK.IPC.A000088")
|
|
121
|
+
assert cam._battery_evidence() is True
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_a_zero_valued_battery_field_still_corroborates():
|
|
125
|
+
"""`charging: '0'` is a report, not an absence - presence is the signal."""
|
|
126
|
+
cam = _cam({"batteryMode": "2", "charging": "0"}, model="LK.IPC.A000088")
|
|
127
|
+
assert cam._battery_evidence() is True
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_evidence_never_returns_false_so_it_cannot_demote_a_known_model():
|
|
131
|
+
"""It may only ADD to the battery set, never remove - preserved property."""
|
|
132
|
+
for props in (M3_PRO_MAINS, PTZ_MAINS, {"batteryMode": "1"}):
|
|
133
|
+
assert _cam(props)._battery_evidence() in (True, None)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def test_power_type_follows_the_classification():
|
|
137
|
+
"""powerType on the wire must never disagree with the battery guards."""
|
|
138
|
+
assert _cam(M3_PRO_MAINS, model="LK.IPC.A000088").live_power_type == 1
|
|
139
|
+
assert _cam(L2_BATTERY, model="LK.IPC.A001513").live_power_type == 2
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_live_validate_policy.py
RENAMED
|
@@ -279,3 +279,58 @@ def test_media_seen_accepts_dtls_frames(lv):
|
|
|
279
279
|
ok, evidence = lv._media_seen(object(), frames=42, out_path=None)
|
|
280
280
|
assert ok
|
|
281
281
|
assert evidence["frames"] == 42
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
# --------------------------------------------------------------------------- #
|
|
285
|
+
# absent-camera early exit
|
|
286
|
+
# --------------------------------------------------------------------------- #
|
|
287
|
+
|
|
288
|
+
def test_slotless_budget_is_smaller_than_the_dtls_budget(lv):
|
|
289
|
+
"""The early exit must actually save attempts, or it is decoration."""
|
|
290
|
+
assert lv.SLOTLESS_MAX_ATTEMPTS < lv.ATTEMPTS_DTLS
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def test_one_retry_is_still_allowed_for_a_single_missed_response(lv):
|
|
294
|
+
"""A camera silent ONCE may just have missed a webrtcResp on a busy account.
|
|
295
|
+
|
|
296
|
+
Dropping to a single attempt would turn one unlucky timeout into a failed
|
|
297
|
+
release, so the budget must be >1.
|
|
298
|
+
"""
|
|
299
|
+
assert lv.SLOTLESS_MAX_ATTEMPTS > 1
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def test_only_the_no_session_verdict_is_treated_as_absent(lv):
|
|
303
|
+
"""ERROR alone means no session was opened, so nothing was probabilistic.
|
|
304
|
+
|
|
305
|
+
NO_MEDIA and BUSY DID reach the camera - those are exactly the flaky cases
|
|
306
|
+
the retry budget exists for, and they must keep their full allowance.
|
|
307
|
+
"""
|
|
308
|
+
assert lv._SLOTLESS_VERDICTS == frozenset({"ERROR"})
|
|
309
|
+
for reached_the_camera in ("PASS", "NO_MEDIA", "BUSY"):
|
|
310
|
+
assert reached_the_camera not in lv._SLOTLESS_VERDICTS
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def test_a_camera_that_reached_us_once_keeps_its_full_budget(lv):
|
|
314
|
+
"""The early exit requires EVERY attempt to be slotless.
|
|
315
|
+
|
|
316
|
+
A camera that returns NO_MEDIA then ERROR is flaky, not absent, and must not
|
|
317
|
+
be cut short - which is why the loop checks all() rather than the last one.
|
|
318
|
+
"""
|
|
319
|
+
mixed = [{"verdict": "NO_MEDIA"}, {"verdict": "ERROR"}]
|
|
320
|
+
assert not all(a["verdict"] in lv._SLOTLESS_VERDICTS for a in mixed)
|
|
321
|
+
|
|
322
|
+
absent = [{"verdict": "ERROR"}, {"verdict": "ERROR"}]
|
|
323
|
+
assert all(a["verdict"] in lv._SLOTLESS_VERDICTS for a in absent)
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def test_an_absent_camera_still_reaches_a_failing_verdict(lv, tmp_path):
|
|
327
|
+
"""Skipping attempts must not soften the verdict - absent is still ERROR.
|
|
328
|
+
|
|
329
|
+
The saving is wall clock, not leniency: a required model with no working
|
|
330
|
+
camera must still fail the release.
|
|
331
|
+
"""
|
|
332
|
+
report = {"cameras": [_cam(lv, "LK.IPC.A000088", "ERROR", name="Deck")]}
|
|
333
|
+
report["cameras"][0]["attempts_used"] = lv.SLOTLESS_MAX_ATTEMPTS
|
|
334
|
+
assert lv._summarize(report, _args(tmp_path)) == 1
|
|
335
|
+
assert report["verdict"] == "FAIL"
|
|
336
|
+
assert report["required_failed"] == ["Deck"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/__init__.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/__init__.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/clock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/events.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/rtp.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/sdp.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/stats.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/_vendor/aiortc/utils.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/__init__.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/constants.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/controls.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/lan_control.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/playback.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/sdes_open.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/aidot_cameras/camera/webrtc_open.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_constants_imports_resolve.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_deferred_hardening.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_device_login_guard.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_device_user_info_cache.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dormant_camera_cleanup.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_mux_terminal_write.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_not_ready_burst.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_serve_decode_skip.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_serve_open_timeout.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_dtls_skip_signaling_wait.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_h264_decode_rate_limit.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_highport_nomination.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_ice_peer_reflexive.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_idle_release_both_loops.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_light_active_color_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_mqtt_credential_refetch.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_mqtt_credential_self_heal.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_mqtt_session_reconnect.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_no_self_referential_go2rtc.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_no_undefined_names.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_offline_keepalive_pause.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_persistent_mqtt_robustness.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_post_merge_hardening.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_bridge_break_gate.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_echo_wait_timeout.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_fast_liveplay.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_ffmpeg_stderr_log.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdes_teardown_exit_log.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_sdp_payload_type_narrowing.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_security_hardening.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_serializable_login_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_stream_drain_ownership.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_token_file_robustness.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_turn_create_permission.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_viewer_check_throttle.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_viewer_present_push_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.13.1 → python_aidot_cameras-0.13.2}/tests/test_wake_readiness_retry.py
RENAMED
|
File without changes
|