From 07882f8c9bb4cbd2cfdd909d2f875f6177164aea Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 16:47:43 +0000 Subject: [PATCH 01/17] Move Overkiz API docs --- docs/{ => api}/apiDocDyn.js | 0 docs/{ => api}/apiDocStyle.css | 0 docs/{tahoma_api.html => api/index.html} | 0 docs/{ => api}/jquery-1.10.2-ui.js | 0 docs/{ => api}/jquery-1.10.2.js | 0 docs/callable_names.txt | 639 ----------------------- 6 files changed, 639 deletions(-) rename docs/{ => api}/apiDocDyn.js (100%) rename docs/{ => api}/apiDocStyle.css (100%) rename docs/{tahoma_api.html => api/index.html} (100%) rename docs/{ => api}/jquery-1.10.2-ui.js (100%) rename docs/{ => api}/jquery-1.10.2.js (100%) delete mode 100644 docs/callable_names.txt diff --git a/docs/apiDocDyn.js b/docs/api/apiDocDyn.js similarity index 100% rename from docs/apiDocDyn.js rename to docs/api/apiDocDyn.js diff --git a/docs/apiDocStyle.css b/docs/api/apiDocStyle.css similarity index 100% rename from docs/apiDocStyle.css rename to docs/api/apiDocStyle.css diff --git a/docs/tahoma_api.html b/docs/api/index.html similarity index 100% rename from docs/tahoma_api.html rename to docs/api/index.html diff --git a/docs/jquery-1.10.2-ui.js b/docs/api/jquery-1.10.2-ui.js similarity index 100% rename from docs/jquery-1.10.2-ui.js rename to docs/api/jquery-1.10.2-ui.js diff --git a/docs/jquery-1.10.2.js b/docs/api/jquery-1.10.2.js similarity index 100% rename from docs/jquery-1.10.2.js rename to docs/api/jquery-1.10.2.js diff --git a/docs/callable_names.txt b/docs/callable_names.txt deleted file mode 100644 index 8ee5ac35..00000000 --- a/docs/callable_names.txt +++ /dev/null @@ -1,639 +0,0 @@ -camera:DomisCameraComponent -camera:GenericCameraComponent -core:OccupancySensor -core:SmokeSensor -core:WeatherSystemSensor -eliot:DimmerLightEliotComponent -eliot:EliotElectricEnergyConsumptionSensor -eliot:OnOffLightEliotComponent -eliot:OnOffSwitchEliotComponent -eliot:RemoteEliotComponent -eliot:RollerShutterEliotComponent -enocean:EnOcean0to1530LuxLightSensor -enocean:EnOcean0to510LuxLightSensor -enocean:EnOcean0to999LuxLightSensor -enocean:EnOceanAirQualityBasedOnTemperatureHumiditySensor -enocean:EnOceanAvidsenAMRCounter -enocean:EnOceanAvidsenRollerShutterComponent -enocean:EnOceanAvidsenRollerShutterComponentWithReCom -enocean:EnOceanAvidsenTICCounter -enocean:EnOceanCO2Sensor -enocean:EnOceanCaleffiValveComponent -enocean:EnOceanCardSwitchComponent -enocean:EnOceanContactSensor -enocean:EnOceanContactWithVoltageSupplySensor -enocean:EnOceanDimplexVentilationComponent -enocean:EnOceanElectricConsumptionCounter -enocean:EnOceanElectricCurrentConsumptionSensor -enocean:EnOceanElectricEnergyConsumptionSensor -enocean:EnOceanEwattchAMRCounter -enocean:EnOceanEwattchTICCounter -enocean:EnOceanEwattchTICPowerConsumption -enocean:EnOceanGenericAMRCounter -enocean:EnOceanGenericActuator -enocean:EnOceanGenericElectricCounter -enocean:EnOceanHVACBatteryPoweredComponent -enocean:EnOceanHVACTemperatureSensor -enocean:EnOceanHeatingSystemConsumptionSensor -enocean:EnOceanHumidityComfortSensor -enocean:EnOceanHumiditySensor -enocean:EnOceanInternalHumiditySensor -enocean:EnOceanLightSensorType01 -enocean:EnOceanLightSensorType02 -enocean:EnOceanMicroPeltValveComponent -enocean:EnOceanMicroPeltValveV2WithRemoteCommissioningComponent -enocean:EnOceanMicroPeltValveWithRemoteCommissioningComponent -enocean:EnOceanMultiChannelEnergyConsumptionSensor -enocean:EnOceanNativeRepeaterComponent -enocean:EnOceanNexelecHumiditySensor -enocean:EnOceanNexelecSmokeSensor -enocean:EnOceanNexelecTemperatureSensor -enocean:EnOceanOccupancySensor -enocean:EnOceanOnOffHeatingSystemComponent -enocean:EnOceanOnOffHeatingSystemComponentWithReCom -enocean:EnOceanOnOffLight -enocean:EnOceanPMDMValveWithRemoteCommissioning -enocean:EnOceanPilotWireComponent -enocean:EnOceanPilotWireComponentWithReCom -enocean:EnOceanPilotWireThermostatComponent -enocean:EnOceanRainSensor -enocean:EnOceanRepeaterComponent -enocean:EnOceanRockerSwitchAutoManuUpDownComponent -enocean:EnOceanRockerSwitchx1Component -enocean:EnOceanRockerSwitchx2Component -enocean:EnOceanRockerSwitchx4Component -enocean:EnOceanRollerShutter -enocean:EnOceanRoomOperatingPanelFanSpeed -enocean:EnOceanRoomOperatingPanelOccupancyControl -enocean:EnOceanRoomOperatingPanelTemperatureSensor -enocean:EnOceanSmokeSensor -enocean:EnOceanStatefulRollerShutter -enocean:EnOceanSunIntensitySensor -enocean:EnOceanSwitchOnOff -enocean:EnOceanSwitchOnOffConsumptionSensorType6 -enocean:EnOceanSwitchOnOffConsumptionSensorType8 -enocean:EnOceanSwitchOnOffConsumptionSensorTypeB -enocean:EnOceanSwitchOnOffConsumptionSensorTypeE -enocean:EnOceanSwitchOnOffType1 -enocean:EnOceanSwitchOnOffType12 -enocean:EnOceanSwitchOnOffType12WithReCom -enocean:EnOceanSwitchOnOffType12WithRemoteCommissioning -enocean:EnOceanSwitchOnOffType6 -enocean:EnOceanSwitchOnOffType8 -enocean:EnOceanSwitchOnOffType8WithReCom -enocean:EnOceanSwitchOnOffTypeA -enocean:EnOceanSwitchOnOffTypeB -enocean:EnOceanSwitchOnOffTypeE -enocean:EnOceanSwitchOnOffTypeF -enocean:EnOceanSwitchOnOffTypeFWithReCom -enocean:EnOceanSwitchOnOffTypeFWithRemoteCommissioning -enocean:EnOceanTemperatureSensor -enocean:EnOceanTemperatureSensorScale0To51 -enocean:EnOceanTemperatureSensorScaleMinus30To50 -enocean:EnOceanTemperatureSensorScaleMinus40To80 -enocean:EnOceanTemperatureSensorType01 -enocean:EnOceanTemperatureSensorType05 -enocean:EnOceanTemperatureSensorType14 -enocean:EnOceanTemperatureSetPoint -enocean:EnOceanThermostatComponent -enocean:EnOceanThermostatController -enocean:EnOceanVOCSensor -enocean:EnOceanVenetianBlindController -enocean:EnOceanVenetianBlindControllerWithRemoteCommissioning -enocean:EnOceanWaterSensor -enocean:EnOceanWindSpeedSensor -enocean:EnOceanWindowHandle -enocean:EnOceanWindowWithVibrationDetectionSensor -enocean:EnOceanWizzConsoCounter -enocean:EnOceanWizzPulseCounter -enocean:EnoceanRollerShutterWithRemoteCommissioning -enocean:RemoteControllerOneWayComponent -enocean:TransceiverEnoceanComponent -hue:BloomHUEComponent -hue:BridgeHUEComponent -hue:BridgeHUEV2Component -hue:ColorLightModuleHUEComponent -hue:ColorTemperatureLightBulbHUEComponent -hue:ColorTemperatureLightCandleHUEComponent -hue:ColorTemperatureLightSpotHUEComponent -hue:ColorTemperatureModuleHUEComponent -hue:ExtendedColorLightCandleHUEComponent -hue:GenericColorLightHUEComponent -hue:GenericColorTemperatureLightHUEComponent -hue:GenericDimmableLightHUEComponent -hue:GenericExtendedColorLightHUEComponent -hue:GoHUEComponent -hue:HueLampHUEComponent -hue:HueLuxHUEComponent -hue:HueSpotHUEComponent -hue:LightStripsHUEComponent -hue:LightStripsPlusHUEComponent -hue:PhoenixHUEComponent -internal:PodComponent -internal:PodMiniComponent -internal:PodV2Component -internal:PodV3Component -internal:TSKAlarmComponent -internal:TSKDockComponent -internal:UPodComponent -internal:UPodNetWorkComponent -internal:WifiComponent -io:AdjustableSlatsRollerShutterIOComponent -io:AirConditioningElectricalEnergyConsumptionSensor -io:AlarmIOComponent -io:AtlanticDimmableLightIOComponent -io:AtlanticDomesticHotWaterProductionIOComponent -io:AtlanticDomesticHotWaterProductionV2IOComponent -io:AtlanticDomesticHotWaterProductionV2_AEX_IOComponent -io:AtlanticDomesticHotWaterProductionV2_CETHI_V4_IOComponent -io:AtlanticDomesticHotWaterProductionV2_CE_FLAT_C2_IOComponent -io:AtlanticDomesticHotWaterProductionV2_CE_S4_IOComponent -io:AtlanticDomesticHotWaterProductionV2_CV4E_IOComponent -io:AtlanticDomesticHotWaterProductionV2_MURAL_IOComponent -io:AtlanticDomesticHotWaterProductionV2_SPLIT_IOComponent -io:AtlanticDomesticHotWaterProductionV2_TEC5_IOComponent -io:AtlanticDomesticHotWaterProductionV3IOComponent -io:AtlanticElectricalHeaterIOComponent -io:AtlanticElectricalHeaterWithAdjustableTemperatureSetpointIOComponent -io:AtlanticElectricalTowelDryerIOComponent -io:AtlanticElectricalTowelDryer_IC3_IOComponent -io:AtlanticHeatRecoveryVentilationIOComponent -io:AtlanticPassAPCBoilerMainComponent -io:AtlanticPassAPCDHWComponent -io:AtlanticPassAPCECSFossilEnergyConsumptionSensor -io:AtlanticPassAPCHeatPumpMainComponent -io:AtlanticPassAPCHeatingAndCoolingZoneComponent -io:AtlanticPassAPCHeatingFossilEnergyConsumptionSensor -io:AtlanticPassAPCHeatingZoneComponent -io:AtlanticPassAPCOutsideTemperatureSensor -io:AtlanticPassAPCTotalFossilEnergyConsumptionSensor -io:AtlanticPassAPCZoneControlMainComponent -io:AtlanticPassAPCZoneControlZoneComponent -io:AtlanticPassAPCZoneTemperatureSensor -io:AwningReceiverUnoIOComponent -io:AwningValanceIOComponent -io:BeaconIOComponent -io:BioclimaticPergolaIOComponent -io:CO2IOSystemDeviceSensor -io:CO2IOSystemSensor -io:COIOSystemSensor -io:CarButtonIODeviceSensor -io:CarLockIOComponent -io:ContactIOSystemDeviceSensor -io:ContactIOSystemSensor -io:CoolingRelatedElectricalEnergyConsumptionSensor -io:CumulatedElectricalEnergyConsumptionIOSystemDeviceSensor -io:CumulatedElectricalEnergyConsumptionIOSystemSensor -io:CumulatedThermalEnergyConsumptionIOSystemSensor -io:CumulatedWaterConsumptionIOSystemSensor -io:CurtainTrackUnoIOComponent -io:CyclicStandardReceiverIOComponent -io:DHWCumulatedElectricalEnergyConsumptionIOSystemDeviceSensor -io:DHWElectricalEnergyConsumptionSensor -io:DHWRelatedElectricalEnergyConsumptionSensor -io:DHWRelatedFossilEnergyConsumptionSensor -io:DimmableColorTemperatureLightIOComponent -io:DimmableLightIOComponent -io:DimmableRGBLightIOComponent -io:DiscreteExteriorHeatingIOComponent -io:DiscreteGarageOpenerIOComponent -io:DiscreteGarageOpenerWithPartialPositionIOComponent -io:DiscreteGateOpenerIOComponent -io:DomesticHotWaterTankComponent -io:DoorLockIOComponent -io:DropArmAwningIOComponent -io:DualRollerShutterIOComponent -io:ElectricalHeaterGenericIOComponent -io:ElectricalHeaterWithAdjustableTemperatureSetpointGenericIOComponent -io:ElectricityMeterComponent -io:EnergyConsumptionSensorsConfigurationComponent -io:EnergyConsumptionSensorsHeatPumpComponent -io:ExteriorHeatingIOComponent -io:ExteriorVenetianBlindIOComponent -io:ExteriorVenetianBlindUnoIOComponent -io:ExteriorVenetianBlindWithWP2IOComponent -io:ExteriorVenetianBlindWithWPIOComponent -io:GarageOpenerIOComponent -io:GasDHWConsumptionSensor -io:GasHeaterConsumptionSensor -io:GateOpenerIOComponent -io:GenericPulseSensor -io:GradHermeticIOComponent -io:HeatPumpIOComponent -io:HeatingElectricalEnergyConsumptionSensor -io:HeatingRelatedElectricalEnergyConsumptionSensor -io:HeatingRelatedFossilEnergyConsumptionSensor -io:HeatingTemperatureInterfaceIOComponent -io:HeatingValveIOComponent -io:HorizontalAwningIOComponent -io:HorizontalAwningUnoIOComponent -io:IORemoteController -io:IzymoController -io:KeygoController -io:KizOThermBoilerTemperatureSensor -io:KizOThermDHWTemperatureSensor -io:KizOThermIOComponent -io:KizOThermOutsideTemperatureSensor -io:KizOThermRoomTemperatureSensor -io:KizOThermV2IOComponent -io:LightIOSystemDeviceSensor -io:LightIOSystemSensor -io:LightMicroModuleSomfyIOComponent -io:LockUnlockDoorLockWithUnknownPositionIOComponent -io:MicroModuleRollerShutterSomfyIOComponent -io:OccupancyIOSystemDeviceSensor -io:OccupancyIOSystemSensor -io:OnOffIOComponent -io:OnOffLightIOComponent -io:OpenClosedTiltSensor -io:OtherElectricalEnergyConsumptionSensor -io:PergolaHorizontalUnoIOComponent -io:PergolaRailGuidedAwningIOComponent -io:PergolaScreenIOComponent -io:PergolaSideScreenIOComponent -io:PlugsElectricalEnergyConsumptionSensor -io:PositionableAndLockableSlidingWindowComponent -io:PositionableSlidingWindowComponent -io:ProjectionRollerShutterIOComponent -io:RSOverkizIOComponent -io:RainIOSystemSensor -io:RelativeHumidityIOSystemDeviceSensor -io:RelativeHumidityIOSystemSensor -io:RollerShutterGenericIOComponent -io:RollerShutterUnoIOComponent -io:RollerShutterVeluxIOComponent -io:RollerShutterWithLowSpeedManagementIOComponent -io:RollingDoorOpenerIOComponent -io:ScreenReceiverUnoIOComponent -io:SimpleBioclimaticPergolaIOComponent -io:SimpleExteriorHeatingIOComponent -io:SirenIOComponent -io:SlidingDiscreteFullyPedestriableGateOpenerIOComponent -io:SmokeIOSystemSensor -io:SomfyBasicContactIOSystemSensor -io:SomfyContactIOSystemSensor -io:SomfyIndoorSimpleSirenIOComponent -io:SomfyOccupancyIOSystemSensor -io:SomfyRainIOSystemSensor -io:SomfySmokeIOSystemSensor -io:SunEnergyIOSystemSensor -io:SwimmingPoolIOComponent -io:SwitchMicroModuleIOComponent -io:SwitchMicroModuleSomfyIOComponent -io:TemperatureIOSystemSensor -io:TemperatureInCelciusIOSystemDeviceSensor -io:TotalElectricalEnergyConsumptionIOSystemSensor -io:TotalElectricalEnergyConsumptionSensor -io:TotalFossilEnergyConsumptionSensor -io:UnknownIOComponent -io:VRHollaIOComponent -io:VenetianBlindIOComponent -io:VentilationPointAirInletIOComponent -io:VentilationPointAirOutletIOComponent -io:VentilationPointAirTransferIOComponent -io:VentilationPointIOComponent -io:VerticalExteriorAwningIOComponent -io:VerticalExteriorAwningUnoIOComponent -io:VerticalInteriorBlindGenericIOComponent -io:VerticalInteriorBlindUnoIOComponent -io:VerticalInteriorBlindVeluxIOComponent -io:VibrationSensor -io:WindIOSystemSensor -io:WindowLockIOComponent -io:WindowOpenerGenericIOComponent -io:WindowOpenerUnoIOComponent -io:WindowOpenerVeluxIOComponent -jsw:CameraController -modbus:DeDietrichGatewayComponent -modbus:FlaktWoodsRS485Component -modbus:YutakiDHWTComponent -modbus:YutakiMainComponent -modbus:YutakiRoomThermostatZone1Component -modbus:YutakiRoomThermostatZone2Component -modbus:YutakiSwimmingPoolComponent -modbus:YutakiV2DHWElectricalEnergyConsumptionComponent -modbus:YutakiV2DHWTComponent -modbus:YutakiV2SpaceCoolingElectricalEnergyConsumptionComponent -modbus:YutakiV2SpaceHeatingElectricalEnergyConsumptionComponent -modbus:YutakiV2SwimmingPoolElectricalEnergyConsumptionComponent -modbus:YutakiV2Zone1Component -modbus:YutakiV2Zone2Component -modbus:YutakiZone1Component -modbus:YutakiZone2Component -myfox:AlarmController -myfox:CameraController -myfox:HomeKeeperProAlarmController -myfox:LightController -myfox:SecurityCameraController -myfox:SomfyOneCameraController -myfox:SomfyOnePlusCameraController -myfox:SomfyProtectAlarmController -myfox:SomfyProtectSecurityCameraController -opendoors:OpenDoorsSmartLockComponent -ovp:BoilerControllerOVPComponent -ovp:CoolingCumulatedElectricalEnergyConsumptionSensor -ovp:CothermThermostatOVPComponent -ovp:DHW1OnDHWCircuitOVPComponent -ovp:DHW1TemperatureSensorOnDHWCircuitOVPComponent -ovp:DHW2OnAuxiliaryCircuitOVPComponent -ovp:DHW2OnCircuitAOVPComponent -ovp:DHW2TemperatureSensorOnAuxiliaryCircuitOVPComponent -ovp:DHW2TemperatureSensorOnCircuitAOVPComponent -ovp:DHWCumulatedElectricalEnergyConsumptionSensor -ovp:DeDietrichModbusGatewayOVPComponent -ovp:ElectricalHeaterGenericOVPComponent -ovp:HLinkMainController -ovp:HeatingCircuitOnCircuitAOVPComponent -ovp:HeatingCircuitOnCircuitBOVPComponent -ovp:HeatingCircuitOnCircuitCOVPComponent -ovp:HeatingCircuitTemperatureSensorOnCircuitAOVPComponent -ovp:HeatingCircuitTemperatureSensorOnCircuitBOVPComponent -ovp:HeatingCircuitTemperatureSensorOnCircuitCOVPComponent -ovp:HeatingCumulatedElectricalEnergyConsumptionSensor -ovp:HeatingTemperatureInterfaceTemperatureSensor -ovp:ImhotepHeatingTemperatureInterfaceOVPComponent -ovp:ImhotepHeatingTemperatureInterfaceTemperatureSensor -ovp:ImhotepHeatingTemperatureRelayOVPComponent -ovp:InsideTemperatureSensorOVPComponent -ovp:KizOThermBoilerTemperatureSensor -ovp:KizOThermDHWTemperatureSensor -ovp:KizOThermOutsideTemperatureSensor -ovp:KizOThermRoomTemperatureSensor -ovp:KizOThermV2OVPComponent -ovp:LPBMainController -ovp:ModbusMainController -ovp:OnOffOVPComponent -ovp:OutsideTemperatureSensorOVPComponent -ovp:SolarCircuitOVPComponent -ovp:SomfyHeatingTemperatureInterfaceOVPComponent -ovp:SomfyPilotWireElectricalHeaterOVPComponent -ovp:SomfyPilotWireHeatingInterfaceOVPComponent -ovp:SomfyPilotWireTemperatureSensorOVPComponent -ovp:SwimmingPoolOnCircuitBOVPComponent -ovp:SwimmingPoolOnCircuitCOVPComponent -ovp:SwimmingPoolTemperatureSensorOnCircuitBOVPComponent -ovp:SwimmingPoolTemperatureSensorOnCircuitCOVPComponent -ovp:UnknownOVPComponent -profalux868:Profalux868ExteriorScreen -profalux868:Profalux868ExteriorScreenPlatinum -profalux868:Profalux868ExteriorVenetianBlind -profalux868:Profalux868ExteriorVenetianBlindPlatinum -profalux868:Profalux868RollerShutter -profalux868:Profalux868RollerShutterPlatinum -ramses:EvoHomeController -ramses:EvoHomeControllerSensor -ramses:EvoHomeDHWSensor -ramses:EvoHomeDHWSetPoint -ramses:EvoHomeZoneSensor -ramses:EvoHomeZoneSetPoint -ramses:RamsesOpenThermGateway -rtd:AlarmRTDComponent -rtd:IndoorSirenRTDComponent -rtd:MotionOrContactSensorRTDComponent -rtd:OutdoorSirenRTDComponent -rtd:UnknownRTDComponent -rtds:RTDSCOSensor -rtds:RTDSContactSensor -rtds:RTDSGasSensor -rtds:RTDSMotionSensor -rtds:RTDSPowerFailure -rtds:RTDSRemoteControllerComponent -rtds:RTDSSmokeSensor -rtds:RTDSTemperatureSensor -rtds:RTDSWaterSensor -rtds:SirenStatusRTDSComponent -rtds:UnknownRTDSComponent -rts:BlindRTSComponent -rts:CurtainRTSComponent -rts:DimmableLightRTSComponent -rts:DualCurtainRTSComponent -rts:ExteriorBlindRTSComponent -rts:ExteriorHeatingRTSComponent -rts:ExteriorVenetianBlindRTSComponent -rts:GarageDoor4TRTSComponent -rts:GarageDoorRTSComponent -rts:GarageDoorWithVentilationPositionRTSComponent -rts:GateOpenerRTS4TComponent -rts:GateOpenerRTSComponent -rts:GateOpenerWithPedestrianPositionRTSComponent -rts:Generic4TRTSComponent -rts:GenericRTSComponent -rts:HorizontalAwningRTSComponent -rts:LightRTSComponent -rts:OnOffRTSComponent -rts:RollerShutterRTSComponent -rts:SlidingGarageDoor4TRTSComponent -rts:SlidingGarageDoorRTSComponent -rts:SlidingGarageDoorWithPedestrianPositionRTSComponent -rts:SlidingGateOpener4TRTSComponent -rts:SlidingGateOpenerRTSComponent -rts:SlidingGateOpenerWithPedestrianPositionRTSComponent -rts:SwingingShutterRTSComponent -rts:ThermostatRTSComponent -rts:UnknowRTSComponent -rts:VenetianBlindRTSComponent -rts:WindowsOpenerRTSComponent -somfythermostat:SomfyThermostatHumiditySensor -somfythermostat:SomfyThermostatTemperatureSensor -somfythermostat:SomfyThermostatThermostatComponent -upnpcontrol:GenericSonosPlayerComponent -upnpcontrol:SonosConnectAMPComponent -upnpcontrol:SonosConnectComponent -upnpcontrol:SonosOneComponent -upnpcontrol:SonosPlayBarComponent -upnpcontrol:SonosPlayBaseComponent -upnpcontrol:SonosPlayFiveComponent -upnpcontrol:SonosPlayOneComponent -upnpcontrol:SonosSubComponent -upnpcontrol:UPnPControlMediaRendererComponent -verisure:GenericAlarmPanel -wiser:CookingCumulatedElectricalEnergyConsumptionSensor -wiser:CoolingCumulatedElectricalEnergyConsumptionSensor -wiser:DHWCumulatedElectricalEnergyConsumptionSensor -wiser:HeatingCumulatedElectricalEnergyConsumptionSensor -wiser:OtherCumulatedElectricalEnergyConsumptionSensor -wiser:PlugsCumulatedElectricalEnergyConsumptionSensor -wiser:TotalColdWaterConsumptionSensor -wiser:TotalElectricalEnergyConsumptionSensor -wiser:TotalElectricalEnergyProductionSensor -wiser:TotalGasConsumptionSensor -wiser:TotalHotWaterConsumptionSensor -wiser:TotalThermalEnergyConsumptionSensor -zigbee:AirQualityBasedOnTemperatureHumiditySensorComponent -zigbee:AwningComponent -zigbee:BallastComponent -zigbee:CIEColorSpaceXYLightComponent -zigbee:CarbonMonoxideSensorComponent -zigbee:CleodeZPilotComponent -zigbee:ColorLightComponent -zigbee:ColorLoopCIEXYLightComponent -zigbee:ColorLoopColorTemperatureLightComponent -zigbee:ColorLoopLightComponent -zigbee:ColorTemperatureCIEXYLightComponent -zigbee:ColorTemperatureLightComponent -zigbee:CurtainComponent -zigbee:DanfossIconModuleComponent -zigbee:DoorSensorComponent -zigbee:ElectricalEnergyConsumptionSensorComponent -zigbee:ElectricalPowerConsumptionSensorComponent -zigbee:EnhancedHueCIEXYLightComponent -zigbee:EnhancedHueColorTemperatureLightComponent -zigbee:EnhancedHueLightComponent -zigbee:EnhancedHueXYTemperatureLightComponent -zigbee:GlobalAirQualityComponent -zigbee:GroupCIEColorSpaceXYLightComponent -zigbee:GroupColorLightComponent -zigbee:GroupColorLoopCIEXYLightComponent -zigbee:GroupColorLoopColorTemperatureLightComponent -zigbee:GroupColorLoopLightComponent -zigbee:GroupColorTemperatureCIEXYLightComponent -zigbee:GroupColorTemperatureLightComponent -zigbee:GroupConfigurationComponent -zigbee:GroupEnhancedHueCIEXYLightComponent -zigbee:GroupEnhancedHueColorTemperatureLightComponent -zigbee:GroupEnhancedHueLightComponent -zigbee:GroupEnhancedHueXYTemperatureLightComponent -zigbee:GroupHueCIEXYLightComponent -zigbee:GroupHueColorTemperatureLightComponent -zigbee:GroupHueLightComponent -zigbee:GroupHueXYTemperatureLightComponent -zigbee:GroupLightComponent -zigbee:GroupOnOffComponent -zigbee:GroupOnOffLightComponent -zigbee:GroupSomfyCurtainComponent -zigbee:GroupSomfyInteriorBlindComponent -zigbee:GroupSomfyRollerShadeComponent -zigbee:HueCIEXYLightComponent -zigbee:HueColorTemperatureLightComponent -zigbee:HueLightComponent -zigbee:HueXYTemperatureLightComponent -zigbee:HumidityComfortSensorComponent -zigbee:InteriorBlindComponent -zigbee:LightComponent -zigbee:MotionSensorComponent -zigbee:NexelecSmokeSensorComponent -zigbee:OnOffComponent -zigbee:OnOffLightComponent -zigbee:ProfaluxExteriorVenetianBlindComponent -zigbee:ProfaluxGenericComponent -zigbee:ProfaluxInteriorBlindComponent -zigbee:ProfaluxRollerShutterComponent -zigbee:ProfaluxTransceiverComponent -zigbee:RelativeHumidityComponent -zigbee:RollerShadeComponent -zigbee:RollerShutterComponent -zigbee:SchneiderBallastComponent -zigbee:SchneiderSwitchConfigurationComponent -zigbee:SmokeSensorComponent -zigbee:SomfyConfigurationToolComponent -zigbee:SomfyCurtainComponent -zigbee:SomfyInteriorBlindComponent -zigbee:SomfyRollerShadeComponent -zigbee:StackComponent -zigbee:StackV3Component -zigbee:TemperatureSensorComponent -zigbee:TransceiverV3_0Component -zigbee:WaterLeakageSensorComponent -zigbee:ZigbeeNetworkNode -zigbee:ZigbeeRemoteComponent -zigbee:ZigbeeSomfyIRBlasterComponent -zigbee:ZigbeeSomfyRemoteComponent -zwave:AeotecControllerConfigurationZWaveComponent -zwave:AeotecHeavyDutySmartSwitchConfigurationZWaveComponent -zwave:AeotecHomeEnergyMeterMainConfigurationZWaveComponent -zwave:AeotecInWallSmartSwitchConfigurationZWaveComponent -zwave:AeotecNanoDimmerConfigurationZWaveComponent -zwave:AssociationClassV2Component -zwave:BasicClassComponent -zwave:BatteryClassV1Component -zwave:BatteryConfigurationZWaveComponent -zwave:BinarySwitchClassV1Component -zwave:CentralSceneClassV1Component -zwave:ConfigurationV1ClassComponent -zwave:DanfossHydronicControllerThermostatZWaveComponent -zwave:DanfossHydronicControllerZWaveComponent -zwave:DanfossRSLinkConfigurationZWaveComponent -zwave:DimmableLightZWaveComponent -zwave:DimmableOnOffZWaveComponent -zwave:DoorLockClassOpenCloseSensorComponent -zwave:DoorLockClassV1Component -zwave:DoorLockClassV2Component -zwave:DynamicNodeComponent -zwave:FibaroDoorWindowSensorConfigurationZWaveComponent -zwave:FibaroGateRollerShutterConfigurationZWaveComponent -zwave:FibaroGateWithoutPositionRollerShutterConfigurationZWaveComponent -zwave:FibaroVenetianRollerShutterConfigurationZWaveComponent -zwave:FibaroWithPositionRollerShutterConfigurationZWaveComponent -zwave:FibaroWithoutPositionRollerShutterConfigurationZWaveComponent -zwave:GateWithoutPositionZWaveComponent -zwave:GateZWaveComponent -zwave:HeatitThermostatConfigurationZWaveComponent -zwave:HeatitZWaterConfigurationZWaveComponent -zwave:IDLockConfigurationZWaveComponent -zwave:IDLockZWaveComponent -zwave:IndicatorClassV1Component -zwave:MeterClassV1Component -zwave:MeterClassV2Component -zwave:MeterClassV3Component -zwave:MultiChannelAssociationClassV2Component -zwave:MultilevelSensorClassV1Component -zwave:MultilevelSensorClassV2Component -zwave:MultilevelSensorClassV3Component -zwave:MultilevelSensorClassV4Component -zwave:MultilevelSwitchClassV1Component -zwave:MultilevelWireZWaveComponent -zwave:NodeComponent -zwave:NodonRemoteControllerConfigurationZWaveComponent -zwave:NotificationClassV2V8Component -zwave:OnOffButtonZWaveComponent -zwave:OnOffLightZWaveComponent -zwave:OnOffZWaveComponent -zwave:PowerLevelClassV1Component -zwave:ProgrammableAndProtectableThermostatSetPointZWaveComponent -zwave:QubinoDINPilotWireConfigurationZWaveComponent -zwave:QubinoFlush1DRelayConfigurationZWaveComponent -zwave:QubinoFlush2DRelayConfigurationZWaveComponent -zwave:QubinoFlushDimmerConfigurationZWaveComponent -zwave:QubinoFlushShutterMainConfigurationComponent -zwave:QubinoFlushShutterTemperatureConfigurationComponent -zwave:QubinoFlushShutterVenetianConfigurationComponent -zwave:QubinoMiniDimmerConfigurationZWaveComponent -zwave:QubinoRollerShutterConfigurationZWaveComponent -zwave:QubinoVenitianRollerShutterConfigurationZWaveComponent -zwave:RepeaterZWaveComponent -zwave:RockerSwitchx2WithBatteryZWaveComponent -zwave:RockerSwitchx2ZWaveComponent -zwave:RollerShutterV3Component -zwave:RollerShutterWithoutPositionZWaveComponent -zwave:RollerShutterZWaveComponent -zwave:SEDeviceCentralSceneZWaveComponent -zwave:SEDevicesDimmerConfigurationZWaveComponent -zwave:SEDevicesMultiSwitchConfigurationZWaveComponent -zwave:SEDevicesRelayConfigurationZWaveComponent -zwave:SEDevicesThermostatConfigurationZWaveComponent -zwave:SEDevicesWheelControllerConfigurationZWaveComponent -zwave:SensativeStripsGuardsConfiguration -zwave:SlatsOrientationV3Component -zwave:TemperatureSensorV7Component -zwave:ThermostatModeClassV1Component -zwave:ThermostatModeClassV2Component -zwave:ThermostatModeClassV3Component -zwave:ThermostatSetPointClassV1Component -zwave:ThermostatSetPointClassV2Component -zwave:ThermostatSetPointGenericZWaveComponent -zwave:TransceiverZWaveComponent -zwave:VenetianBlindZWaveComponent -zwave:WakeUpClassV1Component -zwave:WakeUpClassV2Component -zwave:ZWaveLightSensor -zwave:ZWaveMoistureSensor -zwave:ZWaveNotificationCO2Sensor -zwave:ZWaveNotificationCOSensor -zwave:ZWaveNotificationContactSensor -zwave:ZWaveNotificationHeatSensor -zwave:ZWaveNotificationHomeSecuritySensor -zwave:ZWaveNotificationMotionSensor -zwave:ZWaveNotificationSmokeSensor -zwave:ZWaveNotificationWaterSensor -zwave:ZWaveSmokeSensor -zwave:ZWaveTemperatureSensor From ba97bd5b80a7868faa5ca2c2f2d636c74f9fe3bd Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 17:08:30 +0000 Subject: [PATCH 02/17] Add first (AI generated) version --- .github/workflows/docs.yml | 37 ++++ docs/api-reference.md | 13 ++ docs/authentication.md | 64 ++++++ docs/contribute.md | 38 ++++ docs/core-concepts.md | 44 +++++ docs/device-control.md | 133 +++++++++++++ docs/error-handling.md | 56 ++++++ docs/event-handling.md | 101 ++++++++++ docs/getting-started.md | 101 ++++++++++ docs/index.md | 16 ++ docs/troubleshooting.md | 41 ++++ mkdocs.yml | 39 ++++ pyproject.toml | 9 + uv.lock | 390 +++++++++++++++++++++++++++++++++++++ 14 files changed, 1082 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/api-reference.md create mode 100644 docs/authentication.md create mode 100644 docs/contribute.md create mode 100644 docs/core-concepts.md create mode 100644 docs/device-control.md create mode 100644 docs/error-handling.md create mode 100644 docs/event-handling.md create mode 100644 docs/getting-started.md create mode 100644 docs/index.md create mode 100644 docs/troubleshooting.md create mode 100644 mkdocs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..81d77b6e --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,37 @@ +name: docs + +on: + push: + branches: + - main + - v2/docs + +permissions: + contents: write + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Set up uv + uses: astral-sh/setup-uv@v3 + + - name: Install docs dependencies + run: uv pip install -e ".[docs]" + + - name: Build site + run: uv run mkdocs build + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: site diff --git a/docs/api-reference.md b/docs/api-reference.md new file mode 100644 index 00000000..f10e1f8f --- /dev/null +++ b/docs/api-reference.md @@ -0,0 +1,13 @@ +::: pyoverkiz.client.OverkizClient + +::: pyoverkiz.models + options: + show_source: false + +::: pyoverkiz.enums + options: + show_source: false + +::: pyoverkiz.exceptions + options: + show_source: false diff --git a/docs/authentication.md b/docs/authentication.md new file mode 100644 index 00000000..1551be49 --- /dev/null +++ b/docs/authentication.md @@ -0,0 +1,64 @@ +# Authentication + +## Cloud username and password + +Cloud authentication uses a vendor server from `Server` plus `UsernamePasswordCredentials`. + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + print(await client.get_api_version()) + + +asyncio.run(main()) +``` + +## Local token authentication + +Local authentication requires a token generated by the official mobile app and a local user on the OverKiz API platform. + +```python +import asyncio + +from pyoverkiz.auth.credentials import LocalTokenCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.utils import create_local_server_config + + +async def main() -> None: + async with OverkizClient( + server=create_local_server_config(host="gateway-xxxx.local"), + credentials=LocalTokenCredentials("local-token"), + verify_ssl=False, + ) as client: + await client.login() + print(await client.get_api_version()) + + +asyncio.run(main()) +``` + +## Token refresh behavior + +The client refreshes access tokens as needed during authenticated calls. If you see authentication errors, re-run `login()` before retrying the request. + +## Unsupported auth flows + +Some vendors use authentication flows that are not supported. In those cases, obtain a local token and use a local server configuration instead. + +## Secure storage tips + +- Use environment variables or a secret manager for tokens. +- Avoid hard-coding credentials in source control. +- Rotate tokens regularly if your vendor supports it. diff --git a/docs/contribute.md b/docs/contribute.md new file mode 100644 index 00000000..acb0cfb3 --- /dev/null +++ b/docs/contribute.md @@ -0,0 +1,38 @@ +# Contribute + +Thanks for contributing to pyOverkiz! This project powers production integrations and values careful changes, clear tests, and thoughtful documentation. + +## Development setup + +```bash +uv sync +``` + +Install git hooks: + +```bash +uv run prek install +``` + +## Tests and linting + +```bash +uv run pytest +``` + +```bash +uv run prek run --all-files +``` + +## Project guidelines + +- Use Python 3.10–3.13 features and type annotations. +- Keep absolute imports and avoid relative imports. +- Preserve existing comments and logging unless your change requires updates. +- Prefer small, focused changes and add tests when behavior changes. + +## Submitting changes + +1. Create a feature branch. +2. Run linting and tests. +3. Open a pull request with a clear description and context. diff --git a/docs/core-concepts.md b/docs/core-concepts.md new file mode 100644 index 00000000..901ea942 --- /dev/null +++ b/docs/core-concepts.md @@ -0,0 +1,44 @@ +# Core concepts + +## Servers and gateways + +A server describes where the API calls go. A gateway is the physical hub in your home. Cloud servers route through vendor infrastructure; local servers talk directly to the gateway on your network. + +## Setup and devices + +The setup describes the current gateway configuration and device inventory. Devices expose metadata like `uiClass` and `widget`, plus a list of current `states`. + +## Actions, action groups, and commands + +Commands are sent as `Action` objects, grouped into an action group. Each action targets a device URL and a set of commands with parameters. + +## States + +States are name/value pairs that represent the current device status, such as closure position or temperature. + +## Events and listeners + +The API uses an event listener that you register once per session. Fetching events drains the server-side buffer. + +## Execution model + +Commands are executed asynchronously by the platform. You can poll execution state via events or refresh device states after a delay. + +## Relationship diagram + +``` +Client + | + |-- Server (cloud or local) + | + |-- Gateway + | + |-- Setup + | | + | |-- Devices + | | + | |-- States + | |-- Actions -> Commands -> Parameters + | + |-- Event Listener -> Events +``` diff --git a/docs/device-control.md b/docs/device-control.md new file mode 100644 index 00000000..d96796af --- /dev/null +++ b/docs/device-control.md @@ -0,0 +1,133 @@ +# Device control + +## List devices + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + devices = await client.get_devices() + for device in devices: + print(device.label, device.controllable_name) + + +asyncio.run(main()) +``` + +## Read a state value + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + devices = await client.get_devices() + device = devices[0] + closure_state = next( + (state for state in device.states if state.name == "core:ClosureState"), + None, + ) + print(closure_state.value if closure_state else None) + + +asyncio.run(main()) +``` + +## Send a command + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import OverkizCommand, Server +from pyoverkiz.models import Action, Command + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + await client.execute_action_group( + actions=[ + Action( + device_url="io://1234-5678-1234/12345678", + commands=[ + Command( + name=OverkizCommand.SET_CLOSURE, + parameters=[50], + ) + ], + ) + ], + label="Set closure", + ) + + +asyncio.run(main()) +``` + +## Action groups and common patterns + +- Use a single action group to batch multiple device commands. +- Parameters vary by device. Many closure-style devices use 0–100. +- Thermostat-style devices commonly accept target temperatures. + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import OverkizCommand, Server +from pyoverkiz.models import Action, Command + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + await client.execute_action_group( + actions=[ + Action( + device_url="io://1234-5678-1234/12345678", + commands=[ + Command( + name=OverkizCommand.SET_TARGET_TEMPERATURE, + parameters=[21.5], + ) + ], + ) + ], + label="Set temperature", + ) + + +asyncio.run(main()) +``` + +## Polling vs event-driven + +Polling `get_devices()` is simple but can be slower. Event listeners provide faster updates; see the event handling guide for details. diff --git a/docs/error-handling.md b/docs/error-handling.md new file mode 100644 index 00000000..738e7b1d --- /dev/null +++ b/docs/error-handling.md @@ -0,0 +1,56 @@ +# Error handling + +## Common exceptions + +- `NotAuthenticatedException` +- `TooManyRequestsException` +- `TooManyConcurrentRequestsException` +- `TooManyExecutionsException` +- `MaintenanceException` +- `AccessDeniedToGatewayException` +- `BadCredentialsException` + +## Retry and backoff guidance + +Use short, jittered delays for transient errors and re-authenticate on auth failures. + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server +from pyoverkiz.exceptions import ( + NotAuthenticatedException, + TooManyConcurrentRequestsException, + TooManyRequestsException, +) + + +async def fetch_devices_with_retry() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + for attempt in range(5): + try: + devices = await client.get_devices() + print(devices) + return + except (TooManyRequestsException, TooManyConcurrentRequestsException): + await asyncio.sleep(0.5 * (attempt + 1)) + except NotAuthenticatedException: + await client.login() + + +asyncio.run(fetch_devices_with_retry()) +``` + +## SSL and local certificates + +If you use local gateways with `.local` hostnames, you may need `verify_ssl=False` when a trusted certificate is not available. + +## Timeouts + +For long-running operations, prefer shorter request timeouts with retries rather than a single long timeout. diff --git a/docs/event-handling.md b/docs/event-handling.md new file mode 100644 index 00000000..6bb359e4 --- /dev/null +++ b/docs/event-handling.md @@ -0,0 +1,101 @@ +# Event handling + +## Register and unregister a listener + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + await client.register_event_listener() + await client.unregister_event_listener() + + +asyncio.run(main()) +``` + +## Fetch events with backoff + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server +from pyoverkiz.exceptions import ( + InvalidEventListenerIdException, + NoRegisteredEventListenerException, +) + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + await client.register_event_listener() + + while True: + try: + events = await client.fetch_events() + except (InvalidEventListenerIdException, NoRegisteredEventListenerException): + await asyncio.sleep(1) + await client.register_event_listener() + continue + + for event in events: + print(event) + + await asyncio.sleep(2) + + +asyncio.run(main()) +``` + +## Update an in-memory state map + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + await client.register_event_listener() + + state_map: dict[str, dict[str, object]] = {} + + while True: + events = await client.fetch_events() + for event in events: + device_id = event.device_id + state_map.setdefault(device_id, {})[event.state_name] = event.state_value + + await asyncio.sleep(2) + + +asyncio.run(main()) +``` + +## Reconnect tips + +- Re-register the listener when you see `InvalidEventListenerIdException`. +- Poll occasionally if your network has unstable connectivity. +- Keep the fetch loop alive to avoid listener timeout. diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 00000000..d9966099 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,101 @@ +# Getting started + +## Prerequisites + +- Python 3.10–3.13 +- uv +- An OverKiz-compatible hub and account + +## Install dependencies + +```bash +uv sync +``` + +## Run the docs locally + +```bash +uv run mkdocs serve +``` + +Docs will be available at http://localhost:8000. + +```bash +uv run mkdocs build +``` + +## Choose your server + +Use a cloud server when you want to connect through the vendor’s public API. Use a local server when you want LAN access to a gateway. + +- Cloud servers use the `Server` enum. +- Local servers use `create_local_server_config` with a hostname or IP address. + +## First login (cloud) + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + print(await client.get_setup()) + + +asyncio.run(main()) +``` + +## First login (local) + +```python +import asyncio + +from pyoverkiz.auth.credentials import LocalTokenCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.utils import create_local_server_config + + +async def main() -> None: + async with OverkizClient( + server=create_local_server_config(host="gateway-xxxx.local"), + credentials=LocalTokenCredentials("local-token"), + verify_ssl=False, + ) as client: + await client.login() + print(await client.get_setup()) + + +asyncio.run(main()) +``` + +## Sanity check: list devices + +```python +import asyncio + +from pyoverkiz.auth.credentials import UsernamePasswordCredentials +from pyoverkiz.client import OverkizClient +from pyoverkiz.enums import Server + + +async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + devices = await client.get_devices() + for device in devices: + print(f"{device.label} ({device.id}) -> {device.widget}") + + +asyncio.run(main()) +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..b4194eff --- /dev/null +++ b/docs/index.md @@ -0,0 +1,16 @@ +# pyOverkiz + +pyOverkiz is an async Python client for the OverKiz platform, used by vendors like Somfy TaHoma and Atlantic Cozytouch. It lets you authenticate, discover devices, read states, execute commands, and consume gateway events. + +## What you can do + +- Connect to cloud or local gateways +- Discover devices and read states +- Send commands through action groups +- Consume event streams for near real-time updates + +## Where to go next + +- Start with the [Getting started](getting-started.md) guide +- Learn the architecture in [Core concepts](core-concepts.md) +- Browse the [API reference](api-reference.md) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 00000000..9f6411b6 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,41 @@ +# Troubleshooting + +## Cloud vs local connectivity + +- Cloud servers require internet access and valid vendor credentials. +- Local servers require direct access to the gateway on your LAN. + +## SSL and .local hostnames + +If the gateway uses a self-signed certificate, pass `verify_ssl=False` when creating `OverkizClient` for local access. + +## Authentication failures + +- Confirm the server matches your vendor region. +- Re-run `login()` and retry the call. +- For unsupported auth flows, switch to local token authentication. + +## Rate limits and concurrency + +- Reduce polling frequency. +- Back off on `TooManyRequestsException` or `TooManyConcurrentRequestsException`. + +## Listener drops + +- Re-register the event listener when you see `InvalidEventListenerIdException`. +- Ensure your fetch loop is running every few seconds. + +## Device not found + +- Refresh setup with `get_setup()` and re-fetch devices. +- Confirm you are using the correct gateway and server. + +## Logging tips + +Enable debug logging in your application to inspect request/response details. + +```python +import logging + +logging.basicConfig(level=logging.DEBUG) +``` diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..fb505958 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,39 @@ +site_name: pyOverkiz Documentation + +docs_dir: docs + +theme: + name: material + features: + - navigation.tabs + - toc.follow + - search.suggest + - search.highlight + +plugins: + - search + - autorefs + - mkdocstrings: + handlers: + python: + options: + show_source: true + docstring_style: google + +markdown_extensions: + - pymdownx.highlight + - pymdownx.superfences + - pymdownx.tasklist + +nav: + - Overview: index.md + - User Guide: + - Getting started: getting-started.md + - Authentication: authentication.md + - Core concepts: core-concepts.md + - Device control: device-control.md + - Event handling: event-handling.md + - Error handling: error-handling.md + - Troubleshooting: troubleshooting.md + - Contribute: contribute.md + - API Reference: api-reference.md diff --git a/pyproject.toml b/pyproject.toml index 2e74db8f..16d7ef30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,15 @@ dependencies = [ "warrant-lite<2.0.0,>=1.0.4", ] +[project.optional-dependencies] +docs = [ + "mkdocs>=1.5.0", + "mkdocs-material>=9.5.0", + "mkdocstrings[python]>=0.24.0", + "mkdocs-autorefs>=1.0.0", + "pymdown-extensions>=10.0", +] + [project.urls] homepage = "https://github.com/iMicknl/python-overkiz-api" repository = "https://github.com/iMicknl/python-overkiz-api" diff --git a/uv.lock b/uv.lock index 68bfe7d6..bdde6379 100644 --- a/uv.lock +++ b/uv.lock @@ -118,6 +118,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] +[[package]] +name = "babel" +version = "2.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, +] + [[package]] name = "backoff" version = "2.2.1" @@ -127,6 +136,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" }, ] +[[package]] +name = "backrefs" +version = "6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/e3/bb3a439d5cb255c4774724810ad8073830fac9c9dee123555820c1bcc806/backrefs-6.1.tar.gz", hash = "sha256:3bba1749aafe1db9b915f00e0dd166cba613b6f788ffd63060ac3485dc9be231", size = 7011962, upload-time = "2025-11-15T14:52:08.323Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ee/c216d52f58ea75b5e1841022bbae24438b19834a29b163cb32aa3a2a7c6e/backrefs-6.1-py310-none-any.whl", hash = "sha256:2a2ccb96302337ce61ee4717ceacfbf26ba4efb1d55af86564b8bbaeda39cac1", size = 381059, upload-time = "2025-11-15T14:51:59.758Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9a/8da246d988ded941da96c7ed945d63e94a445637eaad985a0ed88787cb89/backrefs-6.1-py311-none-any.whl", hash = "sha256:e82bba3875ee4430f4de4b6db19429a27275d95a5f3773c57e9e18abc23fd2b7", size = 392854, upload-time = "2025-11-15T14:52:01.194Z" }, + { url = "https://files.pythonhosted.org/packages/37/c9/fd117a6f9300c62bbc33bc337fd2b3c6bfe28b6e9701de336b52d7a797ad/backrefs-6.1-py312-none-any.whl", hash = "sha256:c64698c8d2269343d88947c0735cb4b78745bd3ba590e10313fbf3f78c34da5a", size = 398770, upload-time = "2025-11-15T14:52:02.584Z" }, + { url = "https://files.pythonhosted.org/packages/eb/95/7118e935b0b0bd3f94dfec2d852fd4e4f4f9757bdb49850519acd245cd3a/backrefs-6.1-py313-none-any.whl", hash = "sha256:4c9d3dc1e2e558965202c012304f33d4e0e477e1c103663fd2c3cc9bb18b0d05", size = 400726, upload-time = "2025-11-15T14:52:04.093Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/6296bad135bfafd3254ae3648cd152980a424bd6fed64a101af00cc7ba31/backrefs-6.1-py314-none-any.whl", hash = "sha256:13eafbc9ccd5222e9c1f0bec563e6d2a6d21514962f11e7fc79872fd56cbc853", size = 412584, upload-time = "2025-11-15T14:52:05.233Z" }, + { url = "https://files.pythonhosted.org/packages/02/e3/a4fa1946722c4c7b063cc25043a12d9ce9b4323777f89643be74cef2993c/backrefs-6.1-py39-none-any.whl", hash = "sha256:a9e99b8a4867852cad177a6430e31b0f6e495d65f8c6c134b68c14c3c95bf4b0", size = 381058, upload-time = "2025-11-15T14:52:06.698Z" }, +] + [[package]] name = "boto3" version = "1.42.24" @@ -239,6 +262,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" }, ] +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -450,6 +485,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, ] +[[package]] +name = "ghp-import" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, +] + +[[package]] +name = "griffe" +version = "1.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/0c/3a471b6e31951dce2360477420d0a8d1e00dea6cf33b70f3e8c3ab6e28e1/griffe-1.15.0.tar.gz", hash = "sha256:7726e3afd6f298fbc3696e67958803e7ac843c1cfe59734b6251a40cdbfb5eea", size = 424112, upload-time = "2025-11-10T15:03:15.52Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/83/3b1d03d36f224edded98e9affd0467630fc09d766c0e56fb1498cbb04a9b/griffe-1.15.0-py3-none-any.whl", hash = "sha256:6f6762661949411031f5fcda9593f586e6ce8340f0ba88921a0f2ef7a81eb9a3", size = 150705, upload-time = "2025-11-10T15:03:13.549Z" }, +] + [[package]] name = "idna" version = "3.11" @@ -468,6 +527,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + [[package]] name = "jmespath" version = "1.0.1" @@ -529,6 +600,206 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/51/0e/b756c7708143a63fca65a51ca07990fa647db2cc8fcd65177b9e96680255/librt-0.7.7-cp314-cp314t-win_arm64.whl", hash = "sha256:142c2cd91794b79fd0ce113bd658993b7ede0fe93057668c2f98a45ca00b7e91", size = 39724, upload-time = "2026-01-01T23:52:09.745Z" }, ] +[[package]] +name = "markdown" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ghp-import" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mergedeep" }, + { name = "mkdocs-get-deps" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, +] + +[[package]] +name = "mkdocs-autorefs" +version = "1.4.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/51/fa/9124cd63d822e2bcbea1450ae68cdc3faf3655c69b455f3a7ed36ce6c628/mkdocs_autorefs-1.4.3.tar.gz", hash = "sha256:beee715b254455c4aa93b6ef3c67579c399ca092259cc41b7d9342573ff1fc75", size = 55425, upload-time = "2025-08-26T14:23:17.223Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/4d/7123b6fa2278000688ebd338e2a06d16870aaf9eceae6ba047ea05f92df1/mkdocs_autorefs-1.4.3-py3-none-any.whl", hash = "sha256:469d85eb3114801d08e9cc55d102b3ba65917a869b893403b8987b601cf55dc9", size = 25034, upload-time = "2025-08-26T14:23:15.906Z" }, +] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mergedeep" }, + { name = "platformdirs" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239, upload-time = "2023-11-20T17:51:09.981Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, +] + +[[package]] +name = "mkdocs-material" +version = "9.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "backrefs" }, + { name = "colorama" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "mkdocs" }, + { name = "mkdocs-material-extensions" }, + { name = "paginate" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/e2/2ffc356cd72f1473d07c7719d82a8f2cbd261666828614ecb95b12169f41/mkdocs_material-9.7.1.tar.gz", hash = "sha256:89601b8f2c3e6c6ee0a918cc3566cb201d40bf37c3cd3c2067e26fadb8cce2b8", size = 4094392, upload-time = "2025-12-18T09:49:00.308Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/32/ed071cb721aca8c227718cffcf7bd539620e9799bbf2619e90c757bfd030/mkdocs_material-9.7.1-py3-none-any.whl", hash = "sha256:3f6100937d7d731f87f1e3e3b021c97f7239666b9ba1151ab476cabb96c60d5c", size = 9297166, upload-time = "2025-12-18T09:48:56.664Z" }, +] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, +] + +[[package]] +name = "mkdocstrings" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "pymdown-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e5/13/10bbf9d56565fd91b91e6f5a8cd9b9d8a2b101c4e8ad6eeafa35a706301d/mkdocstrings-1.0.0.tar.gz", hash = "sha256:351a006dbb27aefce241ade110d3cd040c1145b7a3eb5fd5ac23f03ed67f401a", size = 101086, upload-time = "2025-11-27T15:39:40.534Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/fc/80aa31b79133634721cf7855d37b76ea49773599214896f2ff10be03de2a/mkdocstrings-1.0.0-py3-none-any.whl", hash = "sha256:4c50eb960bff6e05dfc631f6bc00dfabffbcb29c5ff25f676d64daae05ed82fa", size = 35135, upload-time = "2025-11-27T15:39:39.301Z" }, +] + +[package.optional-dependencies] +python = [ + { name = "mkdocstrings-python" }, +] + +[[package]] +name = "mkdocstrings-python" +version = "2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "griffe" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocstrings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/24/75/d30af27a2906f00eb90143470272376d728521997800f5dce5b340ba35bc/mkdocstrings_python-2.0.1.tar.gz", hash = "sha256:843a562221e6a471fefdd4b45cc6c22d2607ccbad632879234fa9692e9cf7732", size = 199345, upload-time = "2025-12-03T14:26:11.755Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/06/c5f8deba7d2cbdfa7967a716ae801aa9ca5f734b8f54fd473ef77a088dbe/mkdocstrings_python-2.0.1-py3-none-any.whl", hash = "sha256:66ecff45c5f8b71bf174e11d49afc845c2dfc7fc0ab17a86b6b337e0f24d8d90", size = 105055, upload-time = "2025-12-03T14:26:10.184Z" }, +] + [[package]] name = "multidict" version = "6.7.0" @@ -679,6 +950,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] +[[package]] +name = "paginate" +version = "0.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, +] + [[package]] name = "pathspec" version = "1.0.2" @@ -841,6 +1121,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/11/a1938340ecb32d71e47ad4914843775011e6e9da59ba1229f181fef3119e/pyhumps-3.8.0-py3-none-any.whl", hash = "sha256:060e1954d9069f428232a1adda165db0b9d8dfdce1d265d36df7fbff540acfd6", size = 6095, upload-time = "2022-10-21T10:38:58.231Z" }, ] +[[package]] +name = "pymdown-extensions" +version = "10.20" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3e/35/e3814a5b7df295df69d035cfb8aab78b2967cdf11fcfae7faed726b66664/pymdown_extensions-10.20.tar.gz", hash = "sha256:5c73566ab0cf38c6ba084cb7c5ea64a119ae0500cce754ccb682761dfea13a52", size = 852774, upload-time = "2025-12-31T19:59:42.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/10/47caf89cbb52e5bb764696fd52a8c591a2f0e851a93270c05a17f36000b5/pymdown_extensions-10.20-py3-none-any.whl", hash = "sha256:ea9e62add865da80a271d00bfa1c0fa085b20d133fb3fc97afdc88e682f60b2f", size = 268733, upload-time = "2025-12-31T19:59:40.652Z" }, +] + [[package]] name = "pyoverkiz" version = "2.0.0" @@ -854,6 +1147,15 @@ dependencies = [ { name = "warrant-lite" }, ] +[package.optional-dependencies] +docs = [ + { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocs-material" }, + { name = "mkdocstrings", extra = ["python"] }, + { name = "pymdown-extensions" }, +] + [package.dev-dependencies] dev = [ { name = "mypy" }, @@ -872,9 +1174,15 @@ requires-dist = [ { name = "attrs", specifier = ">=21.2" }, { name = "backoff", specifier = ">=1.10.0,<3.0" }, { name = "boto3", specifier = ">=1.18.59,<2.0.0" }, + { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.5.0" }, + { name = "mkdocs-autorefs", marker = "extra == 'docs'", specifier = ">=1.0.0" }, + { name = "mkdocs-material", marker = "extra == 'docs'", specifier = ">=9.5.0" }, + { name = "mkdocstrings", extras = ["python"], marker = "extra == 'docs'", specifier = ">=0.24.0" }, { name = "pyhumps", specifier = ">=3.8.0,<4.0.0" }, + { name = "pymdown-extensions", marker = "extra == 'docs'", specifier = ">=10.0" }, { name = "warrant-lite", specifier = ">=1.0.4,<2.0.0" }, ] +provides-extras = ["docs"] [package.metadata.requires-dev] dev = [ @@ -969,6 +1277,64 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/c3/0bd11992072e6a1c513b16500a5d07f91a24017c5909b02c72c62d7ad024/python_jose-3.5.0-py2.py3-none-any.whl", hash = "sha256:abd1202f23d34dfad2c3d28cb8617b90acf34132c7afd60abd0b0b7d3cb55771", size = 34624, upload-time = "2025-05-28T17:31:52.802Z" }, ] +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "pyyaml-env-tag" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, +] + [[package]] name = "requests" version = "2.32.5" @@ -1134,6 +1500,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/04/e2deee7138370e27cb4f86cfe9e4230d3228b6a0804bd68e97e49483d465/warrant_lite-1.0.4-py3-none-any.whl", hash = "sha256:e5ea95dfee9d4f56398c3d8846fb9e16db1b0ad6395c59e1c5df5bf541f075b2", size = 10210, upload-time = "2019-05-21T13:50:30.487Z" }, ] +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + [[package]] name = "yarl" version = "1.22.0" From c3a1f46435c3b892b7a616dd208cd9851ede9dcd Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 17:17:31 +0000 Subject: [PATCH 03/17] Enhance documentation structure and configuration for mkdocs --- docs/index.md | 5 +++++ mkdocs.yml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docs/index.md b/docs/index.md index b4194eff..854abfee 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,8 @@ +--- +hide: + - navigation + - toc +--- # pyOverkiz pyOverkiz is an async Python client for the OverKiz platform, used by vendors like Somfy TaHoma and Atlantic Cozytouch. It lets you authenticate, discover devices, read states, execute commands, and consume gateway events. diff --git a/mkdocs.yml b/mkdocs.yml index fb505958..2500ca2d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,6 @@ site_name: pyOverkiz Documentation +repo_url: https://github.com/iMicknl/python-overkiz-api +edit_uri: edit/main/docs/ docs_dir: docs @@ -19,6 +21,9 @@ plugins: options: show_source: true docstring_style: google + show_signature: true + show_signature_annotations: true + signature_crossrefs: true markdown_extensions: - pymdownx.highlight From d01027cc7954fa2e618ca9b8a84dfd6329ceeb4b Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 20:42:57 +0000 Subject: [PATCH 04/17] Update documentation: enhance contribute and getting started sections --- docs/contribute.md | 12 ++++++++++++ docs/getting-started.md | 24 ++++++++++++------------ mkdocs.yml | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/docs/contribute.md b/docs/contribute.md index acb0cfb3..9914a247 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -14,6 +14,18 @@ Install git hooks: uv run prek install ``` +## Run the docs locally + +```bash +uv run mkdocs serve +``` + +Docs will be available at http://localhost:8000. + +```bash +uv run mkdocs build +``` + ## Tests and linting ```bash diff --git a/docs/getting-started.md b/docs/getting-started.md index d9966099..d0526e02 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,26 +2,19 @@ ## Prerequisites -- Python 3.10–3.13 -- uv +- Python 3.10+ - An OverKiz-compatible hub and account -## Install dependencies +## Install pyOverkiz from PyPi ```bash -uv sync +pip install pyoverkiz ``` -## Run the docs locally +If you use uv: ```bash -uv run mkdocs serve -``` - -Docs will be available at http://localhost:8000. - -```bash -uv run mkdocs build +uv add pyoverkiz ``` ## Choose your server @@ -98,4 +91,11 @@ async def main() -> None: asyncio.run(main()) + +## Next steps + +- Learn about authentication flows in [docs/authentication.md](docs/authentication.md). +- Control devices and run actions in [docs/device-control.md](docs/device-control.md). +- Handle events in [docs/event-handling.md](docs/event-handling.md). +- Understand errors in [docs/error-handling.md](docs/error-handling.md). ``` diff --git a/mkdocs.yml b/mkdocs.yml index 2500ca2d..570415c6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -40,5 +40,5 @@ nav: - Event handling: event-handling.md - Error handling: error-handling.md - Troubleshooting: troubleshooting.md - - Contribute: contribute.md - API Reference: api-reference.md + - Contribute: contribute.md From 06817fc4785bca6d2a4694b2cc0a58ea9236be17 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 20:57:44 +0000 Subject: [PATCH 05/17] Update GitHub Actions workflow for documentation deployment and enhance contribution guidelines --- .github/workflows/docs.yml | 41 ++++++++++++++++++++++++++++---------- docs/contribute.md | 2 +- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 81d77b6e..799f3697 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,16 +1,21 @@ name: docs on: - push: - branches: - - main - - v2/docs + release: + types: + - created + pull_request: + paths: + - docs/** + - mkdocs.yml + - pyproject.toml + - README.md permissions: - contents: write + contents: read jobs: - build-and-deploy: + build: runs-on: ubuntu-latest steps: - name: Checkout @@ -25,13 +30,27 @@ jobs: uses: astral-sh/setup-uv@v3 - name: Install docs dependencies - run: uv pip install -e ".[docs]" + run: uv sync --all-extras --dev - name: Build site run: uv run mkdocs build - - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v4 + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: site + path: site + + deploy: + if: github.event_name == 'release' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/docs/contribute.md b/docs/contribute.md index 9914a247..d3b6e126 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -38,7 +38,7 @@ uv run prek run --all-files ## Project guidelines -- Use Python 3.10–3.13 features and type annotations. +- Use Python 3.10+ features and type annotations. - Keep absolute imports and avoid relative imports. - Preserve existing comments and logging unless your change requires updates. - Prefer small, focused changes and add tests when behavior changes. From baf3d1260f4d2cbb2e06a15812536df9cc1501f7 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 21:01:00 +0000 Subject: [PATCH 06/17] Update index.md: refine description and enhance supported hubs section --- docs/index.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 854abfee..84e08fbc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,15 +5,31 @@ hide: --- # pyOverkiz -pyOverkiz is an async Python client for the OverKiz platform, used by vendors like Somfy TaHoma and Atlantic Cozytouch. It lets you authenticate, discover devices, read states, execute commands, and consume gateway events. +pyOverkiz is an async Python client for the OverKiz platform, used by vendors like Somfy and Atlantic. It lets you authenticate, discover devices, read states, execute commands, and consume gateway events. ## What you can do - Connect to cloud or local gateways - Discover devices and read states -- Send commands through action groups +- Send commands to your devices - Consume event streams for near real-time updates +## Supported hubs + +- Atlantic Cozytouch +- Bouygues Flexom + +- Hitachi Hi Kumo +- Nexity Eugénie + +- Sauter Cozytouch +- Simu (LiveIn2) +- Somfy Connexoon IO +- Somfy Connexoon RTS +- Somfy TaHoma +- Somfy TaHoma Switch +- Thermor Cozytouch + ## Where to go next - Start with the [Getting started](getting-started.md) guide From 6602304439ff49c371f5f3f2c4ee3c009a49aacc Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 21:08:13 +0000 Subject: [PATCH 07/17] Update mkdocs.yml: add extra configuration for generator --- mkdocs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index 570415c6..1f1011b0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -4,6 +4,9 @@ edit_uri: edit/main/docs/ docs_dir: docs +extra: + generator: false + theme: name: material features: From 0fc83993be1e52c0be6a25ffa3224651221b8e9b Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 22:35:57 +0000 Subject: [PATCH 08/17] Update documentation: refine installation instructions and enhance project description --- docs/getting-started.md | 9 ++++++--- docs/index.md | 22 +++++++++------------- mkdocs.yml | 3 +++ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index d0526e02..9cf19fad 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -7,14 +7,17 @@ ## Install pyOverkiz from PyPi + +### With UV recommended { #with-uv data-toc-label="with uv" } + ```bash -pip install pyoverkiz +uv add pyoverkiz ``` -If you use uv: +### With pip ```bash -uv add pyoverkiz +pip install pyoverkiz ``` ## Choose your server diff --git a/docs/index.md b/docs/index.md index 84e08fbc..7af1b992 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,26 +2,26 @@ hide: - navigation - toc + - title --- # pyOverkiz -pyOverkiz is an async Python client for the OverKiz platform, used by vendors like Somfy and Atlantic. It lets you authenticate, discover devices, read states, execute commands, and consume gateway events. +pyOverkiz is an async Python library for interacting with Overkiz-based platforms, including Somfy and Atlantic. It enables authentication, device discovery, state reading, command execution, and real-time event streaming from supported gateways. ## What you can do -- Connect to cloud or local gateways -- Discover devices and read states -- Send commands to your devices -- Consume event streams for near real-time updates +- Authenticate with Overkiz cloud or local gateways +- Automatically discover and list connected devices +- Read device states and attributes +- Execute commands on devices +- Receive real-time updates via event streams ## Supported hubs - Atlantic Cozytouch - Bouygues Flexom - - Hitachi Hi Kumo - Nexity Eugénie - - Sauter Cozytouch - Simu (LiveIn2) - Somfy Connexoon IO @@ -29,9 +29,5 @@ pyOverkiz is an async Python client for the OverKiz platform, used by vendors li - Somfy TaHoma - Somfy TaHoma Switch - Thermor Cozytouch - -## Where to go next - -- Start with the [Getting started](getting-started.md) guide -- Learn the architecture in [Core concepts](core-concepts.md) -- Browse the [API reference](api-reference.md) + + diff --git a/mkdocs.yml b/mkdocs.yml index 1f1011b0..5a6ea6ee 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,7 @@ repo_url: https://github.com/iMicknl/python-overkiz-api edit_uri: edit/main/docs/ docs_dir: docs +copyright: This project is not affiliated with Overkiz, Somfy, or any other mentioned brand. All trademarks and brand names are the property of their respective owners. extra: generator: false @@ -14,6 +15,7 @@ theme: - toc.follow - search.suggest - search.highlight + - navigation.footer plugins: - search @@ -32,6 +34,7 @@ markdown_extensions: - pymdownx.highlight - pymdownx.superfences - pymdownx.tasklist + - admonition nav: - Overview: index.md From 20eb40a3ac1730321ff843ec0b4a31eba9812b03 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sun, 18 Jan 2026 23:00:11 +0000 Subject: [PATCH 09/17] Update documentation: remove outdated authentication guide and enhance getting started section --- docs/authentication.md | 64 --------------------- docs/getting-started.md | 123 ++++++++++++++++++++++------------------ docs/index.md | 6 +- mkdocs.yml | 4 +- 4 files changed, 75 insertions(+), 122 deletions(-) delete mode 100644 docs/authentication.md diff --git a/docs/authentication.md b/docs/authentication.md deleted file mode 100644 index 1551be49..00000000 --- a/docs/authentication.md +++ /dev/null @@ -1,64 +0,0 @@ -# Authentication - -## Cloud username and password - -Cloud authentication uses a vendor server from `Server` plus `UsernamePasswordCredentials`. - -```python -import asyncio - -from pyoverkiz.auth.credentials import UsernamePasswordCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.enums import Server - - -async def main() -> None: - async with OverkizClient( - server=Server.SOMFY_EUROPE, - credentials=UsernamePasswordCredentials("you@example.com", "password"), - ) as client: - await client.login() - print(await client.get_api_version()) - - -asyncio.run(main()) -``` - -## Local token authentication - -Local authentication requires a token generated by the official mobile app and a local user on the OverKiz API platform. - -```python -import asyncio - -from pyoverkiz.auth.credentials import LocalTokenCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.utils import create_local_server_config - - -async def main() -> None: - async with OverkizClient( - server=create_local_server_config(host="gateway-xxxx.local"), - credentials=LocalTokenCredentials("local-token"), - verify_ssl=False, - ) as client: - await client.login() - print(await client.get_api_version()) - - -asyncio.run(main()) -``` - -## Token refresh behavior - -The client refreshes access tokens as needed during authenticated calls. If you see authentication errors, re-run `login()` before retrying the request. - -## Unsupported auth flows - -Some vendors use authentication flows that are not supported. In those cases, obtain a local token and use a local server configuration instead. - -## Secure storage tips - -- Use environment variables or a secret manager for tokens. -- Avoid hard-coding credentials in source control. -- Rotate tokens regularly if your vendor supports it. diff --git a/docs/getting-started.md b/docs/getting-started.md index 9cf19fad..6370dbb8 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,14 +1,15 @@ # Getting started +This guide will help you install the library, connect to your hub, and perform your first actions. + ## Prerequisites - Python 3.10+ - An OverKiz-compatible hub and account -## Install pyOverkiz from PyPi - +## Install pyOverkiz from PyPI -### With UV recommended { #with-uv data-toc-label="with uv" } +### With UV recommended ```bash uv add pyoverkiz @@ -27,78 +28,88 @@ Use a cloud server when you want to connect through the vendor’s public API. U - Cloud servers use the `Server` enum. - Local servers use `create_local_server_config` with a hostname or IP address. -## First login (cloud) +## Authentication -```python -import asyncio +=== "Somfy (cloud)" -from pyoverkiz.auth.credentials import UsernamePasswordCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.enums import Server + Cloud authentication uses a vendor server from `Server` plus `UsernamePasswordCredentials`. + ```python + import asyncio -async def main() -> None: - async with OverkizClient( - server=Server.SOMFY_EUROPE, - credentials=UsernamePasswordCredentials("you@example.com", "password"), - ) as client: - await client.login() - print(await client.get_setup()) + from pyoverkiz.auth.credentials import UsernamePasswordCredentials + from pyoverkiz.client import OverkizClient + from pyoverkiz.enums import Server -asyncio.run(main()) -``` + async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() -## First login (local) + asyncio.run(main()) + ``` -```python -import asyncio +=== "Somfy (local)" -from pyoverkiz.auth.credentials import LocalTokenCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.utils import create_local_server_config + Local authentication requires a token generated by the official mobile app and a local user on the OverKiz API platform. + ```python + import asyncio -async def main() -> None: - async with OverkizClient( - server=create_local_server_config(host="gateway-xxxx.local"), - credentials=LocalTokenCredentials("local-token"), - verify_ssl=False, - ) as client: - await client.login() - print(await client.get_setup()) + from pyoverkiz.auth.credentials import LocalTokenCredentials + from pyoverkiz.client import OverkizClient + from pyoverkiz.utils import create_local_server_config -asyncio.run(main()) -``` + async def main() -> None: + async with OverkizClient( + server=create_local_server_config(host="gateway-xxxx.local"), + credentials=LocalTokenCredentials("local-token"), + verify_ssl=True, # disable if you connect via IP + ) as client: + await client.login() -## Sanity check: list devices + asyncio.run(main()) + ``` -```python -import asyncio +=== "Cozytouch (cloud)" -from pyoverkiz.auth.credentials import UsernamePasswordCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.enums import Server + ```python + import asyncio + from pyoverkiz.auth.credentials import UsernamePasswordCredentials + from pyoverkiz.client import OverkizClient + from pyoverkiz.enums import Server -async def main() -> None: - async with OverkizClient( - server=Server.SOMFY_EUROPE, - credentials=UsernamePasswordCredentials("you@example.com", "password"), - ) as client: - await client.login() - devices = await client.get_devices() - for device in devices: - print(f"{device.label} ({device.id}) -> {device.widget}") + async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() -asyncio.run(main()) + asyncio.run(main()) + ``` -## Next steps +=== "Rexel (cloud)" -- Learn about authentication flows in [docs/authentication.md](docs/authentication.md). -- Control devices and run actions in [docs/device-control.md](docs/device-control.md). -- Handle events in [docs/event-handling.md](docs/event-handling.md). -- Understand errors in [docs/error-handling.md](docs/error-handling.md). -``` + ```python + import asyncio + + from pyoverkiz.auth.credentials import UsernamePasswordCredentials + from pyoverkiz.client import OverkizClient + from pyoverkiz.enums import Server + + async def main() -> None: + async with OverkizClient( + server=Server.SOMFY_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + + asyncio.run(main()) + ``` diff --git a/docs/index.md b/docs/index.md index 7af1b992..d07f685f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,7 +4,11 @@ hide: - toc - title --- -# pyOverkiz + pyOverkiz is an async Python library for interacting with Overkiz-based platforms, including Somfy and Atlantic. It enables authentication, device discovery, state reading, command execution, and real-time event streaming from supported gateways. diff --git a/mkdocs.yml b/mkdocs.yml index 5a6ea6ee..faa5fca9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,12 +35,14 @@ markdown_extensions: - pymdownx.superfences - pymdownx.tasklist - admonition + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true nav: - Overview: index.md - User Guide: - Getting started: getting-started.md - - Authentication: authentication.md - Core concepts: core-concepts.md - Device control: device-control.md - Event handling: event-handling.md From 90cfe36ee3be358e64a544fc42f015cdb64e2f0c Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 15:20:59 +0000 Subject: [PATCH 10/17] Add VSCode tasks --- .pre-commit-config.yaml | 2 +- .vscode/tasks.json | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .vscode/tasks.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a5753900..3472c55a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - id: check-json - exclude: .devcontainer + exclude: .devcontainer|.vscode - id: check-yaml - id: check-added-large-files - id: no-commit-to-branch diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..fcb02265 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Docs: Serve (development)", + "type": "shell", + "command": "uv run mkdocs serve" + }, + { + "label": "Docs: Build", + "type": "shell", + "command": "uv run mkdocs build --clean" + }, + ] +} From 6de13db0b6811a261ebe847508ef5ce3f52f43a5 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 15:43:24 +0000 Subject: [PATCH 11/17] Improve docs --- docs/contribute.md | 4 ++-- docs/getting-started.md | 46 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/docs/contribute.md b/docs/contribute.md index d3b6e126..41b3d79a 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -45,6 +45,6 @@ uv run prek run --all-files ## Submitting changes -1. Create a feature branch. -2. Run linting and tests. +1. Fork the repository and create a new feature branch for your changes. +2. Ensure all linting and tests pass locally before submitting. 3. Open a pull request with a clear description and context. diff --git a/docs/getting-started.md b/docs/getting-started.md index 6370dbb8..962f0fe3 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -32,7 +32,9 @@ Use a cloud server when you want to connect through the vendor’s public API. U === "Somfy (cloud)" - Cloud authentication uses a vendor server from `Server` plus `UsernamePasswordCredentials`. + Authentication to the Somfy cloud requires your mobile app username and password and your region. + + Use `Server.SOMFY_EUROPE`, `Server.SOMFY_AMERICA`, or `Server.SOMFY_OCEANIA` with `UsernamePasswordCredentials` to select your region and authenticate. ```python import asyncio @@ -54,7 +56,9 @@ Use a cloud server when you want to connect through the vendor’s public API. U === "Somfy (local)" - Local authentication requires a token generated by the official mobile app and a local user on the OverKiz API platform. + Local authentication requires a token generated via the official mobile app. For details on obtaining a token, refer to [Somfy TaHoma Developer Mode](https://github.com/Somfy-Developer/Somfy-TaHoma-Developer-Mode). + + Use the helper function `create_local_server_config` to create a `Server` with `LocalTokenCredentials` to provide your token. ```python import asyncio @@ -66,8 +70,8 @@ Use a cloud server when you want to connect through the vendor’s public API. U async def main() -> None: async with OverkizClient( - server=create_local_server_config(host="gateway-xxxx.local"), - credentials=LocalTokenCredentials("local-token"), + server=create_local_server_config(host="gateway-xxxx-xxxx-xxxx.local"), + credentials=LocalTokenCredentials("token-from-your-mobile-app"), verify_ssl=True, # disable if you connect via IP ) as client: await client.login() @@ -77,6 +81,10 @@ Use a cloud server when you want to connect through the vendor’s public API. U === "Cozytouch (cloud)" + Authentication to the Cozytouch cloud requires your mobile app username and password and your vendor. + + Use `Server.ATLANTIC_COZYTOUCH`, `Server.SAUTER_COZYTOUCH`, or `Server.THERMOR_COZYTOUCH` with `UsernamePasswordCredentials` to select your vendor and authenticate. + ```python import asyncio @@ -95,8 +103,36 @@ Use a cloud server when you want to connect through the vendor’s public API. U asyncio.run(main()) ``` +=== "Hitachi Hi Kumo (cloud)" + + Authentication to the Hitachi Hi Kumo cloud requires your mobile app username and password and your region. + + Use `Server.HI_KUMO_ASIA`, `Server.HI_KUMO_EUROPE`, or `Server.HI_KUMO_OCEANIA` with `UsernamePasswordCredentials` to select your region and authenticate. + + ```python + import asyncio + + from pyoverkiz.auth.credentials import UsernamePasswordCredentials + from pyoverkiz.client import OverkizClient + from pyoverkiz.enums import Server + + + async def main() -> None: + async with OverkizClient( + server=Server.HI_KUMO_EUROPE, + credentials=UsernamePasswordCredentials("you@example.com", "password"), + ) as client: + await client.login() + + asyncio.run(main()) + ``` + === "Rexel (cloud)" + Authentication to the Rexel cloud requires your mobile app username and password. + + Use `Server.REXEL` with `UsernamePasswordCredentials` to authenticate. + ```python import asyncio @@ -106,7 +142,7 @@ Use a cloud server when you want to connect through the vendor’s public API. U async def main() -> None: async with OverkizClient( - server=Server.SOMFY_EUROPE, + server=Server.REXEL, credentials=UsernamePasswordCredentials("you@example.com", "password"), ) as client: await client.login() From fbc3eb445854b8b23cba98146d3d3316e515a07d Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 15:47:55 +0000 Subject: [PATCH 12/17] Update troubleshooting documentation: remove note on unsupported auth flows --- docs/troubleshooting.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 9f6411b6..4508af6c 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -13,7 +13,6 @@ If the gateway uses a self-signed certificate, pass `verify_ssl=False` when crea - Confirm the server matches your vendor region. - Re-run `login()` and retry the call. -- For unsupported auth flows, switch to local token authentication. ## Rate limits and concurrency From f476c19baa02c5a9cabecfe3f28914adb4e96fa0 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 16:05:41 +0000 Subject: [PATCH 13/17] Refactor device control examples: streamline code and enhance clarity --- docs/device-control.md | 143 ++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 93 deletions(-) diff --git a/docs/device-control.md b/docs/device-control.md index d96796af..372e13b5 100644 --- a/docs/device-control.md +++ b/docs/device-control.md @@ -1,133 +1,90 @@ # Device control +All examples assume you are authenticated and have an active session. For details on setting up authentication, see the [Getting Started](getting-started) guide. + ## List devices ```python -import asyncio - -from pyoverkiz.auth.credentials import UsernamePasswordCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.enums import Server - - -async def main() -> None: - async with OverkizClient( - server=Server.SOMFY_EUROPE, - credentials=UsernamePasswordCredentials("you@example.com", "password"), - ) as client: - await client.login() - devices = await client.get_devices() - for device in devices: - print(device.label, device.controllable_name) +devices = await client.get_devices() +for device in devices: + print(device.label, device.controllable_name) -asyncio.run(main()) + # Access device metadata, including available commands, states, and identifiers: + print(device.definition) ``` ## Read a state value ```python -import asyncio - -from pyoverkiz.auth.credentials import UsernamePasswordCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.enums import Server - - -async def main() -> None: - async with OverkizClient( - server=Server.SOMFY_EUROPE, - credentials=UsernamePasswordCredentials("you@example.com", "password"), - ) as client: - await client.login() - devices = await client.get_devices() - device = devices[0] - closure_state = next( - (state for state in device.states if state.name == "core:ClosureState"), - None, - ) - print(closure_state.value if closure_state else None) +devices = await client.get_devices() +for device in devices: + print(device.label, device.controllable_name) -asyncio.run(main()) +device = devices[0] +closure_state = next( + (state for state in device.states if state.name == "core:ClosureState"), + None, +) +print(closure_state.value if closure_state else None) ``` ## Send a command ```python -import asyncio - -from pyoverkiz.auth.credentials import UsernamePasswordCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.enums import OverkizCommand, Server +from pyoverkiz.enums import OverkizCommand from pyoverkiz.models import Action, Command - -async def main() -> None: - async with OverkizClient( - server=Server.SOMFY_EUROPE, - credentials=UsernamePasswordCredentials("you@example.com", "password"), - ) as client: - await client.login() - await client.execute_action_group( - actions=[ - Action( - device_url="io://1234-5678-1234/12345678", - commands=[ - Command( - name=OverkizCommand.SET_CLOSURE, - parameters=[50], - ) - ], +await client.execute_action_group( + actions=[ + Action( + device_url="io://1234-5678-1234/12345678", + commands=[ + Command( + name=OverkizCommand.SET_CLOSURE, + parameters=[50], ) ], - label="Set closure", ) - - -asyncio.run(main()) + ], + label="Execution: set closure", +) ``` ## Action groups and common patterns - Use a single action group to batch multiple device commands. -- Parameters vary by device. Many closure-style devices use 0–100. -- Thermostat-style devices commonly accept target temperatures. ```python -import asyncio - -from pyoverkiz.auth.credentials import UsernamePasswordCredentials -from pyoverkiz.client import OverkizClient -from pyoverkiz.enums import OverkizCommand, Server +from pyoverkiz.enums import OverkizCommand from pyoverkiz.models import Action, Command - -async def main() -> None: - async with OverkizClient( - server=Server.SOMFY_EUROPE, - credentials=UsernamePasswordCredentials("you@example.com", "password"), - ) as client: - await client.login() - await client.execute_action_group( - actions=[ - Action( - device_url="io://1234-5678-1234/12345678", - commands=[ - Command( - name=OverkizCommand.SET_TARGET_TEMPERATURE, - parameters=[21.5], - ) - ], +await client.execute_action_group( + actions=[ + Action( + device_url="io://1234-5678-1234/12345678", + commands=[ + Command( + name=OverkizCommand.SET_DEROGATION, + parameters=[21.5, OverkizCommandParam.FURTHER_NOTICE], + ) + ], + ), + Action( + device_url="io://1234-5678-1234/12345678", + commands=[ + Command( + name=OverkizCommand.SET_MODE_TEMPERATURE, + parameters=[OverkizCommandParam.MANUAL_MODE, 21.5], ) ], - label="Set temperature", ) - - -asyncio.run(main()) + ], + label="Execution: multiple commands", +) ``` ## Polling vs event-driven -Polling `get_devices()` is simple but can be slower. Event listeners provide faster updates; see the event handling guide for details. +Polling with `get_devices()` is straightforward but may introduce latency and increase server load. For more immediate updates, consider using event listeners. Refer to the [event handling](event-handling.md) guide for implementation details. From 381763343a210c52560ff45e2b990ce792769670 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 16:08:09 +0000 Subject: [PATCH 14/17] Improve docs --- docs/device-control.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/device-control.md b/docs/device-control.md index 372e13b5..dbb87a8f 100644 --- a/docs/device-control.md +++ b/docs/device-control.md @@ -17,17 +17,19 @@ for device in devices: ## Read a state value ```python -devices = await client.get_devices() +from pyoverkiz.enums import OverkizState -for device in devices: - print(device.label, device.controllable_name) +devices = await client.get_devices() +# For demo purposes we take the first availalbe device device = devices[0] -closure_state = next( - (state for state in device.states if state.name == "core:ClosureState"), + +availability_state = next( + (state for state in device.states if state.name == OverkizState.CORE_AVAILABILITY), None, ) -print(closure_state.value if closure_state else None) + +print(availability_state.value if availability_state else None) ``` ## Send a command From a4efaddb8c384f465f9bcf627c99c05a203f24cb Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 16:08:57 +0000 Subject: [PATCH 15/17] Fix URL --- docs/device-control.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/device-control.md b/docs/device-control.md index dbb87a8f..c9747b32 100644 --- a/docs/device-control.md +++ b/docs/device-control.md @@ -1,6 +1,6 @@ # Device control -All examples assume you are authenticated and have an active session. For details on setting up authentication, see the [Getting Started](getting-started) guide. +All examples assume you are authenticated and have an active session. For details on setting up authentication, see the [Getting Started](getting-started.md) guide. ## List devices From e7aa4d997bf6f3d33e0c49aed8478e5f71394e02 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 16:16:59 +0000 Subject: [PATCH 16/17] Enhance mkdocs configuration: enable display of docstring attributes --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index faa5fca9..28c5d6f0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -26,6 +26,7 @@ plugins: options: show_source: true docstring_style: google + show_docstring_attributes: true show_signature: true show_signature_annotations: true signature_crossrefs: true From ff82257cba192dfe0b1f628a5658c44efc370c54 Mon Sep 17 00:00:00 2001 From: Mick Vleeshouwer Date: Sat, 24 Jan 2026 16:18:29 +0000 Subject: [PATCH 17/17] Fix typo in device control documentation --- docs/device-control.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/device-control.md b/docs/device-control.md index c9747b32..d1bf7757 100644 --- a/docs/device-control.md +++ b/docs/device-control.md @@ -21,7 +21,7 @@ from pyoverkiz.enums import OverkizState devices = await client.get_devices() -# For demo purposes we take the first availalbe device +# For demo purposes we take the first available device device = devices[0] availability_state = next(