diff --git a/homeassistant/components/homekit_controller/const.py b/homeassistant/components/homekit_controller/const.py index 271834f2e92..bf2fd7ce1aa 100644 --- a/homeassistant/components/homekit_controller/const.py +++ b/homeassistant/components/homekit_controller/const.py @@ -63,6 +63,7 @@ CHARACTERISTIC_PLATFORMS = { CharacteristicsTypes.Vendor.KOOGEEK_REALTIME_ENERGY: "sensor", CharacteristicsTypes.Vendor.KOOGEEK_REALTIME_ENERGY_2: "sensor", CharacteristicsTypes.Vendor.VOCOLINC_HUMIDIFIER_SPRAY_LEVEL: "number", + CharacteristicsTypes.Vendor.VOCOLINC_OUTLET_ENERGY: "sensor", CharacteristicsTypes.TEMPERATURE_CURRENT: "sensor", CharacteristicsTypes.RELATIVE_HUMIDITY_CURRENT: "sensor", CharacteristicsTypes.AIR_QUALITY: "sensor", diff --git a/homeassistant/components/homekit_controller/manifest.json b/homeassistant/components/homekit_controller/manifest.json index 4b4b971b3b6..7133871da42 100644 --- a/homeassistant/components/homekit_controller/manifest.json +++ b/homeassistant/components/homekit_controller/manifest.json @@ -3,7 +3,7 @@ "name": "HomeKit Controller", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homekit_controller", - "requirements": ["aiohomekit==0.6.10"], + "requirements": ["aiohomekit==0.6.11"], "zeroconf": ["_hap._tcp.local."], "after_dependencies": ["zeroconf"], "codeowners": ["@Jc2k", "@bdraco"], diff --git a/homeassistant/components/homekit_controller/sensor.py b/homeassistant/components/homekit_controller/sensor.py index cb57bc74064..fb1c42ceac4 100644 --- a/homeassistant/components/homekit_controller/sensor.py +++ b/homeassistant/components/homekit_controller/sensor.py @@ -97,6 +97,13 @@ SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = { state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=PRESSURE_HPA, ), + CharacteristicsTypes.Vendor.VOCOLINC_OUTLET_ENERGY: HomeKitSensorEntityDescription( + key=CharacteristicsTypes.Vendor.VOCOLINC_OUTLET_ENERGY, + name="Real Time Energy", + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=POWER_WATT, + ), CharacteristicsTypes.TEMPERATURE_CURRENT: HomeKitSensorEntityDescription( key=CharacteristicsTypes.TEMPERATURE_CURRENT, name="Current Temperature", diff --git a/requirements_all.txt b/requirements_all.txt index f3f5e802bc0..52aeb05f3cb 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -184,7 +184,7 @@ aioguardian==2021.11.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==0.6.10 +aiohomekit==0.6.11 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6cee1437298..12ae2a42387 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -134,7 +134,7 @@ aioguardian==2021.11.0 aioharmony==0.2.9 # homeassistant.components.homekit_controller -aiohomekit==0.6.10 +aiohomekit==0.6.11 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/tests/components/homekit_controller/fixtures/vocolinc_vp3.json b/tests/components/homekit_controller/fixtures/vocolinc_vp3.json new file mode 100644 index 00000000000..bc58df1623e --- /dev/null +++ b/tests/components/homekit_controller/fixtures/vocolinc_vp3.json @@ -0,0 +1,430 @@ +[ + { + "aid":1, + "services":[ + { + "iid":1, + "type":"0000003E-0000-1000-8000-0026BB765291", + "primary":false, + "hidden":false, + "linked":[ + + ], + "characteristics":[ + { + "iid":2, + "type":"00000014-0000-1000-8000-0026BB765291", + "format":"bool", + "perms":[ + "pw" + ] + }, + { + "iid":3, + "type":"00000020-0000-1000-8000-0026BB765291", + "format":"string", + "value":"VOCOlinc", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":4, + "type":"00000021-0000-1000-8000-0026BB765291", + "format":"string", + "value":"VP3", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":5, + "type":"00000023-0000-1000-8000-0026BB765291", + "format":"string", + "value":"VOCOlinc-VP3-123456", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":6, + "type":"00000030-0000-1000-8000-0026BB765291", + "format":"string", + "value":"EU0121203xxxxx07", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":7, + "type":"00000052-0000-1000-8000-0026BB765291", + "format":"string", + "value":"1.101.2", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":8, + "type":"00000053-0000-1000-8000-0026BB765291", + "format":"string", + "value":"1.0.3", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":9, + "type":"34AB8811-AC7F-4340-BAC3-FD6A85F9943B", + "format":"string", + "value":"3.0;17A126", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":10, + "type":"220", + "format":"data", + "value":"wLrKXjM2g90=", + "perms":[ + "pr", + "hd" + ], + "ev":false, + "maxDataLen":8 + } + ] + }, + { + "iid":16, + "type":"000000A2-0000-1000-8000-0026BB765291", + "primary":false, + "hidden":false, + "linked":[ + + ], + "characteristics":[ + { + "iid":18, + "type":"00000037-0000-1000-8000-0026BB765291", + "format":"string", + "value":"1.1.0", + "perms":[ + "pr" + ], + "ev":false + } + ] + }, + { + "iid":48, + "type":"00000047-0000-1000-8000-0026BB765291", + "primary":true, + "hidden":false, + "linked":[ + + ], + "characteristics":[ + { + "iid":50, + "type":"00000023-0000-1000-8000-0026BB765291", + "format":"string", + "value":"Outlet", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":51, + "type":"00000025-0000-1000-8000-0026BB765291", + "format":"bool", + "value":1, + "perms":[ + "pr", + "pw", + "ev" + ], + "ev":false + }, + { + "iid":83, + "type":"A30DFE96-271A-42A5-88BA-00E3FF5488AD", + "format":"data", + "value":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "perms":[ + "pr", + "pw", + "ev" + ], + "ev":false, + "maxDataLen":256 + }, + { + "iid":53, + "type":"E2E80928-E08A-472F-8AE9-70BA72E132F2", + "format":"int", + "value":1, + "perms":[ + "pr", + "pw", + "ev" + ], + "ev":false, + "minValue":1, + "maxValue":3600, + "minStep":1 + }, + { + "iid":54, + "type":"D4669376-C36E-4C43-ACA4-ED07686EAB19", + "format":"uint8", + "value":0, + "perms":[ + "pr", + "pw", + "ev" + ], + "ev":false, + "minValue":0, + "maxValue":2, + "minStep":0 + }, + { + "iid":97, + "type":"FC093458-18F0-4B1D-8360-BB68A3FCC9C5", + "format":"int", + "value":0, + "perms":[ + "pr", + "ev" + ], + "ev":false, + "minValue":0, + "maxValue":2147483647, + "minStep":1 + }, + { + "iid":98, + "type":"865AD00B-A016-416E-8918-CF8E7EC788C4", + "format":"int", + "value":2552, + "perms":[ + "pr" + ], + "ev":false, + "minValue":0, + "maxValue":2147483647, + "minStep":1 + }, + { + "iid":99, + "type":"2D5D1654-63EE-4314-9CF1-651F266D3BBE", + "format":"data", + "value":"AQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "perms":[ + "pr", + "ev" + ], + "ev":false, + "maxDataLen":128 + }, + { + "iid":100, + "type":"6E46AD30-6FC2-426F-9A86-C2A834DD8F29", + "format":"data", + "value":"AQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "perms":[ + "pr", + "ev" + ], + "ev":false, + "maxDataLen":128 + }, + { + "iid":101, + "type":"56F805A5-4B30-47D0-9908-E609B4CF18E3", + "format":"data", + "value":"AQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "perms":[ + "pr", + "ev" + ], + "ev":false, + "maxDataLen":128 + }, + { + "iid":102, + "type":"A121FC5E-67DB-41EC-BF4F-5A431F0DA9CB", + "format":"data", + "value":"AQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "perms":[ + "pr", + "ev" + ], + "ev":false, + "maxDataLen":64 + }, + { + "iid":103, + "type":"BC75E7A0-7DD8-4CBB-9DE8-93E70A04916D", + "format":"data", + "value":"AQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "perms":[ + "pr", + "ev" + ], + "ev":false, + "maxDataLen":64 + }, + { + "iid":89, + "type":"43CE176B-2933-4034-98A7-AD215BEEBF2F", + "format":"data", + "value":"AAAAAAAAAAAAAA==", + "perms":[ + "pr", + "pw", + "ev" + ], + "ev":false, + "description":"\"CountDown\"", + "maxDataLen":256 + } + ] + }, + { + "iid":64, + "type":"3138B537-E830-4F52-90A7-D6FDB000BF97", + "primary":false, + "hidden":true, + "linked":[ + + ], + "characteristics":[ + { + "iid":65, + "type":"00000023-0000-1000-8000-0026BB765291", + "format":"string", + "value":"FW Update", + "perms":[ + "pr" + ], + "ev":false + }, + { + "iid":66, + "type":"4C203E30-EB25-466D-9980-C6C2E14BF6AA", + "format":"string", + "perms":[ + "pw", + "hd" + ], + "description":"\"FW update\"", + "maxLen":128 + }, + { + "iid":67, + "type":"49DDDE07-C3FA-499E-8055-58E154E04F34", + "format":"int", + "value":null, + "perms":[ + "pr", + "ev" + ], + "ev":false, + "minValue":0, + "maxValue":3, + "minStep":1 + } + ] + }, + { + "iid":80, + "type":"C635EF5C-5BBC-4F96-B7DA-6669069A4B32", + "primary":false, + "hidden":true, + "linked":[ + + ], + "characteristics":[ + { + "iid":82, + "type":"8137182C-6904-4FB9-ADCC-61CECA85CE48", + "format":"uint8", + "value":27, + "perms":[ + "pr", + "ev" + ], + "ev":false + }, + { + "iid":81, + "type":"00000023-0000-1000-8000-0026BB765291", + "format":"string", + "value":"Rssi Report", + "perms":[ + "pr" + ], + "ev":false + } + ] + }, + { + "iid":84, + "type":"961BBB65-A1E3-4F34-BD31-86552706FE40", + "primary":false, + "hidden":false, + "linked":[ + + ], + "characteristics":[ + { + "iid":85, + "type":"38396B8E-161B-4A77-AF3F-C4DAC0BE9B74", + "format":"int", + "value":999, + "perms":[ + "pr", + "pw" + ], + "ev":false, + "minValue":-1200, + "maxValue":1400, + "minStep":1 + }, + { + "iid":86, + "type":"71216CD3-209E-40CC-BEA0-71A2A9458E13", + "format":"int", + "perms":[ + "pw" + ], + "minValue":0, + "maxValue":2147483647, + "minStep":1 + }, + { + "iid":87, + "type":"00000023-0000-1000-8000-0026BB765291", + "format":"string", + "value":"sync time", + "perms":[ + "pr" + ], + "ev":false + } + ] + } + ] + } +] diff --git a/tests/components/homekit_controller/specific_devices/test_vocolinc_vp3.py b/tests/components/homekit_controller/specific_devices/test_vocolinc_vp3.py new file mode 100644 index 00000000000..7489dca2f08 --- /dev/null +++ b/tests/components/homekit_controller/specific_devices/test_vocolinc_vp3.py @@ -0,0 +1,48 @@ +"""Make sure that existing VOCOlinc VP3 support isn't broken.""" + +from homeassistant.components.sensor import SensorStateClass +from homeassistant.const import POWER_WATT + +from tests.components.homekit_controller.common import ( + DeviceTestInfo, + EntityTestInfo, + assert_devices_and_entities_created, + setup_accessories_from_file, + setup_test_accessories, +) + + +async def test_vocolinc_vp3_setup(hass): + """Test that a VOCOlinc VP3 can be correctly setup in HA.""" + accessories = await setup_accessories_from_file(hass, "vocolinc_vp3.json") + await setup_test_accessories(hass, accessories) + + await assert_devices_and_entities_created( + hass, + DeviceTestInfo( + unique_id="00:00:00:00:00:00", + name="VOCOlinc-VP3-123456", + model="VP3", + manufacturer="VOCOlinc", + sw_version="1.101.2", + hw_version="1.0.3", + serial_number="EU0121203xxxxx07", + devices=[], + entities=[ + EntityTestInfo( + entity_id="switch.vocolinc_vp3_123456", + friendly_name="VOCOlinc-VP3-123456", + unique_id="homekit-EU0121203xxxxx07-48", + state="on", + ), + EntityTestInfo( + entity_id="sensor.vocolinc_vp3_123456_real_time_energy", + friendly_name="VOCOlinc-VP3-123456 - Real Time Energy", + unique_id="homekit-EU0121203xxxxx07-aid:1-sid:48-cid:97", + unit_of_measurement=POWER_WATT, + capabilities={"state_class": SensorStateClass.MEASUREMENT}, + state="0", + ), + ], + ), + )