matter-python-client 1.4.1a5.dev20260916__tar.gz → 1.4.1a6.dev20260918__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.
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/PKG-INFO +1 -1
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_python_client.egg-info/PKG-INFO +1 -1
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/client/client.py +6 -2
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/pyproject.toml +1 -1
- matter_python_client-1.4.1a6.dev20260918/tests/test_client.py +222 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_client_integration.py +1 -0
- matter_python_client-1.4.1a5.dev20260916/tests/test_client.py +0 -105
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/README.md +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/ChipUtility.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/ClusterObjects.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/Objects.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/Types.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/AccessControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/AccountLogin.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Actions.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ActivatedCarbonFilterMonitoring.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/AdministratorCommissioning.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/AirQuality.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/AmbientContextSensing.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ApplicationBasic.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ApplicationLauncher.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/AudioOutput.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/BasicInformation.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Binding.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/BooleanState.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/BooleanStateConfiguration.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/BridgedDeviceBasicInformation.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CameraAvSettingsUserLevelManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CameraAvStreamManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CarbonDioxideConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CarbonMonoxideConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Channel.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Chime.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ClosureControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ClosureDimension.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ColorControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CommissionerControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CommodityMetering.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CommodityPrice.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/CommodityTariff.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ContentAppObserver.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ContentControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ContentLauncher.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Descriptor.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/DeviceEnergyManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/DeviceEnergyManagementMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/DiagnosticLogs.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/DishwasherAlarm.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/DishwasherMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/DoorLock.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/DraftElectricalMeasurementCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/EcosystemInformation.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ElectricalEnergyMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ElectricalGridConditions.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ElectricalPowerMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/EnergyEvse.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/EnergyEvseMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/EnergyPreference.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/EthernetNetworkDiagnostics.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/EveCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/FanControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/FixedLabel.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/FlowMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/FormaldehydeConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/GeneralCommissioning.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/GeneralDiagnostics.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Globals.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/GroupKeyManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Groupcast.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Groups.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/HeimanCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/HepaFilterMonitoring.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/IcdManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Identify.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/IlluminanceMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/InovelliCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/JointFabricAdministrator.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/JointFabricDatastore.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/KeypadInput.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/LaundryDryerControls.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/LaundryWasherControls.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/LaundryWasherMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/LevelControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/LocalizationConfiguration.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/LowPower.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/MediaInput.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/MediaPlayback.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Messages.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/MeterIdentification.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/MicrowaveOvenControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/MicrowaveOvenMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ModeSelect.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/NeoCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/NetworkCommissioning.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/NitrogenDioxideConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OccupancySensing.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OnOff.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OperationalCredentials.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OperationalState.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OtaSoftwareUpdateProvider.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OtaSoftwareUpdateRequestor.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OvenCavityOperationalState.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OvenMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/OzoneConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Pm10ConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Pm1ConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Pm25ConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/PowerSource.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/PowerSourceConfiguration.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/PowerTopology.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/PressureMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/PumpConfigurationAndControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/PushAvStreamTransport.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/RadonConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/RefrigeratorAlarm.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/RefrigeratorAndTemperatureControlledCabinetMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/RelativeHumidityMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/RvcCleanMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/RvcOperationalState.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/RvcRunMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ScenesManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ServiceArea.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/SmokeCoAlarm.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/SoftwareDiagnostics.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/SoilMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Switch.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TargetNavigator.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TclDehumidifierCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TemperatureAlarm.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TemperatureControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TemperatureMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/Thermostat.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ThermostatUserInterfaceConfiguration.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ThirdRealityMeteringCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ThreadBorderRouterManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ThreadNetworkDiagnostics.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ThreadNetworkDirectory.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TimeFormatLocalization.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TimeSynchronization.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TlsCertificateManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TlsClientManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/TotalVolatileOrganicCompoundsConcentrationMeasurement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/UnitLocalization.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/UserLabel.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ValveConfigurationAndControl.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WagoCluster.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WakeOnLan.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WaterHeaterManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WaterHeaterMode.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WaterTankLevelMonitoring.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WebRtcTransportDefinitions.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WebRtcTransportProvider.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WebRtcTransportRequestor.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WiFiNetworkDiagnostics.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WiFiNetworkManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/WindowCovering.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/ZoneManagement.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/cluster_defs/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/clusters/enum.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/tlv/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/chip/tlv/tlvlist.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_python_client.egg-info/SOURCES.txt +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_python_client.egg-info/dependency_links.txt +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_python_client.egg-info/not-zip-safe +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_python_client.egg-info/requires.txt +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_python_client.egg-info/top_level.txt +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/client/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/client/connection.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/client/exceptions.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/client/models/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/client/models/device_types.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/client/models/node.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/const.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/custom_clusters.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/errors.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/helpers/__init__.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/helpers/api.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/helpers/json.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/helpers/util.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/common/models.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/matter_server/py.typed +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/setup.cfg +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_credentials.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_event_dispatch.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_icd.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_imports.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_integration.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_network_topology.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_ota_upload.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_util.py +0 -0
- {matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/tests/test_webrtc_protocol.py +0 -0
|
@@ -774,8 +774,8 @@ class MatterClient:
|
|
|
774
774
|
message = self._prepare_message(command, require_schema, **kwargs)
|
|
775
775
|
future: asyncio.Future[Any] = self._loop.create_future()
|
|
776
776
|
self._result_futures[message.message_id] = future
|
|
777
|
-
await self.connection.send_message(message)
|
|
778
777
|
try:
|
|
778
|
+
await self.connection.send_message(message)
|
|
779
779
|
return await future
|
|
780
780
|
finally:
|
|
781
781
|
self._result_futures.pop(message.message_id)
|
|
@@ -850,7 +850,11 @@ class MatterClient:
|
|
|
850
850
|
if isinstance(msg, ResultMessageBase):
|
|
851
851
|
future = self._result_futures.get(msg.message_id)
|
|
852
852
|
|
|
853
|
-
if future is None
|
|
853
|
+
if future is None:
|
|
854
|
+
self.logger.debug("No listener for result of message id %s", msg.message_id)
|
|
855
|
+
return
|
|
856
|
+
if future.done():
|
|
857
|
+
self.logger.debug("Result arrived for already settled message id %s", msg.message_id)
|
|
854
858
|
return
|
|
855
859
|
|
|
856
860
|
if isinstance(msg, SuccessResultMessage):
|
{matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/pyproject.toml
RENAMED
|
@@ -25,7 +25,7 @@ license = "Apache-2.0"
|
|
|
25
25
|
name = "matter-python-client"
|
|
26
26
|
readme = "README.md"
|
|
27
27
|
requires-python = ">=3.12"
|
|
28
|
-
version = "1.4.
|
|
28
|
+
version = "1.4.1a6.dev20260918"
|
|
29
29
|
|
|
30
30
|
[project.urls]
|
|
31
31
|
Homepage = "https://github.com/matter-js/matterjs-server"
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""Tests for matter_server.client.client.MatterClient."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
from unittest.mock import AsyncMock, MagicMock
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from chip.clusters import Objects as clusters
|
|
12
|
+
from matter_server.client.client import MatterClient
|
|
13
|
+
from matter_server.client.connection import MatterClientConnection
|
|
14
|
+
from matter_server.common.const import SCHEMA_VERSION
|
|
15
|
+
from matter_server.common.errors import NodeCommissionFailed
|
|
16
|
+
from matter_server.common.models import (
|
|
17
|
+
APICommand,
|
|
18
|
+
CommandMessage,
|
|
19
|
+
ErrorResultMessage,
|
|
20
|
+
MessageType,
|
|
21
|
+
ServerInfoMessage,
|
|
22
|
+
SuccessResultMessage,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from collections.abc import Awaitable, Callable
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _make_client() -> MatterClient:
|
|
30
|
+
return MatterClient(ws_server_url="ws://example.invalid/ws", aiohttp_session=MagicMock())
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.mark.parametrize(
|
|
34
|
+
"message",
|
|
35
|
+
[
|
|
36
|
+
SuccessResultMessage(message_id="late-result", result={"ok": True}),
|
|
37
|
+
ErrorResultMessage(message_id="late-result", error_code=1, details="late error"),
|
|
38
|
+
],
|
|
39
|
+
ids=["success", "error"],
|
|
40
|
+
)
|
|
41
|
+
@pytest.mark.parametrize("done_state", ["cancelled", "resolved"])
|
|
42
|
+
async def test_handle_incoming_message_ignores_result_for_done_future(
|
|
43
|
+
message: SuccessResultMessage | ErrorResultMessage, done_state: str
|
|
44
|
+
) -> None:
|
|
45
|
+
client = _make_client()
|
|
46
|
+
future = asyncio.get_running_loop().create_future()
|
|
47
|
+
client._result_futures[message.message_id] = future
|
|
48
|
+
|
|
49
|
+
if done_state == "cancelled":
|
|
50
|
+
future.cancel()
|
|
51
|
+
else:
|
|
52
|
+
future.set_result("existing result")
|
|
53
|
+
|
|
54
|
+
client._handle_incoming_message(message)
|
|
55
|
+
|
|
56
|
+
if done_state == "cancelled":
|
|
57
|
+
assert future.cancelled()
|
|
58
|
+
else:
|
|
59
|
+
assert future.result() == "existing result"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async def test_handle_incoming_message_resolves_pending_success() -> None:
|
|
63
|
+
client = _make_client()
|
|
64
|
+
future = asyncio.get_running_loop().create_future()
|
|
65
|
+
client._result_futures["pending-success"] = future
|
|
66
|
+
|
|
67
|
+
client._handle_incoming_message(SuccessResultMessage(message_id="pending-success", result={"ok": True}))
|
|
68
|
+
|
|
69
|
+
assert future.result() == {"ok": True}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
async def test_handle_incoming_message_rejects_pending_error() -> None:
|
|
73
|
+
client = _make_client()
|
|
74
|
+
future = asyncio.get_running_loop().create_future()
|
|
75
|
+
client._result_futures["pending-error"] = future
|
|
76
|
+
|
|
77
|
+
client._handle_incoming_message(
|
|
78
|
+
ErrorResultMessage(message_id="pending-error", error_code=1, details="expected error")
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
error = future.exception()
|
|
82
|
+
assert type(error) is NodeCommissionFailed
|
|
83
|
+
assert str(error) == "expected error"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def test_write_attribute_sends_tag_keyed_value() -> None:
|
|
87
|
+
"""write_attribute must route struct values through dataclass_to_tag_dict.
|
|
88
|
+
|
|
89
|
+
send_command must receive TLV-tag keys ("0".."5"), not field names, or the
|
|
90
|
+
server rejects the write with INVALID_DATA_TYPE.
|
|
91
|
+
"""
|
|
92
|
+
client = MatterClient(ws_server_url="ws://example.invalid/ws", aiohttp_session=MagicMock())
|
|
93
|
+
client.send_command = AsyncMock(return_value=None)
|
|
94
|
+
|
|
95
|
+
preset = clusters.Thermostat.Structs.PresetStruct(
|
|
96
|
+
presetHandle=b"\x01",
|
|
97
|
+
presetScenario=clusters.Thermostat.Enums.PresetScenarioEnum.kOccupied,
|
|
98
|
+
name=None,
|
|
99
|
+
coolingSetpoint=2500,
|
|
100
|
+
heatingSetpoint=2100,
|
|
101
|
+
builtIn=True,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
await client.write_attribute(node_id=1, attribute_path="1/513/80", value=preset)
|
|
105
|
+
|
|
106
|
+
client.send_command.assert_awaited_once_with(
|
|
107
|
+
APICommand.WRITE_ATTRIBUTE,
|
|
108
|
+
require_schema=4,
|
|
109
|
+
node_id=1,
|
|
110
|
+
attribute_path="1/513/80",
|
|
111
|
+
value={
|
|
112
|
+
"0": b"\x01",
|
|
113
|
+
"1": clusters.Thermostat.Enums.PresetScenarioEnum.kOccupied,
|
|
114
|
+
"3": 2500,
|
|
115
|
+
"4": 2100,
|
|
116
|
+
"5": True,
|
|
117
|
+
},
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async def test_handle_incoming_message_ignores_result_without_listener() -> None:
|
|
122
|
+
client = _make_client()
|
|
123
|
+
unrelated = asyncio.get_running_loop().create_future()
|
|
124
|
+
client._result_futures["other"] = unrelated
|
|
125
|
+
|
|
126
|
+
client._handle_incoming_message(SuccessResultMessage(message_id="unknown", result={"ok": True}))
|
|
127
|
+
|
|
128
|
+
assert client._result_futures == {"other": unrelated}
|
|
129
|
+
assert not unrelated.done()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
_FAKE_SERVER_SCHEMA_VERSION = 13
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class _FakeConnection(MatterClientConnection):
|
|
136
|
+
"""Connection stub driving the client read loop from an in-memory queue."""
|
|
137
|
+
|
|
138
|
+
def __init__(self, send_error: Exception | None = None) -> None:
|
|
139
|
+
super().__init__(ws_server_url="ws://example.invalid/ws", aiohttp_session=MagicMock())
|
|
140
|
+
self.sent = list[CommandMessage]()
|
|
141
|
+
self.send_error = send_error
|
|
142
|
+
self.is_connected = False
|
|
143
|
+
self.on_receive: Callable[[], Awaitable[None]] | None = None
|
|
144
|
+
self.message_sent = asyncio.Event()
|
|
145
|
+
self._incoming = asyncio.Queue[MessageType]()
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def connected(self) -> bool:
|
|
149
|
+
return self.is_connected
|
|
150
|
+
|
|
151
|
+
async def connect(self) -> None:
|
|
152
|
+
self.is_connected = True
|
|
153
|
+
self.server_info = ServerInfoMessage(
|
|
154
|
+
fabric_id=1,
|
|
155
|
+
compressed_fabric_id=1,
|
|
156
|
+
schema_version=_FAKE_SERVER_SCHEMA_VERSION,
|
|
157
|
+
min_supported_schema_version=SCHEMA_VERSION,
|
|
158
|
+
sdk_version="test",
|
|
159
|
+
wifi_credentials_set=False,
|
|
160
|
+
thread_credentials_set=False,
|
|
161
|
+
bluetooth_enabled=False,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
async def disconnect(self) -> None:
|
|
165
|
+
self.is_connected = False
|
|
166
|
+
|
|
167
|
+
async def send_message(self, message: CommandMessage) -> None:
|
|
168
|
+
if self.send_error is not None:
|
|
169
|
+
raise self.send_error
|
|
170
|
+
self.sent.append(message)
|
|
171
|
+
self.message_sent.set()
|
|
172
|
+
|
|
173
|
+
async def receive_message_or_raise(self) -> MessageType:
|
|
174
|
+
message = await self._incoming.get()
|
|
175
|
+
if self.on_receive is not None:
|
|
176
|
+
await self.on_receive()
|
|
177
|
+
return message
|
|
178
|
+
|
|
179
|
+
def deliver(self, message: MessageType) -> None:
|
|
180
|
+
self._incoming.put_nowait(message)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
async def test_send_command_forgets_the_future_when_the_send_fails() -> None:
|
|
184
|
+
client = _make_client()
|
|
185
|
+
connection = _FakeConnection(send_error=ConnectionResetError("Cannot write to closing transport"))
|
|
186
|
+
connection.is_connected = True
|
|
187
|
+
client.connection = connection
|
|
188
|
+
client._loop = asyncio.get_running_loop()
|
|
189
|
+
|
|
190
|
+
with pytest.raises(ConnectionResetError):
|
|
191
|
+
await client.send_command(APICommand.SERVER_DIAGNOSTICS)
|
|
192
|
+
|
|
193
|
+
assert client._result_futures == {}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
async def test_late_result_after_disconnect_keeps_the_read_loop_alive(
|
|
197
|
+
caplog: pytest.LogCaptureFixture,
|
|
198
|
+
) -> None:
|
|
199
|
+
caplog.set_level("DEBUG", logger="matter_server.client")
|
|
200
|
+
client = _make_client()
|
|
201
|
+
connection = _FakeConnection()
|
|
202
|
+
client.connection = connection
|
|
203
|
+
|
|
204
|
+
init_ready = asyncio.Event()
|
|
205
|
+
listen_task = asyncio.create_task(client.start_listening(init_ready))
|
|
206
|
+
connection.deliver(SuccessResultMessage(message_id="start-listening", result=[]))
|
|
207
|
+
await asyncio.wait_for(init_ready.wait(), timeout=1)
|
|
208
|
+
|
|
209
|
+
connection.message_sent.clear()
|
|
210
|
+
command_task = asyncio.create_task(client.send_command(APICommand.SERVER_DIAGNOSTICS))
|
|
211
|
+
await asyncio.wait_for(connection.message_sent.wait(), timeout=1)
|
|
212
|
+
message_id = next(iter(client._result_futures))
|
|
213
|
+
|
|
214
|
+
# disconnect must land between the wire read and the handler, or the race cannot occur
|
|
215
|
+
connection.on_receive = client.disconnect
|
|
216
|
+
connection.deliver(SuccessResultMessage(message_id=message_id, result={"late": True}))
|
|
217
|
+
|
|
218
|
+
await asyncio.wait_for(listen_task, timeout=1)
|
|
219
|
+
with pytest.raises(asyncio.CancelledError):
|
|
220
|
+
await command_task
|
|
221
|
+
assert client._result_futures == {}
|
|
222
|
+
assert f"Result arrived for already settled message id {message_id}" in caplog.text
|
|
@@ -75,6 +75,7 @@ async def test_send_command_and_receive_response(mock_server, client_session):
|
|
|
75
75
|
|
|
76
76
|
result = await client.send_command("diagnostics")
|
|
77
77
|
assert result == {"info": "test"}
|
|
78
|
+
assert client._result_futures == {}
|
|
78
79
|
|
|
79
80
|
await client.disconnect()
|
|
80
81
|
listen_task.cancel()
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"""Tests for matter_server.client.client.MatterClient."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import asyncio
|
|
6
|
-
from unittest.mock import AsyncMock, MagicMock
|
|
7
|
-
|
|
8
|
-
import pytest
|
|
9
|
-
|
|
10
|
-
from chip.clusters import Objects as clusters
|
|
11
|
-
from matter_server.client.client import MatterClient
|
|
12
|
-
from matter_server.common.errors import MatterError
|
|
13
|
-
from matter_server.common.models import APICommand, ErrorResultMessage, SuccessResultMessage
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def _make_client() -> MatterClient:
|
|
17
|
-
return MatterClient(ws_server_url="ws://example.invalid/ws", aiohttp_session=MagicMock())
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@pytest.mark.parametrize(
|
|
21
|
-
"message",
|
|
22
|
-
[
|
|
23
|
-
SuccessResultMessage(message_id="late-result", result={"ok": True}),
|
|
24
|
-
ErrorResultMessage(message_id="late-result", error_code=1, details="late error"),
|
|
25
|
-
],
|
|
26
|
-
ids=["success", "error"],
|
|
27
|
-
)
|
|
28
|
-
@pytest.mark.parametrize("done_state", ["cancelled", "resolved"])
|
|
29
|
-
async def test_handle_incoming_message_ignores_result_for_done_future(
|
|
30
|
-
message: SuccessResultMessage | ErrorResultMessage, done_state: str
|
|
31
|
-
) -> None:
|
|
32
|
-
client = _make_client()
|
|
33
|
-
future = asyncio.get_running_loop().create_future()
|
|
34
|
-
client._result_futures[message.message_id] = future
|
|
35
|
-
|
|
36
|
-
if done_state == "cancelled":
|
|
37
|
-
future.cancel()
|
|
38
|
-
else:
|
|
39
|
-
future.set_result("existing result")
|
|
40
|
-
|
|
41
|
-
client._handle_incoming_message(message)
|
|
42
|
-
|
|
43
|
-
if done_state == "cancelled":
|
|
44
|
-
assert future.cancelled()
|
|
45
|
-
else:
|
|
46
|
-
assert future.result() == "existing result"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
async def test_handle_incoming_message_resolves_pending_success() -> None:
|
|
50
|
-
client = _make_client()
|
|
51
|
-
future = asyncio.get_running_loop().create_future()
|
|
52
|
-
client._result_futures["pending-success"] = future
|
|
53
|
-
|
|
54
|
-
client._handle_incoming_message(SuccessResultMessage(message_id="pending-success", result={"ok": True}))
|
|
55
|
-
|
|
56
|
-
assert future.result() == {"ok": True}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
async def test_handle_incoming_message_rejects_pending_error() -> None:
|
|
60
|
-
client = _make_client()
|
|
61
|
-
future = asyncio.get_running_loop().create_future()
|
|
62
|
-
client._result_futures["pending-error"] = future
|
|
63
|
-
|
|
64
|
-
client._handle_incoming_message(
|
|
65
|
-
ErrorResultMessage(message_id="pending-error", error_code=1, details="expected error")
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
error = future.exception()
|
|
69
|
-
assert isinstance(error, MatterError)
|
|
70
|
-
assert str(error) == "expected error"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
async def test_write_attribute_sends_tag_keyed_value() -> None:
|
|
74
|
-
"""write_attribute must route struct values through dataclass_to_tag_dict.
|
|
75
|
-
|
|
76
|
-
send_command must receive TLV-tag keys ("0".."5"), not field names, or the
|
|
77
|
-
server rejects the write with INVALID_DATA_TYPE.
|
|
78
|
-
"""
|
|
79
|
-
client = MatterClient(ws_server_url="ws://example.invalid/ws", aiohttp_session=MagicMock())
|
|
80
|
-
client.send_command = AsyncMock(return_value=None)
|
|
81
|
-
|
|
82
|
-
preset = clusters.Thermostat.Structs.PresetStruct(
|
|
83
|
-
presetHandle=b"\x01",
|
|
84
|
-
presetScenario=clusters.Thermostat.Enums.PresetScenarioEnum.kOccupied,
|
|
85
|
-
name=None,
|
|
86
|
-
coolingSetpoint=2500,
|
|
87
|
-
heatingSetpoint=2100,
|
|
88
|
-
builtIn=True,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
await client.write_attribute(node_id=1, attribute_path="1/513/80", value=preset)
|
|
92
|
-
|
|
93
|
-
client.send_command.assert_awaited_once_with(
|
|
94
|
-
APICommand.WRITE_ATTRIBUTE,
|
|
95
|
-
require_schema=4,
|
|
96
|
-
node_id=1,
|
|
97
|
-
attribute_path="1/513/80",
|
|
98
|
-
value={
|
|
99
|
-
"0": b"\x01",
|
|
100
|
-
"1": clusters.Thermostat.Enums.PresetScenarioEnum.kOccupied,
|
|
101
|
-
"3": 2500,
|
|
102
|
-
"4": 2100,
|
|
103
|
-
"5": True,
|
|
104
|
-
},
|
|
105
|
-
)
|
{matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/README.md
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{matter_python_client-1.4.1a5.dev20260916 → matter_python_client-1.4.1a6.dev20260918}/setup.cfg
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
|