Qolsys IQ Panel 2 and 3rd party integration

Just set this up a few days ago! Excited about the way you’ve figured out how to reverse-engineer the remote panel connection. It’s been working great so far. Still need to migrate automations to this integration

This project is absolutely fantastic!

I just got it installed and I’m genuinely impressed. Not only did it detect all of my devices flawlessly, but it even successfully integrated my smoke detectors, something I struggled with on the Qolsys Gateway project.

Huge thanks to the developers. I’m really looking forward to putting this through its paces!

1 Like

You can check with v0.0.22-beta.3 in HACS

Added support to trigger Police, Auxilliary and Fire Alarm through integration linked services. Services need to be enabled on integration page options.


@EHylands hey, happy to test this for you however I have a few questions can I use this in parallel with the existing control 4 integration? Also I have an iq2 panel not a two +, as far as I remember the two plus supports power G otherwise it’s the same so will it work for a non-2 plus? Thanks

EDIT: so, yes, this works with a regular IQ2 panel in beta 30. Pairing took 5 seconds. Nice!


1 Like

Great news !
As per official qolsys specs, IQ Remote are only supported on IQ2+ panels…

Integration can be run in parallel with either C4 integration or alarmdotcom integration without any unique_id collision in Home Assistant.

Yes I’m really happy this is working. My panel is about 8 years old and it’s been flawless knock on wood I haven’t had to replace it yet so I’m just going to go along with it.

There’s a couple of blocking call logs I’ll submit an issue at your repo but so far everything is working perfectly here.

P.S. I do have two IQ panel remotes already this will be a third.

There seems to be a theoretical limit on how many IQ Remotes can connect to the main panel at the same time (3?).

One interesting thing I noticed: if you delete the Home Assistant virtual IQ Remote from the panel’s list, you can still connect using the client certificate that was already created. It doesn’t look like the main panel actually revokes the client certificate when the remote is deleted from the list.

IQ Remotes are really useful for discovering new capabilities. That’s actually how I was able to reverse the protocol, by issuing commands on the remote and listening to what gets published on the MQTT server.

If you run into issues or find bugs, please submit them on the GitHub page.

Tnx for helping out !

The two main blocking issues I’m aware of right now:

1- Zeroconf handling while pairing:
The controller uses its own Zeroconf instance, while Home Assistant would like me to use its own. WIP.

2- AIOMQTT client / certificate loading
The controller uses AIOMQTT as an async MQTT client, but Home Assistant doesn’t provide a helper to avoid blocking while loading certificates. Because of this, I’ll likely need to move the entire main function into an executor thread instead of running it directly as an asyncio coroutine. Also still WIP :slightly_smiling_face:

oh, interesting @EHylands! it must be at least 3 IQ Remotes, because I just tested my 2 real IQ Remotes and the virtual remote (i.e. your integration), simply arming and disarming and eveything is working and communicating with eachother, including the Q4 and alarm.com. Eventually, if your integration proves stable, I will switch because its first one I’ve seen that has sensor battery information!

Perhaps i don’t have to submit an issue, but the 2 logs I received (are very long) and seemed to have happened on parining, which if its a one off, probably ok, but I know event loop block is bad for HA, but here’s the logs with redacted pki values and 0xXXX.

Are these logs what you’re seeing?

Logs
Logger: homeassistant.util.loop
Source: util/loop.py:137
First occurred: 5:57:45 PM (2 occurrences)
Last logged: 5:57:45 PM

