Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HmIP-WGC #449

Merged
merged 1 commit into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions homematicip/aio/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,3 +585,9 @@ class AsyncRainSensor(RainSensor, AsyncDevice):

class AsyncTemperaturDifferenceSensor2(TemperaturDifferenceSensor2, AsyncDevice):
""" HmIP-STE2-PCB (Temperature Difference Sensors - 2x sensors) """

class AsyncWallMountedGarageDoorController(WallMountedGarageDoorController, AsyncDevice):
""" HmIP-WGC (Garage Door Controller) """

async def send_start_impulse(self):
return await self._connection.api_call(*super().send_start_impulse())
2 changes: 2 additions & 0 deletions homematicip/base/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ class DeviceType(AutoNameEnum):
TORMATIC_MODULE = auto()
WALL_MOUNTED_THERMOSTAT_BASIC_HUMIDITY = auto()
WALL_MOUNTED_THERMOSTAT_PRO = auto()
WALL_MOUNTED_GARAGE_DOOR_CONTROLLER = auto()
WATER_SENSOR = auto()
WEATHER_SENSOR = auto()
WEATHER_SENSOR_PLUS = auto()
Expand Down Expand Up @@ -421,6 +422,7 @@ class FunctionalChannelType(AutoNameEnum):
HEAT_DEMAND_CHANNEL = auto()
HEATING_THERMOSTAT_CHANNEL = auto()
INTERNAL_SWITCH_CHANNEL = auto()
IMPULSE_OUTPUT_CHANNEL = auto()
LIGHT_SENSOR_CHANNEL = auto()
MAINS_FAILURE_CHANNEL = auto()
MOTION_DETECTION_CHANNEL = auto()
Expand Down
11 changes: 11 additions & 0 deletions homematicip/base/functionalChannels.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,17 @@ def from_json(self, js, groups: Iterable[Group]):
self.valveProtectionDuration = js["valveProtectionDuration"]
self.valveProtectionSwitchingInterval = js["valveProtectionSwitchingInterval"]

class ImpulseOutputChannel(FunctionalChannel):
""" this is the representation of the IMPULSE_OUTPUT_CHANNEL """

def __init__(self):
super().__init__()

def from_json(self, js, groups: Iterable[Group]):
super().from_json(js, groups)
self.impulseDuration = js["impulseDuration"]
self.processing = js["processing"]


class MultiModeInputChannel(FunctionalChannel):
""" this is the representative of the MULTI_MODE_INPUT_CHANNEL channel"""
Expand Down
2 changes: 2 additions & 0 deletions homematicip/class_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
DeviceType.TEMPERATURE_SENSOR_2_EXTERNAL_DELTA: TemperaturDifferenceSensor2,
DeviceType.TILT_VIBRATION_SENSOR: TiltVibrationSensor,
DeviceType.TORMATIC_MODULE: GarageDoorModuleTormatic,
DeviceType.WALL_MOUNTED_GARAGE_DOOR_CONTROLLER: WallMountedGarageDoorController,
DeviceType.WALL_MOUNTED_THERMOSTAT_PRO: WallMountedThermostatPro,
DeviceType.WALL_MOUNTED_THERMOSTAT_BASIC_HUMIDITY: WallMountedThermostatBasicHumidity,
DeviceType.WATER_SENSOR: WaterSensor,
Expand Down Expand Up @@ -174,6 +175,7 @@
FunctionalChannelType.HEAT_DEMAND_CHANNEL: HeatDemandChannel,
FunctionalChannelType.HEATING_THERMOSTAT_CHANNEL: HeatingThermostatChannel,
FunctionalChannelType.INTERNAL_SWITCH_CHANNEL: InternalSwitchChannel,
FunctionalChannelType.IMPULSE_OUTPUT_CHANNEL: ImpulseOutputChannel,
FunctionalChannelType.LIGHT_SENSOR_CHANNEL: LightSensorChannel,
FunctionalChannelType.MAINS_FAILURE_CHANNEL: MainsFailureChannel,
FunctionalChannelType.MOTION_DETECTION_CHANNEL: MotionDetectionChannel,
Expand Down
23 changes: 23 additions & 0 deletions homematicip/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,29 @@ def from_json(self, js):
self.set_attr_from_dict("genericAlarmSignal", c, AlarmSignalType)


