raman325 / pyvizio

Python client for Vizio SmartCast
MIT License
109 stars 29 forks source link

VFD40M-0809 - Home Assistant #166

Closed krozgrov closed 1 week ago

krozgrov commented 1 week ago

VFD40M Vizio TV, I am able to connect using pyvizio CLI and can connect to the device and make perform power on, power off, get-input-list. But when trying to add the device in Home Assistant no Device or Entity is detected. When trying to add the device via YAML the integration just says "FAILED TO CONNECT". I have a second device that connects fine through CLI or HA.

Image 10-6-24 at 10 00 PM

Here is the log output between the working and non-working device.

2024-10-06 22:04:03.517 DEBUG (MainThread) [pyvizio.api._protocol] Using Command: GetCurrentPowerStateCommand({'_url': '/state/device/power_mode', 'item_name': 'POWER_MODE', 'default_return': 0}) 2024-10-06 22:04:03.518 DEBUG (MainThread) [pyvizio.api._protocol] Using Request: {'method': 'get', 'url': 'https://192.168.1.226:7345/state/device/power_mode', 'headers': {'AUTH': 'xxxxxxxxxxx'}} 2024-10-06 22:04:03.757 DEBUG (MainThread) [pyvizio.api._protocol] Response: {'STATUS': {'RESULT': 'SUCCESS', 'DETAIL': 'Success'}, 'URI': '/state/device/power_mode', 'ITEMS': [{'NAME': 'Power Mode', 'CNAME': 'power_mode', 'TYPE': 'T_VALUE_V1', 'VALUE': 1}]} 2024-10-06 22:04:03.758 DEBUG (MainThread) [pyvizio.api._protocol] Using Command: GetAllSettingsCommand({'_url': '/menu_native/dynamic/tv_settings/audio', 'item_name': 'SETTINGS', 'default_return': None, 'setting_type': 'audio'}) 2024-10-06 22:04:03.758 DEBUG (MainThread) [pyvizio.api._protocol] Using Request: {'method': 'get', 'url': 'https://192.168.1.226:7345/menu_native/dynamic/tv_settings/audio', 'headers': {'AUTH': 'xxxxxxxxxxx'}} 2024-10-06 22:04:04.013 DEBUG (MainThread) [pyvizio.api._protocol] Response: {'STATUS': {'RESULT': 'SUCCESS', 'DETAIL': 'Success'}, 'URI': '/menu_native/dynamic/tv_settings/audio', 'PARAMETERS': {'HASHONLY': 'FALSE', 'FLAT': 'TRUE', 'HELPTEXT': 'FALSE'}, 'ITEMS': [{'STATUS': {'RESULT': 'FAILURE', 'DETAIL': 'Failure'}, 'CNAME': 'soundbar_settings', 'TYPE': 'T_STRING_V1', 'NAME': 'Sound Bar Settings', 'READONLY': 'TRUE', 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE'}, {'CNAME': 'soundbar_eq_mode', 'TYPE': 'T_LIST_X_V1', 'NAME': 'EQ', 'VALUE': None, 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': None, 'ELEMENTS': []}, {'CNAME': 'soundbar_bass', 'TYPE': 'T_LIST_V1', 'NAME': 'Bass', 'VALUE': None, 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': None}, {'CNAME': 'soundbar_treble', 'TYPE': 'T_LIST_V1', 'NAME': 'Treble', 'VALUE': None, 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': None}, {'CNAME': 'soundbar_dialogue', 'TYPE': 'T_LIST_V1', 'NAME': 'Dialogue', 'VALUE': None, 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': None}, {'CNAME': 'soundbar_subwoofer', 'TYPE': 'T_LIST_V1', 'NAME': 'Subwoofer', 'VALUE': None, 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': None}, {'CNAME': 'soundbar_night_mode', 'TYPE': 'T_LIST_V1', 'NAME': 'Night Mode', 'VALUE': None, 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': None}, {'CNAME': 'soundbar_virtual_x', 'TYPE': 'T_LIST_V1', 'NAME': 'Virtual X', 'VALUE': None, 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': None}, {'CNAME': 'soundbar_speaker_test', 'TYPE': 'T_ACTION_V1', 'NAME': 'Speaker Test', 'VALUE': 'T_ACTION_V1', 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': 679411624}, {'CNAME': 'soundbar_info', 'TYPE': 'T_ACTION_V1', 'NAME': 'Info', 'VALUE': 'T_ACTION_V1', 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': 1227494634}, {'STATUS': {'RESULT': 'FAILURE', 'DETAIL': 'Failure'}, 'CNAME': 'tv_audio_settings', 'TYPE': 'T_STRING_V1', 'NAME': 'TV Audio Settings', 'READONLY': 'TRUE', 'ENABLED': 'FALSE'}, {'CNAME': 'tv_speakers', 'TYPE': 'T_LIST_X_V1', 'NAME': 'Audio Out', 'VALUE': 'TV speakers', 'HASHVAL': 1053867189, 'ELEMENTS': ['TV speakers', 'Optical/Audio Out']}, {'CNAME': 'surround_sound', 'TYPE': 'T_LIST_V1', 'NAME': 'Surround Sound', 'VALUE': 'Virtual:X™', 'HASHVAL': 1938414902}, {'CNAME': 'volume_leveling', 'TYPE': 'T_LIST_V1', 'NAME': 'Volume Leveling', 'VALUE': 'Off', 'HASHVAL': 1952348291, 'INDEX': 0}, {'CNAME': 'balance', 'TYPE': 'T_VALUE_ABS_V1', 'NAME': 'Balance', 'VALUE': 0, 'HASHVAL': 4048164689}, {'CNAME': 'bass', 'TYPE': 'T_VALUE_V1', 'NAME': 'Bass', 'VALUE': 0, 'HASHVAL': 2636064362}, {'CNAME': 'treble', 'TYPE': 'T_VALUE_V1', 'NAME': 'Treble', 'VALUE': 0, 'HASHVAL': 2027669657}, {'CNAME': 'lip_sync', 'TYPE': 'T_VALUE_V1', 'NAME': 'Lip Sync', 'VALUE': 0, 'HASHVAL': 83475440}, {'CNAME': 'digital_audio_out', 'TYPE': 'T_LIST_V1', 'NAME': 'Digital Audio Out', 'VALUE': 'Auto', 'HASHVAL': 2870599450, 'INDEX': 0}, {'CNAME': 'analog_audio_out', 'TYPE': 'T_LIST_V1', 'NAME': 'Analog Audio Out', 'VALUE': 'Fixed', 'HASHVAL': 1924764227, 'INDEX': 0}, {'CNAME': 'dialogue_enhancer', 'TYPE': 'T_LIST_V1', 'NAME': 'Dialogue Enhancer', 'VALUE': 'Off', 'HASHVAL': 4284435521, 'INDEX': 0}, {'CNAME': 'earc_mode', 'TYPE': 'T_LIST_V1', 'NAME': 'eARC', 'VALUE': 'Off', 'ENABLED': 'FALSE', 'HIDDEN': 'TRUE', 'HASHVAL': 1331403342, 'INDEX': 0}, {'CNAME': 'volume', 'TYPE': 'T_VALUE_V1', 'NAME': 'Volume', 'VALUE': 13, 'ENABLED': 'FALSE', 'HASHVAL': 1722708210}, {'CNAME': 'mute', 'TYPE': 'T_LIST_V1', 'NAME': 'Mute', 'VALUE': 0, 'ENABLED': 'FALSE', 'HASHVAL': 2969109703}], 'NAME': 'Audio', 'TYPE': 'T_MENU_V1', 'CNAME': 'audio', 'GROUP': 'G_AUDIO', 'HASHLIST': [4207517932, 4161985932]} 2024-10-06 22:05:09.352 DEBUG (MainThread) [pyvizio.api._protocol] Using Command: GetCurrentPowerStateCommand({'_url': '/state/device/power_mode', 'item_name': 'POWER_MODE', 'default_return': 0}) 2024-10-06 22:05:09.352 DEBUG (MainThread) [pyvizio.api._protocol] Using Request: {'method': 'get', 'url': 'https://192.168.1.225:7345/state/device/power_mode', 'headers': {'AUTH': 'xxxxxxxxx'}} 2024-10-06 22:05:11.180 DEBUG (MainThread) [pyvizio.api._protocol] Response: {'STATUS': {'RESULT': 'SUCCESS', 'DETAIL': 'Success'}, 'URI': '/state/device/power_mode', 'ITEMS': [{'NAME': 'Power Mode', 'CNAME': 'power_mode', 'TYPE': 'T_VALUE_V1', 'VALUE': 0}]} 2024-10-06 22:05:11.180 DEBUG (MainThread) [pyvizio.api._protocol] Using Command: GetModelNameCommand({'_url': '/state/device/deviceinfo', 'paths': [['model_name'], ['system_info', 'model_name']]}) 2024-10-06 22:05:11.180 DEBUG (MainThread) [pyvizio.api._protocol] Using Request: {'method': 'get', 'url': 'https://192.168.1.225:7345/state/device/deviceinfo', 'headers': {}} 2024-10-06 22:05:11.496 DEBUG (MainThread) [pyvizio.api._protocol] Response: {'STATUS': {'RESULT': 'SUCCESS', 'DETAIL': 'Success'}, 'URI': '/state/device/deviceinfo', 'ITEMS': [{'NAME': 'VIZIO Device Info', 'CNAME': 'deviceinfo', 'TYPE': 'T_VIZIO_DEVICE_INFO_V1', 'VALUE': {'MODEL_NAME': 'D40fM-K09', 'SETTINGS_ROOT': 'tv_settings', 'API_VERSION': '3.0.5-2429.0002', 'CAST_NAME': "Gabe's Bedroom - TV", 'INPUTS': ['hwtuner', 'comp', 'hdmi1', 'hdmi2', 'usb', 'cast', 'watchfree', 'TV', 'Recorder 1', 'Recorder 2', 'Tuner 1', 'Player 1', 'Audio System', 'Tuner 2', 'Tuner 3', 'Player 2', 'Recorder 3', 'Tuner 4', 'Player 3', 'Device 1', 'Device 2', 'Device 3', 'airplay', 'tuner'], 'CAPABILITIES': {'ABC': False, 'ACCESSIBILITY': True, 'AUDIO_2.0_API': True, 'AppleTVSupported': True, 'BACKLIGHT': True, 'BATTERY': False, 'BLE': False, 'BT_AUDIO_STREAMING': True, 'BT_REMOTE': True, 'BootToSC': True, 'CASTCORE_CAPABLE': True, 'CASTCORE_OPTOUT': True, 'CHANNEL_LANDING_INDICATOR_CAPABLE': False, 'CONJURE_SYSTEM_UI': False, 'CONJURE_SYSTEM_UI_LITE': True, 'CS_TROUBLESHOOT_ENABLED': True, 'EA_SENTRY': False, 'EA_SENTRY_TX_INSIGHT': False, 'ENERGY_STAR': False, 'FRC': False, 'GeoLocation': '/system/dynamic/iptolocation', 'HDR': None, 'IOTV2_CERT_CAPABLE': True, 'ITV_CAPABLE': True, 'ITV_DYNAMIC_TRIGGER_CAPABLE': True, 'ITV_OPT_OUT': True, 'ITV_OTT_CAPABLE': True, 'IoT_V2_Rollout': 50, 'LOKI_VOICE_NOTIFICATIONS': True, 'MEMC': False, 'MOBILE_VOICE_CAPABLE': True, 'NETFLIX_NRDP_VERSION': -1, 'RJ45': True, 'SCPLHandlesToSVerification': True, 'SCPL_SENTRY': False, 'SCTVInputsSupported': True, 'SCTV_V2_CAPABLE': True, 'SCTV_WF_CONTEXT_SWITCH': False, 'SOFT_AP': False, 'SYSTEM_REGISTRY_CAPABLE': True, 'TTS': True, 'TUNER': True, 'TUNER_WEBSOCKET': True, 'USB_POWER': True, 'VIZIOAPPS_IN_CONJURE': True, 'VIZIOGRAM_CAPABLE': True, 'VIZIO_HOME_IDENTITY_FCS': True, 'VIZIO_HOME_IDENTITY_MP': True, 'VIZIO_HOME_ONETRUST': True, 'VIZIO_PAY_CAPABLE': True, 'VIZIO_PAY_DISCOUNT_CAPABLE': True, 'VOICE_CAPABLE': True, 'WF_OTA_CAPABLE': True, 'YT_DEEPLINK_SUPPORT': True, 'ZOOMMODE': True, 'type': 'tvtuner', 'memc': 0}, 'BINARIES': {'CL': '5.30.1-2352.8868', 'TOOLKITX': '0.0.0', 'REDWOLF': '2.5.1.0', 'SCTV': '58.57', 'VIZIOSDK': 'MTK5583-4.600.37.0', 'LOGGER': '0.0.0', 'OOBE': '5.20.0-2319.16408', 'BLUETOOTH': 'MTK5583-6.0.000.3i', 'VZAIRPLAY': '33X-0.600.39.0-prod', 'COBALT': '23.lts.4.311259', 'CONJURE': 'MTKE-108.600.29.0-prod', 'SCPL': '3.0.5-2429.0002', 'VIZIOWEBPLAYER': 'v-0.2.4.32-mtk2020-bf21e80', 'ACR': 'MTK5583-3.5.1053', 'APPLETV': 'MTKE-14.4.0.32', 'VIZIONDK': 'MTKE-2.1.23.0-prod', 'VIZIOS': 'MTK5583-1.4.523.868.1-a89eb4d-a7bd265', 'DAI': 'MTK5583-1.7.2200', 'AIRPLAY': '0.0.0'}, 'SYSTEM_PICTURE_MODES': ['Vivid', 'Bright', 'Calibrated', 'Calibrated Dark', 'Game', 'Sports'], 'SYSTEM_INFO': {'CHIPSET': 4, 'DEVICE_TYPE': 0, 'MODEL_GROUP': 336, 'MODEL_NAME': 'D40fM-K09', 'MODEL_RESOLUTION': 1, 'MODEL_TYPE': 7, 'PANEL_TYPE': 0, 'SERIAL_NUMBER': '19LINIK4KY00864', 'SERIES': 'D', 'SIZE': 40, 'SOC': 1, 'SUBSERIES': 'D', 'VERSION': '3.600.31.1-5', 'DIID': 'ca5b0e99-f2a4-4078-97f9-f0da89c7c9be', 'TVAD_ID': {'IFA': 'b72dbc53-195e-4aa2-9661-bd9b7c08c763', 'IFA_TYPE': 'vida', 'LMT': 0}}, 'SC_INFO': 'prod 58.57'}}]} 2024-10-06 22:05:11.496 DEBUG (MainThread) [pyvizio.api._protocol] Using Command: GetVersionCommand({'_url': '/menu_native/dynamic/tv_settings/system/system_information/tv_information/version', 'item_name': 'VERSION', 'default_return': None}) 2024-10-06 22:05:11.499 DEBUG (MainThread) [pyvizio.api._protocol] Using Request: {'method': 'get', 'url': 'https://192.168.1.225:7345/menu_native/dynamic/tv_settings/system/system_information/tv_information/version', 'headers': {}} 2024-10-06 22:05:11.653 DEBUG (MainThread) [pyvizio.api._protocol] Response: {'STATUS': {'RESULT': 'URI_NOT_FOUND', 'DETAIL': 'URI not found'}, 'URI': '/menu_native/dynamic/tv_settings/system/system_information/tv_information/version'} 2024-10-06 22:05:11.653 DEBUG (MainThread) [pyvizio.api._protocol] Using Command: GetAltVersionCommand({'_url': '/menu_native/dynamic/tv_settings/admin_and_privacy/system_information/tv_information/version', 'item_name': 'VERSION', 'default_return': None}) 2024-10-06 22:05:11.654 DEBUG (MainThread) [pyvizio.api._protocol] Using Request: {'method': 'get', 'url': 'https://192.168.1.225:7345/menu_native/dynamic/tv_settings/admin_and_privacy/system_information/tv_information/version', 'headers': {}} 2024-10-06 22:05:11.750 DEBUG (MainThread) [pyvizio.api._protocol] Response: {'STATUS': {'RESULT': 'URI_NOT_FOUND', 'DETAIL': 'URI not found'}, 'URI': '/menu_native/dynamic/tv_settings/admin_and_privacy/system_information/tv_information/version'}

