diff --git a/homeassistant/components/homekit/accessories.py b/homeassistant/components/homekit/accessories.py index c13bb870551..e86135fb9a1 100644 --- a/homeassistant/components/homekit/accessories.py +++ b/homeassistant/components/homekit/accessories.py @@ -64,6 +64,11 @@ from .const import ( HK_NOT_CHARGABLE, HK_NOT_CHARGING, MANUFACTURER, + MAX_MANUFACTURER_LENGTH, + MAX_MODEL_LENGTH, + MAX_NAME_LENGTH, + MAX_SERIAL_LENGTH, + MAX_VERSION_LENGTH, SERV_BATTERY_SERVICE, SERVICE_HOMEKIT_RESET_ACCESSORY, TYPE_FAUCET, @@ -217,7 +222,9 @@ class HomeAccessory(Accessory): **kwargs, ): """Initialize a Accessory object.""" - super().__init__(driver=driver, display_name=name, aid=aid, *args, **kwargs) + super().__init__( + driver=driver, display_name=name[:MAX_NAME_LENGTH], aid=aid, *args, **kwargs + ) self.config = config or {} domain = split_entity_id(entity_id)[0].replace("_", " ") @@ -237,10 +244,10 @@ class HomeAccessory(Accessory): sw_version = __version__ self.set_info_service( - manufacturer=manufacturer, - model=model, - serial_number=entity_id, - firmware_revision=sw_version, + manufacturer=manufacturer[:MAX_MANUFACTURER_LENGTH], + model=model[:MAX_MODEL_LENGTH], + serial_number=entity_id[:MAX_SERIAL_LENGTH], + firmware_revision=sw_version[:MAX_VERSION_LENGTH], ) self.category = category diff --git a/homeassistant/components/homekit/const.py b/homeassistant/components/homekit/const.py index d2802ec8fb0..30b2a1c2597 100644 --- a/homeassistant/components/homekit/const.py +++ b/homeassistant/components/homekit/const.py @@ -293,3 +293,10 @@ CONFIG_OPTIONS = [ CONF_ENTITY_CONFIG, CONF_HOMEKIT_MODE, ] + +# ### Maximum Lengths ### +MAX_NAME_LENGTH = 64 +MAX_SERIAL_LENGTH = 64 +MAX_MODEL_LENGTH = 64 +MAX_VERSION_LENGTH = 64 +MAX_MANUFACTURER_LENGTH = 64 diff --git a/homeassistant/components/homekit/type_fans.py b/homeassistant/components/homekit/type_fans.py index 1efb3b6c8be..1a0bb41774c 100644 --- a/homeassistant/components/homekit/type_fans.py +++ b/homeassistant/components/homekit/type_fans.py @@ -39,6 +39,7 @@ from .const import ( CHAR_ROTATION_DIRECTION, CHAR_ROTATION_SPEED, CHAR_SWING_MODE, + MAX_NAME_LENGTH, PROP_MIN_STEP, SERV_FANV2, SERV_SWITCH, @@ -100,7 +101,8 @@ class Fan(HomeAccessory): preset_serv = self.add_preload_service(SERV_SWITCH, CHAR_NAME) serv_fan.add_linked_service(preset_serv) preset_serv.configure_char( - CHAR_NAME, value=f"{self.display_name} {preset_mode}" + CHAR_NAME, + value=f"{self.display_name} {preset_mode}"[:MAX_NAME_LENGTH], ) self.preset_mode_chars[preset_mode] = preset_serv.configure_char( diff --git a/homeassistant/components/homekit/type_media_players.py b/homeassistant/components/homekit/type_media_players.py index 5cd27109bd8..081053d2591 100644 --- a/homeassistant/components/homekit/type_media_players.py +++ b/homeassistant/components/homekit/type_media_players.py @@ -55,6 +55,7 @@ from .const import ( FEATURE_PLAY_STOP, FEATURE_TOGGLE_MUTE, KEY_PLAY_PAUSE, + MAX_NAME_LENGTH, SERV_SWITCH, SERV_TELEVISION_SPEAKER, ) @@ -134,7 +135,7 @@ class MediaPlayer(HomeAccessory): def generate_service_name(self, mode): """Generate name for individual service.""" - return f"{self.display_name} {MODE_FRIENDLY_NAME[mode]}" + return f"{self.display_name} {MODE_FRIENDLY_NAME[mode]}"[:MAX_NAME_LENGTH] def set_on_off(self, value): """Move switch state to value if call came from HomeKit.""" diff --git a/homeassistant/components/homekit/type_remotes.py b/homeassistant/components/homekit/type_remotes.py index 718671dfd1d..9e54221430c 100644 --- a/homeassistant/components/homekit/type_remotes.py +++ b/homeassistant/components/homekit/type_remotes.py @@ -47,6 +47,7 @@ from .const import ( KEY_PREVIOUS_TRACK, KEY_REWIND, KEY_SELECT, + MAX_NAME_LENGTH, SERV_INPUT_SOURCE, SERV_TELEVISION, ) @@ -120,8 +121,10 @@ class RemoteInputSelectAccessory(HomeAccessory): SERV_INPUT_SOURCE, [CHAR_IDENTIFIER, CHAR_NAME] ) serv_tv.add_linked_service(serv_input) - serv_input.configure_char(CHAR_CONFIGURED_NAME, value=source) - serv_input.configure_char(CHAR_NAME, value=source) + serv_input.configure_char( + CHAR_CONFIGURED_NAME, value=source[:MAX_NAME_LENGTH] + ) + serv_input.configure_char(CHAR_NAME, value=source[:MAX_NAME_LENGTH]) serv_input.configure_char(CHAR_IDENTIFIER, value=index) serv_input.configure_char(CHAR_IS_CONFIGURED, value=True) input_type = 3 if "hdmi" in source.lower() else 0 diff --git a/tests/components/homekit/test_accessories.py b/tests/components/homekit/test_accessories.py index 987a90ce61a..9b70bf4830e 100644 --- a/tests/components/homekit/test_accessories.py +++ b/tests/components/homekit/test_accessories.py @@ -66,7 +66,7 @@ async def test_accessory_cancels_track_state_change_on_stop(hass, hk_driver): async def test_home_accessory(hass, hk_driver): """Test HomeAccessory class.""" entity_id = "sensor.accessory" - entity_id2 = "light.accessory" + entity_id2 = "light.accessory_that_exceeds_the_maximum_maximum_maximum_maximum_maximum_maximum_maximum_allowed_length" hass.states.async_set(entity_id, None) hass.states.async_set(entity_id2, STATE_UNAVAILABLE) @@ -94,27 +94,42 @@ async def test_home_accessory(hass, hk_driver): assert serv.get_characteristic(CHAR_NAME).value == "Home Accessory" assert serv.get_characteristic(CHAR_MANUFACTURER).value == f"{MANUFACTURER} Light" assert serv.get_characteristic(CHAR_MODEL).value == "Light" - assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == "light.accessory" + assert ( + serv.get_characteristic(CHAR_SERIAL_NUMBER).value + == "light.accessory_that_exceeds_the_maximum_maximum_maximum_maximum" + ) acc3 = HomeAccessory( hass, hk_driver, - "Home Accessory", + "Home Accessory that exceeds the maximum maximum maximum maximum maximum maximum length", entity_id2, 3, { - ATTR_MODEL: "Awesome", - ATTR_MANUFACTURER: "Lux Brands", - ATTR_SW_VERSION: "0.4.3", - ATTR_INTEGRATION: "luxe", + ATTR_MODEL: "Awesome Model that exceeds the maximum maximum maximum maximum maximum maximum length", + ATTR_MANUFACTURER: "Lux Brands that exceeds the maximum maximum maximum maximum maximum maximum length", + ATTR_SW_VERSION: "0.4.3 that exceeds the maximum maximum maximum maximum maximum maximum length", + ATTR_INTEGRATION: "luxe that exceeds the maximum maximum maximum maximum maximum maximum length", }, ) assert acc3.available is False serv = acc3.services[0] # SERV_ACCESSORY_INFO - assert serv.get_characteristic(CHAR_NAME).value == "Home Accessory" - assert serv.get_characteristic(CHAR_MANUFACTURER).value == "Lux Brands" - assert serv.get_characteristic(CHAR_MODEL).value == "Awesome" - assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == "light.accessory" + assert ( + serv.get_characteristic(CHAR_NAME).value + == "Home Accessory that exceeds the maximum maximum maximum maximum " + ) + assert ( + serv.get_characteristic(CHAR_MANUFACTURER).value + == "Lux Brands that exceeds the maximum maximum maximum maximum maxi" + ) + assert ( + serv.get_characteristic(CHAR_MODEL).value + == "Awesome Model that exceeds the maximum maximum maximum maximum m" + ) + assert ( + serv.get_characteristic(CHAR_SERIAL_NUMBER).value + == "light.accessory_that_exceeds_the_maximum_maximum_maximum_maximum" + ) hass.states.async_set(entity_id, "on") await hass.async_block_till_done()