class WallMountedGarageDoorController(Device):
""" HmIP-WGC Wall mounted Garage Door Controller """

def __init__(self, connection):
super().__init__(connection)
self.impulseDuration = 0
self.processing = False

def from_json(self, js):
super().from_json(js)
c = get_functional_channel("IMPULSE_OUTPUT_CHANNEL", js)
if c:
self.set_attr_from_dict("impulseDuration", c)
self.set_attr_from_dict("processing", c)

def send_start_impulse(self, channelIndex = 2):
""" Toggle Wall mounted Garage Door Controller. """
data = {
"channelIndex": channelIndex,
"deviceId": self.id
}
return self._restCall("device/control/startImpulse", body=json.dumps(data))

class TiltVibrationSensor(Device):
""" HMIP-STV (Inclination and vibration Sensor) """

Expand Down
7 changes: 7 additions & 0 deletions homematicip_demo/fake_cloud_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,13 @@ async def post_hmip_group_switching_stop(
response = web.json_response(None)
return response

@validate_authorization
async def post_hmip_device_control_startImpulse(
self, request: web.Request
) -> web.Response:
response = web.json_response(None)
return response

@validate_authorization
async def post_hmip_group_heating_setSetPointTemperature(
self, request: web.Request
Expand Down
203 changes: 203 additions & 0 deletions homematicip_demo/json_data/home.json
Original file line number Diff line number Diff line change
Expand Up @@ -7294,6 +7294,209 @@
"serializedGlobalTradeItemNumber": "3014F7110000000000056775",
"type": "FULL_FLUSH_CONTACT_INTERFACE_6",
"updateState": "UP_TO_DATE"
},
"3014F7110000000000STE2015": {
"availableFirmwareVersion": "1.0.26",
"connectionType": "HMIP_RF",
"firmwareVersion": "1.0.18",
"firmwareVersionInteger": 65554,
"functionalChannels": {
"0": {
"busConfigMismatch": null,
"coProFaulty": false,
"coProRestartNeeded": false,
"coProUpdateFailure": false,
"configPending": false,
"deviceId": "3014F7110000000000STE2015",
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"displayContrast": null,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": [
"00000000-0000-0000-0000-000000000024"
],
"index": 0,
"label": "",
"lockJammed": null,
"lowBat": false,
"mountingOrientation": null,
"multicastRoutingEnabled": false,
"particulateMatterSensorCommunicationError": null,
"particulateMatterSensorError": null,
"powerShortCircuit": null,
"profilePeriodLimitReached": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -60,
"rssiPeerValue": null,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceIdentify": false,
"IFeatureDeviceOverheated": false,
"IFeatureDeviceOverloaded": false,
"IFeatureDeviceParticulateMatterSensorCommunicationError": false,
"IFeatureDeviceParticulateMatterSensorError": false,
"IFeatureDevicePowerFailure": false,
"IFeatureDeviceTemperatureHumiditySensorCommunicationError": false,
"IFeatureDeviceTemperatureHumiditySensorError": false,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": false,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureProfilePeriodLimit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDeviceErrorLockJammed": false,
"IOptionalFeatureDisplayContrast": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": true,
"IOptionalFeatureMountingOrientation": false
},
"temperatureHumiditySensorCommunicationError": null,
"temperatureHumiditySensorError": null,
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"deviceId": "3014F7110000000000STE2015",
"functionalChannelType": "TEMPERATURE_SENSOR_2_EXTERNAL_DELTA_CHANNEL",
"groupIndex": 1,
"groups": [
"00000000-0000-0000-0000-000000000025"
],
"index": 1,
"label": "",
"temperatureExternalDelta": -0.1,
"temperatureExternalOne": 22.4,
"temperatureExternalTwo": 22.5
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000STE2015",
"label": "Temperatursensor mit externen F\u00fchlern \u2013 2-fach",
"lastStatusUpdate": 1645012379988,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manufacturerCode": 1,
"modelId": 415,
"modelType": "HmIP-STE2-PCB",
"oem": "eQ-3",
"permanentlyReachable": false,
"serializedGlobalTradeItemNumber": "3014F7110000000000STE2015",
"type": "TEMPERATURE_SENSOR_2_EXTERNAL_DELTA",
"updateState": "TRANSFERING_UPDATE"
},
"3014F7110000000000000WGC": {
"availableFirmwareVersion": "1.0.2",
"connectionType": "HMIP_RF",
"firmwareVersion": "1.0.2",
"firmwareVersionInteger": 65538,
"functionalChannels": {
"0": {
"busConfigMismatch": null,
"coProFaulty": false,
"coProRestartNeeded": false,
"coProUpdateFailure": false,
"configPending": false,
"deviceId": "3014F7110000000000000WGC",
"deviceOverheated": false,
"deviceOverloaded": false,
"devicePowerFailureDetected": false,
"deviceUndervoltage": false,
"displayContrast": null,
"dutyCycle": false,
"functionalChannelType": "DEVICE_BASE",
"groupIndex": 0,
"groups": [
"00000000-0000-0000-0000-000000000003"
],
"index": 0,
"label": "",
"lockJammed": null,
"lowBat": false,
"mountingOrientation": null,
"multicastRoutingEnabled": false,
"particulateMatterSensorCommunicationError": null,
"particulateMatterSensorError": null,
"powerShortCircuit": null,
"profilePeriodLimitReached": null,
"routerModuleEnabled": false,
"routerModuleSupported": false,
"rssiDeviceValue": -30,
"rssiPeerValue": -34,
"shortCircuitDataLine": null,
"supportedOptionalFeatures": {
"IFeatureBusConfigMismatch": false,
"IFeatureDeviceCoProError": false,
"IFeatureDeviceCoProRestart": false,
"IFeatureDeviceCoProUpdate": false,
"IFeatureDeviceIdentify": false,
"IFeatureDeviceOverheated": false,
"IFeatureDeviceOverloaded": false,
"IFeatureDeviceParticulateMatterSensorCommunicationError": false,
"IFeatureDeviceParticulateMatterSensorError": false,
"IFeatureDevicePowerFailure": false,
"IFeatureDeviceTemperatureHumiditySensorCommunicationError": false,
"IFeatureDeviceTemperatureHumiditySensorError": false,
"IFeatureDeviceTemperatureOutOfRange": false,
"IFeatureDeviceUndervoltage": true,
"IFeatureMulticastRouter": false,
"IFeaturePowerShortCircuit": false,
"IFeatureProfilePeriodLimit": false,
"IFeatureRssiValue": true,
"IFeatureShortCircuitDataLine": false,
"IOptionalFeatureDeviceErrorLockJammed": false,
"IOptionalFeatureDisplayContrast": false,
"IOptionalFeatureDutyCycle": true,
"IOptionalFeatureLowBat": true,
"IOptionalFeatureMountingOrientation": false
},
"temperatureHumiditySensorCommunicationError": null,
"temperatureHumiditySensorError": null,
"temperatureOutOfRange": false,
"unreach": false
},
"1": {
"deviceId": "3014F7110000000000000WGC",
"functionalChannelType": "SINGLE_KEY_CHANNEL",
"groupIndex": 1,
"groups": [],
"index": 1,
"label": ""
},
"2": {
"deviceId": "3014F7110000000000000WGC",
"functionalChannelType": "IMPULSE_OUTPUT_CHANNEL",
"groupIndex": 2,
"groups": [
"00000000-0000-0000-0000-000000000004"
],
"impulseDuration": 0.10000000149011612,
"index": 2,
"label": "Garage \u00f6ffnen/schliessen",
"processing": false
}
},
"homeId": "00000000-0000-0000-0000-000000000001",
"id": "3014F7110000000000000WGC",
"label": "Garagentortaster",
"lastStatusUpdate": 1637336400956,
"liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
"manufacturerCode": 1,
"modelId": 331,
"modelType": "HmIP-WGC",
"oem": "eQ-3",
"permanentlyReachable": true,
"serializedGlobalTradeItemNumber": "3014F7110000000000000001",
"type": "WALL_MOUNTED_GARAGE_DOOR_CONTROLLER",
"updateState": "UP_TO_DATE"
}
},
"groups": {
Expand Down
34 changes: 26 additions & 8 deletions tests/test_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from homematicip.class_maps import TYPE_FUNCTIONALCHANNEL_MAP


def test_getTypeFunctionalChannelMap(fake_home: Home):
for channelType in TYPE_FUNCTIONALCHANNEL_MAP.keys():
fc = TYPE_FUNCTIONALCHANNEL_MAP[channelType]()
Expand Down Expand Up @@ -1418,25 +1419,42 @@ def test_din_rail_dimmer_3(fake_home: Home):
def test_temperatur_sensor_2_delta(fake_home: Home):
d = fake_home.search_device_by_id("3014F711000HmIP-STE2-PCB")
assert isinstance(d, TemperaturDifferenceSensor2)
assert d.temperatureExternalDelta == -0.3
assert d.temperatureExternalOne == 37.8
assert d.temperatureExternalTwo == 38.1
assert d.temperatureExternalDelta == -0.3
assert d.temperatureExternalOne == 37.8
assert d.temperatureExternalTwo == 38.1

assert str(d) == (
"HmIP-STE2-PCB Temperatursensor Speicher lowBat(False) unreach(False) "
"rssiDeviceValue(-61) rssiPeerValue(None) configPending(False) dutyCycle(False) "
"temperatureExternalDelta(-0.3) temperatureExternalOne(37.8) temperatureExternalTwo(38.1)"
)
)