krozgrov commented 1 week ago

Also see this error but cannot tell if it's related to the one device not registering with Home Assistant.

2024-10-07 19:15:00.057 ERROR (MainThread) [homeassistant.components.media_player] vizio: Error on device update! Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 724, in _async_add_entity await entity.async_device_update(warning=False) File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1300, in async_device_update await self.async_update() File "/usr/src/homeassistant/homeassistant/components/vizio/media_player.py", line 242, in async_update audio_settings[VIZIO_MUTE].lower() == VIZIO_MUTE_ON ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'int' object has no attribute 'lower'

krozgrov commented 1 week ago

I have this fixed by updating the logic of the integer handling. With this update the TV that was not creating a device or entity is now working properly. @raman325 could you help get this in fix PR?

Original Code: if VIZIO_MUTE in audio_settings: self._attr_is_volume_muted = ( audio_settings[VIZIO_MUTE].lower() == VIZIO_MUTE_ON ) else: self._attr_is_volume_muted = None

Updated Code: `if VIZIO_MUTE in audio_settings: mute_value = audio_settings[VIZIO_MUTE]

if isinstance(mute_value, str):
    self._attr_is_volume_muted = mute_value.lower() == VIZIO_MUTE_ON
elif isinstance(mute_value, int):
    # Assuming 1 represents muted and 0 represents unmuted
    self._attr_is_volume_muted = mute_value == 1
else:
    self._attr_is_volume_muted = None

else: self._attr_is_volume_muted = None`