Detected blocking call to load_cert_chain with args (<ssl.SSLContext object at 0xXXXXXXXX>, '/config/qolsys_panel/pki/[REDACTED].secure', '/config/qolsys_panel/pki/[REDACTED].key', None) inside the event loop by custom integration 'qolsys_panel' at custom_components/qolsys_panel/config_flow.py, line 130: await self._QolsysPanel.mqtt_connect_task( (offender: /usr/local/lib/python3.13/site-packages/paho/mqtt/client.py, line 1285: context.load_cert_chain(certfile, keyfile, keyfile_password)), please create a bug report at https://github.com/EHylands/ha-qolsys-panel/issues For developers, please see https://developers.home-assistant.io/docs/asyncio_blocking_operations/#load_cert_chain Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/src/homeassistant/homeassistant/__main__.py", line 229, in <module> sys.exit(main()) File "/usr/src/homeassistant/homeassistant/__main__.py", line 215, in main exit_code = runner.run(runtime_conf) File "/usr/src/homeassistant/homeassistant/runner.py", line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File "/usr/local/lib/python3.13/asyncio/base_events.py", line 712, in run_until_complete self.run_forever() File "/usr/local/lib/python3.13/asyncio/base_events.py", line 683, in run_forever self._run_once() File "/usr/local/lib/python3.13/asyncio/base_events.py", line 2050, in _run_once handle._run() File "/usr/local/lib/python3.13/asyncio/events.py", line 89, in _run self._context.run(self._callback, *self._args) File "/usr/local/lib/python3.13/site-packages/aiohttp/web_protocol.py", line 510, in _handle_request resp = await request_handler(request) File "/usr/local/lib/python3.13/site-packages/aiohttp/web_app.py", line 569, in _handle return await handler(request) File "/usr/local/lib/python3.13/site-packages/aiohttp/web_middlewares.py", line 117, in impl return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 92, in security_filter_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 81, in forwarded_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 26, in request_context_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 86, in ban_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 242, in auth_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 41, in headers_middleware response = await handler(request) File "/usr/src/homeassistant/homeassistant/helpers/http.py", line 73, in handle result = await handler(request, **request.match_info) File "/usr/src/homeassistant/homeassistant/components/http/decorators.py", line 83, in with_admin return await func(self, request, *args, **kwargs) File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 234, in post return await super().post(request, flow_id) File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 74, in wrapper return await method(view, request, data, *args, **kwargs) File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 121, in post result = await self._flow_mgr.async_configure(flow_id, data) File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 346, in async_configure result = await self._async_configure(flow_id, user_input) File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 393, in _async_configure result = await self._async_handle_step( File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 493, in _async_handle_step result: _FlowResultT = await getattr(flow, method)(user_input) File "/config/custom_components/qolsys_panel/config_flow.py", line 130, in async_step_pki_autodiscovery_2 await self._QolsysPanel.mqtt_connect_task(
Detected blocking call to load_verify_locations with args (<ssl.SSLContext object at 0x7XXXXXXXXX>, '/config/qolsys_panel/pki/[REDACTED].qolsys') inside the event loop by custom integration 'qolsys_panel' at custom_components/qolsys_panel/config_flow.py, line 130: await self._QolsysPanel.mqtt_connect_task( (offender: /usr/local/lib/python3.13/site-packages/paho/mqtt/client.py, line 1293: context.load_verify_locations(ca_certs)), please create a bug report at https://github.com/EHylands/ha-qolsys-panel/issues For developers, please see https://developers.home-assistant.io/docs/asyncio_blocking_operations/#load_verify_locations Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/src/homeassistant/homeassistant/__main__.py", line 229, in <module> sys.exit(main()) File "/usr/src/homeassistant/homeassistant/__main__.py", line 215, in main exit_code = runner.run(runtime_conf) File "/usr/src/homeassistant/homeassistant/runner.py", line 289, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File "/usr/local/lib/python3.13/asyncio/base_events.py", line 712, in run_until_complete self.run_forever() File "/usr/local/lib/python3.13/asyncio/base_events.py", line 683, in run_forever self._run_once() File "/usr/local/lib/python3.13/asyncio/base_events.py", line 2050, in _run_once handle._run() File "/usr/local/lib/python3.13/asyncio/events.py", line 89, in _run self._context.run(self._callback, *self._args) File "/usr/local/lib/python3.13/site-packages/aiohttp/web_protocol.py", line 510, in _handle_request resp = await request_handler(request) File "/usr/local/lib/python3.13/site-packages/aiohttp/web_app.py", line 569, in _handle return await handler(request) File "/usr/local/lib/python3.13/site-packages/aiohttp/web_middlewares.py", line 117, in impl return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 92, in security_filter_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 81, in forwarded_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 26, in request_context_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 86, in ban_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 242, in auth_middleware return await handler(request) File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 41, in headers_middleware response = await handler(request) File "/usr/src/homeassistant/homeassistant/helpers/http.py", line 73, in handle result = await handler(request, **request.match_info) File "/usr/src/homeassistant/homeassistant/components/http/decorators.py", line 83, in with_admin return await func(self, request, *args, **kwargs) File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 234, in post return await super().post(request, flow_id) File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 74, in wrapper return await method(view, request, data, *args, **kwargs) File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 121, in post result = await self._flow_mgr.async_configure(flow_id, data) File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 346, in async_configure result = await self._async_configure(flow_id, user_input) File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 393, in _async_configure result = await self._async_handle_step( File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 493, in _async_handle_step result: _FlowResultT = await getattr(flow, method)(user_input) File "/config/custom_components/qolsys_panel/config_flow.py", line 130, in async_step_pki_autodiscovery_2 await self._QolsysPanel.mqtt_connect_task(

By the way, is it normal for each sensor entitiy name to called Zone 1, 2, etc.? When I think of a zone, I think like an area that could have many sensors, but could be a Qolsys thing that im not sure of.

Yes, the blocking call you reported is the one related to aiomqtt. It only blocks one time when the integration is loading tls certificates.

  • Zones are individual sensors (binary sensor + battery sensor + signal sensor in HA)
  • Partitions are what you are refering to as areas

You will also find:

  • Z-Wave devices
  • Virtual or ADC devices (can read virtual ADC garage door status, but not control them yet …)
2 Likes

Fantastic! Ok, im all set here. Monitoring beta related issues and will report if i see anything.

Cheers