def test_temperatur_sensor_2_delta_2(fake_home: Home):
d = fake_home.search_device_by_id("3014F7110000000000300015")
assert isinstance(d, TemperaturDifferenceSensor2)
assert d.temperatureExternalDelta == -0.1
assert d.temperatureExternalOne == 22.4
assert d.temperatureExternalTwo == 22.5
assert d.temperatureExternalDelta == -0.1
assert d.temperatureExternalOne == 22.4
assert d.temperatureExternalTwo == 22.5

assert str(d) == (
"HmIP-STE2-PCB Temperatursensor mit externen F\u00fchlern \u2013 2-fach lowBat(False) unreach(False) "
"rssiDeviceValue(-60) rssiPeerValue(None) configPending(False) dutyCycle(False) "
"temperatureExternalDelta(-0.1) temperatureExternalOne(22.4) temperatureExternalTwo(22.5)"
)
)


def test_wall_mounted_garage_door_controller(fake_home: Home):
with no_ssl_verification():
d = fake_home.search_device_by_id("3014F7110000000000000WGC")
assert isinstance(d, WallMountedGarageDoorController)
assert d.impulseDuration == 0.10000000149011612
assert d.processing == False

result = d.send_start_impulse()

assert str(d) == (
"HmIP-WGC Garagentortaster lowBat(False) unreach(False) "
"rssiDeviceValue(-30) rssiPeerValue(-34) configPending(False) dutyCycle(False) deviceUndervoltage(False) "
"impulseDuration(0.10000000149011612) processing(False)"
)