Warning
This project is not affiliated with, endorsed by, or supported by Crestron. It is very likely that Crestron will not like this project at all, and will not support anything done as part of it. This project uses a decent number of undocumented features that are subject to change at any time for any reason.
DO NOT USE THIS PROJECT FOR PAYING CLIENTS OR DEPLOY IT IN A PROFESSIONAL ENVIRONMENT. This project makes absolutely zero promises as to its stability and reliability, and use in production environments will cause significant trouble when something inevitably breaks. This is NOT a replacement for a properly-configured and competently-programmed Crestron control system.
Caution
This project is still under active development, and nothing should be considered stable at this time. Significant work is still necessary before this is ready to use outside of lab settings.
The ch5-ha-bridge aims to bridge the gap between Crestron tablets (such as the TSW-xx60 and TSW-xx70 product lines)
and open smart home projects like Home Assistant. It works standalone, meaning there is no need for a central
processor or any controlled programming. Everything lives, to the best of its ability, within the context of the tablet
itself. Root/debug access to the tablet is NOT required to use this application!
This project aims to bridge the gap between Crestron tablets (e.g. the TSW xx60 and xx70 product lines) and Home Assistant, allowing deep integration without needing a control processor or the ability to do custom programming on a Crestron system. To this end, this project makes extensive use of Crestron's CrComLib to interact with the tablet and its joins, and uses MQTT to speak to Home Assistant or any other MQTT consumer. Many of the insights in this project came from staring at CrComLib's code and throwing various things at the wall in an attempt to make things work.
This project makes use of the CH5 React TS Template as its base.
This is a standard Vite project, so just run yarn install to install deps, yarn build:dev to build the dist files,
and then yarn:archive to generate a .ch5z file.
You will also need to copy .env.template to .env and fill in any appropriate values for your system.
At present, there are a few extra required steps to deploy this project in a typical Home Assistant environment. These are temporary (sorta) until the bootloader and all relevant code is completed, and are not included in the project pipeline because the underyling code is unlikely to change regularly.
- Compile
polyfill_localstorage.tsto JavaScript using your favorite TypeScript compiler. - Place
coldboot.htmland your compiledpolyfill_localstorage.jsfile inwww/crestronon your HA server. - Define the
VITE_HA_DASHBOARD_URLashttp://YOUR_HA_HOST/local/crestron/coldboot.html?redirect_to=/your/dashboard/url - Make the following changes to your HA
configuration.yaml:frontend: extra_module_url: - /local/crestron/polyfill_localstorage.js http: use_x_frame_options: false
If HTTPS access is desired and a publicly-trusted certificate is not available, you will need to load all relevant certificates on the panel. Note that HTTPS has not been thoroughly tested, and may cause other problems I don't know about yet.
Also note that setting http.use_x_frame_options will make your Home Assistant install
slightly less secure. A proposal is open to fix this, but additional work will be necessary
on the Home Assistant side for this.
As of now, this project is very much a proof of concept. It will not run properly without configuration changes to Home Assistant, and there are still unanswered questions regarding how best to tie things in properly.
There are plans to build a proper "bootloader" app to fetch the latest JavaScript from the Home Assistant install to facilitate easy app updates, as well as remote configuration and other niceties.
Help is very much welcome here!
At the moment, the actual integration component is roughly split into three distinct layers:
- The
interoplayer contains Crestron specific logic and "controllers" that are designed to make the join system more accessible and usable in TypeScript land. It's helpful to consider this layer to be the "drivers" behind the project. - The
serviceslayer exposes Crestron state to the world, either from an interop controller or directly via the CrComLib interface. - The
behaviorslayer contains on-device business logic to control the tablet and its operation.
Of these layers, services is (by design) opinionated to translate things into a Home Assistant and architecturally
friendly pattern. The behaviors layer is extremely opinionated and will likely be moved somewhere else in the
future to allow users to define and control their own logic.
The following is a list of MQTT topics that this project currently implements. All custom MQTT events will be placed in
the crestron/ch5_mqtt/{PanelModel}_{PanelSerial} namespace, with the following subtopics:
/joins- Joins subsystem./{JoinType}/{JoinName}(R/W) - API to access joins directly./_subscribe(W) - Special topic to force subscribing to a join. No payload is used./_unsubscribe(W) - Special topic to force unsubscribing from a join. No payload is used.
/_subscribeAll(W) - Special topic to subscribe to all joins the panel is currently aware of. No payload is used.
/hardButton- Hard Button subsystem/{ButtonName}/press(R) - Indication that a button was pressed.truewhen pressed,falsewhen released./{ButtonName}/active(R/W) - State of the button.trueif the LED is lit and the button can be used./brightness(R/W) - Brightness of the hard button LEDs, from 0 to 65535. Not respected if autobrightness is enabled.
/ledAccessory- LED accessory subsystem/control./available(R, persistent) -trueif the LED accessory is available,falseotherwise./color(R/W) - Color of the LED accessory. Accepts hex, color names, tuple, or{"r":100,"g":100,"b":100}./brightness(R/W) - Brightness of the LED accessory, from 0 to 100./power(R/W) - Power state of the LED accessory,truefor on,falsefor off.
When accessing joins through the /joins topic, the join type will be one of boolean, integer, string, or
object. Join names are defined by the Reserved Join Viewers in the Crestron documentation, though certain
other undocumented joins may also be available.
When reading a join, the State name will be used, which normally will be suffixed with _fb. Subscriptions can only
be made to these states, not events.
When writing to a join, use the Event name, which will normally not be suffixed with _fb.