Tuxedo Touch Controller with HA

I am still using this despite the recent change mentioned by wchan.

I will update the github sources with the changes.

No longer working in 2021.5.5

Logger: homeassistant.components.alarm_control_panel
Source: util/async_.py:140
Integration: Alarm control panel (documentation, issues)
First occurred: 7:06:27 PM (2 occurrences)
Last logged: 7:06:28 PM

Error adding entities for domain alarm_control_panel with platform tuxedo
Error while setting up tuxedo platform for alarm_control_panel
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/helpers/entity_platform.py”, line 364, in async_add_entities
await asyncio.gather(*tasks)
File “/usr/src/homeassistant/homeassistant/helpers/entity_platform.py”, line 558, in _async_add_entity
await entity.add_to_platform_finish()
File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 580, in add_to_platform_finish
await self.async_added_to_hass()
File “/config/custom_components/tuxedo/alarm_control_panel.py”, line 131, in async_added_to_hass
async_register()
File “/config/custom_components/tuxedo/alarm_control_panel.py”, line 126, in async_register
result = self._api_request(
File “/config/custom_components/tuxedo/alarm_control_panel.py”, line 250, in _api_request
response = requests.post(
File “/usr/local/lib/python3.8/site-packages/requests/api.py”, line 119, in post
return request(‘post’, url, data=data, json=json, **kwargs)
File “/usr/local/lib/python3.8/site-packages/requests/api.py”, line 61, in request
return session.request(method=method, url=url, **kwargs)
File “/usr/local/lib/python3.8/site-packages/requests/sessions.py”, line 542, in request
resp = self.send(prep, **send_kwargs)
File “/usr/local/lib/python3.8/site-packages/requests/sessions.py”, line 655, in send
r = adapter.send(request, **kwargs)
File “/usr/local/lib/python3.8/site-packages/requests/adapters.py”, line 439, in send
resp = conn.urlopen(
File “/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py”, line 699, in urlopen
httplib_response = self._make_request(
File “/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py”, line 394, in _make_request
conn.request(method, url, **httplib_request_kw)
File “/usr/local/lib/python3.8/site-packages/urllib3/connection.py”, line 234, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File “/usr/local/lib/python3.8/http/client.py”, line 1252, in request
self._send_request(method, url, body, headers, encode_chunked)
File “/usr/local/lib/python3.8/http/client.py”, line 1263, in send_request
self.putrequest(method, url, **skips)
File “/usr/local/lib/python3.8/site-packages/urllib3/connection.py”, line 214, in putrequest
return HTTPConnection.putrequest(self, method, url, *args, **kwargs)
File "/usr/src/homeassistant/homeassistant/util/async
.py", line 151, in protected_loop_func
check_loop()
File "/usr/src/homeassistant/homeassistant/util/async
.py", line 140, in check_loop
raise RuntimeError(
RuntimeError: I/O must be done in the executor; Use await hass.async_add_executor_job() at custom_components/tuxedo/alarm_control_panel.py, line 250: response = requests.post(

@Quinchu Thanks for letting me know, i am on 2021.2.1 i will update and submit a fix… most likely need to convert one operation to async.

@Quinchu issue should be fixed now… updated sources in github home-assistant/alarm_control_panel.py at 94b738c313ea7a6cdc436214ede63c8300b39ed3 · hinzo/home-assistant · GitHub

since this is a custom integration, if HA complained about missing version, add this to manifest.json of the tuxedo integration:
“version”: “0.1.1”

Worked like a charm.

Do you think there is any way for information about zones opening / closing with this as well?

@hani_atassi

So just to confirm, HA can access the tuxedo locally without having to pay monthly for Total Connect? But it’s only to arm/disarm and check status? No info about sensors or zones?

Struggling to get this integration to work in Homeassistant. Can anybody provide detailed information please? I’m currently on Home Assistant 2022.3.2, I’ve copied the 3 files ( init.py, alarm_control_panel.py and manifest.json to the config/custom_components/tuxedo folder but it will not show up. I’m clearly missing something but don’t know what yet. Any help would be appreciated. Hoping to test this on the new Honeywell Home Tuxedo.

Ok, figured out I missed editing my configuration.yaml file by adding:

alarm_control_panel:

To others who are also struggling with this, the Mac Id needs to be that of “hassio” when you check in terminal via ifconfig… not docker0, enp0s3, etc. The url also needs the “https://” added.

And for those wondering, Yes, it does appear to be working with the New version Of Honeywell Home Tuxedo.

The Tuxedo touch custom component is not working after upgrading to 2022.07.0. Here is the error:

Logger: homeassistant.components.alarm_control_panel
Source: components/tuxedo/alarm_control_panel.py:263 
Integration: Alarm control panel (documentation, issues) 
First occurred: 8:36:55 PM (1 occurrences) 
Last logged: 8:36:55 PM

tuxedo: Error on device update!
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.10/site-packages/homeassistant/helpers/entity_platform.py", line 446, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/srv/homeassistant/lib/python3.10/site-packages/homeassistant/helpers/entity.py", line 702, in async_device_update
    await task
  File "/srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/tuxedo/alarm_control_panel.py", line 167, in async_update
    result = await self._api_get_state()
  File "/srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/tuxedo/alarm_control_panel.py", line 211, in _api_get_state
    return await self._async_api_request("/GetSecurityStatus", {"operation": "get"})
  File "/srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/tuxedo/alarm_control_panel.py", line 239, in _async_api_request
    return await self.hass.async_add_executor_job(
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/lib/python3.10/site-packages/homeassistant/components/tuxedo/alarm_control_panel.py", line 263, in _api_request
    response = requests.post(
  File "/srv/homeassistant/lib/python3.10/site-packages/requests/api.py", line 115, in post
    return request("post", url, data=data, json=json, **kwargs)
  File "/srv/homeassistant/lib/python3.10/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
  File "/srv/homeassistant/lib/python3.10/site-packages/requests/sessions.py", line 573, in request
    prep = self.prepare_request(req)
  File "/srv/homeassistant/lib/python3.10/site-packages/requests/sessions.py", line 484, in prepare_request
    p.prepare(
  File "/srv/homeassistant/lib/python3.10/site-packages/requests/models.py", line 369, in prepare
    self.prepare_headers(headers)
  File "/srv/homeassistant/lib/python3.10/site-packages/requests/models.py", line 491, in prepare_headers
    check_header_validity(header)
  File "/srv/homeassistant/lib/python3.10/site-packages/requests/utils.py", line 1037, in check_header_validity
    raise InvalidHeader(
requests.exceptions.InvalidHeader: Header part ('Pragma') from {'Pragma': 'no-cache'} must be of type str or bytes, not <class 'multidict._multidict.istr'>

Oh good, it’s not me.
There was a series of breaking changes over the last 2 updates that I think may be related but I’m trying to find the time to dig into the changes.

Ok, so I made some code changes that seem to work. I’ll do a PR to the Github repo, but for now if you want to do it yourself here is what you can try:

I added Line 78:

requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL:@SECLEVEL=1'

I modified lines 262-267 to this:

            headers={
                "authtoken": authtoken,
                "identity": self._api_iv_enc,
                "PRAGMA": "no-cache",
                "CACHE_CONTROL": "no-cache",
            },

I am attempting to get this integration work. I have a new folder that I created within custom_components called ‘tuxedo’. In that folder I have the alarm_control_panel.py, manifest.json and init.py.

Within my configuration.yaml I have added the following lines with the appropriate data:

#Tuxedo
alarm_control_panel:
  - platform: tuxedo
    mac: 0xxxxxxxx
    url: https://1xxxxxxxx
    private_key: 4xxxxxxxxxxxxxxxxxx3
    code: xxxx'

I am getting the following error

[140563627163168] The system cannot restart because the configuration is not valid: Platform error alarm_control_panel.tuxedo - Integration ‘tuxedo’ not found.

11:37:39 AM – (ERROR) Home Assistant WebSocket API

Can someone please advise as to what I am doing wrong?

Thank you!

@nnn103, try doing a 2 reboot install.
Remove the code from configuration.yaml file, and leave the tuxedo folder in custom_components. Reboot.
This will let HA see the custom component.
Then readd in the configuration.yaml code.
Reboot again.

See if that works.

Having the same problem as nnm103, I have the 3 files in “/config/custom_components/tuxedo”, added the following code to “/config/configuration.yaml”, when I click I do a Configuration validation, I get the same error;

“Platform error alarm_control_panel.tuxedo - Integration ‘tuxedo’ not found.”

alarm_control_panel:
  - platform: tuxedo
    mac: 08:xx:27:xx:xx:xx
    url: https://192.168.1.xx
    private_key: 1c24.......e2f41d9
    code: 9999

Added “version”: “0.1.1” to the manifest.json file, seems to load now.

Getting this error;

Logger: homeassistant.components.alarm_control_panel
Source: custom_components/tuxedo/alarm_control_panel.py:254
Integration: Alarm control panel (documentation, issues)
First occurred: September 17, 2022 at 7:38:20 PM (1 occurrences)
Last logged: September 17, 2022 at 7:38:20 PM

tuxedo: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 493, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 703, in async_device_update
    await task
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 167, in async_update
    result = await self._api_get_state()
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 211, in _api_get_state
    return await self._async_api_request("/GetSecurityStatus", {"operation": "get"})
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 239, in _async_api_request
    return await self.hass.async_add_executor_job(
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 254, in _api_request
    response = requests.post(
  File "/usr/local/lib/python3.10/site-packages/requests/api.py", line 115, in post
    return request("post", url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 573, in request
    prep = self.prepare_request(req)
  File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 484, in prepare_request
    p.prepare(
  File "/usr/local/lib/python3.10/site-packages/requests/models.py", line 369, in prepare
    self.prepare_headers(headers)
  File "/usr/local/lib/python3.10/site-packages/requests/models.py", line 491, in prepare_headers
    check_header_validity(header)
  File "/usr/local/lib/python3.10/site-packages/requests/utils.py", line 1037, in check_header_validity
    raise InvalidHeader(
requests.exceptions.InvalidHeader: Header part ('Pragma') from {'Pragma': 'no-cache'} must be of type str or bytes, not <class 'multidict._multidict.istr'>

Code fix from post 29 fixed the above problem.

Now I am getting error “Unauthorized API” Tried using the MAC I got by doing ifconfig in terminal and the one listed in my router, both with new private keys from the tuxedo API page.

Both give me same error

Is there a special way for the MAC address to be entered?
Using uppercase in this format XX:XX:XX:XX:XX

 Logger: custom_components.tuxedo.alarm_control_panel
Source: custom_components/tuxedo/alarm_control_panel.py:280
Integration: tuxedo
First occurred: 4:23:41 PM (2 occurrences)
Last logged: 4:23:43 PM

    Unauthorized, API: /GetSecurityStatus
    Unauthorized, API: /Registration/Register

Mine looks like this (with things X’d out for privacy):

alarm_control_panel:
  - platform: tuxedo
    mac: 60eb69XXXXXX
    url: https://192.168.X.XX
    private_key: 56a7.....
    code: XXXX

So to answer your question, the MAC address should be all lower case and with no special characters.
The MAC address also needs to be the MAC address from the last hop device. So if your tuxedo is across a subnet boundary, then the mac would be the routers interface mac address. If you are using docker, then it’s the containers network interface, etc.

Works!
Thanks!

Anyway to secure it?
So a would be burglar could not just walk up to a tablet on the wall and hit disarm ?

Pretty much. AFAIK there is no way to secure it.

hey all, having some trouble getting this integration working. I’m getting this error message.

Logger: homeassistant.components.alarm_control_panel
Source: custom_components/tuxedo/alarm_control_panel.py:99 
Integration: Alarm control panel (documentation, issues) 
First occurred: 4:45:13 PM (1 occurrences) 
Last logged: 4:45:13 PM

tuxedo: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 493, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 703, in async_device_update
    await task
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 168, in async_update
    result = await self._api_get_state()
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 212, in _api_get_state
    return await self._async_api_request("/GetSecurityStatus", {"operation": "get"})
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 240, in _async_api_request
    return await self.hass.async_add_executor_job(
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 247, in _api_request
    uri_params_encrypted = _encrypt_data(
  File "/config/custom_components/tuxedo/alarm_control_panel.py", line 99, in _encrypt_data
    encryptor = AES.new(key, AES.MODE_CBC, IV=iv)
  File "/usr/local/lib/python3.10/site-packages/Crypto/Cipher/AES.py", line 232, in new
    return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/Crypto/Cipher/__init__.py", line 79, in _create_cipher
    return modes[mode](factory, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/Crypto/Cipher/_mode_cbc.py", line 287, in _create_cbc_cipher
    raise ValueError("Incorrect IV length (it must be %d bytes long)" %
ValueError: Incorrect IV length (it must be 16 bytes long)

I’ve already tried updating the integration code based on post 29 above, which adds in this newline:

requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL:@SECLEVEL=1'

and modifies the headers on line 262 to this:

            headers={
                "authtoken": authtoken,
                "identity": self._api_iv_enc,
                "PRAGMA": "no-cache",
                "CACHE_CONTROL": "no-cache",
            },

I think I’ve also configured my YAML properly with the following:

alarm_control_panel:
  - platform: tuxedo
    mac: a2:2a:xx:xx:xx:xx
    url: https://[tuxedo_url]
    private_key: [my_private_key]
    code: [my_panel_code]

I’m on HASS version 2022.10.5

Any tips would be appreciated!