Hi everyone,
I wanted to share a project I’ve been working on, a React settings page. It allows to use all the homey
functions inside the React app. I used TypeScript since I prefer it over JS but you can also use JS.
Also, I used class components instead of the more modern functional components, but this is purely personal preference.
You need 3 files to make it work.
<!DOCTYPE html>
<html lang="en" style="padding: 0 !important;">
<head>
<meta charset="utf-8"/>
<script data-origin="settings" src="/homey.js" type="text/javascript"></script>
<script type="text/javascript">
function onHomeyReady(Homey) {
window.Homey = Homey;
Homey.ready();
window.HomeyReady = true;
}
</script>
</head>
<body style="padding: 0 !important; min-height: auto !important;">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
The index.html
binds the Homey
object to the window
object. Homey can be used inside React using the window
scope. The body
style is optional, it makes the app full size so it looks better.
For development, you can include the homey.css
in this index.html
file.
<link href="https://<cloud-id>.connect.athom.com/manager/webserver/assets/css/homey.css" rel="stylesheet">
import {HomeyAPI} from './Homey';
declare global {
interface Window {
Homey: HomeyAPI;
HomeyReady: boolean;
}
}
export const Homey: HomeyAPI = window.Homey;
This makes the window.Homey
object available in the typescript scope.
export interface HomeyAPI {
__(key: string, tokens?: Object): string;
ready(callback?: () => void): void;
alert(message: string, callback?: () => void): void;
confirm(eventName: string, listener: HomeyEventListener): Promise<any>;
popup(url: string): void;
trigger(eventName: string, data?: Record<string, any>): Promise<any>;
get(key: string, callback?: (value: any) => void): Promise<any>;
set(key: string, value: any, callback?: (err: any) => void): Promise<any>;
unset(key: string, callback?: (value: any) => void): Promise<any>;
api(key: string, path: string, body: any, callback?: () => void): Promise<any>;
}
export default class Homey {
public static __(key: string, tokens?: Object) {
if (window.HomeyReady)
return window.Homey.__(key, tokens) ?? key;
else return key;
}
public static set(key: string, value: any, callback?: (value: any) => void) {
if (window.HomeyReady) return window.Homey.set(key, value, callback);
}
public static unset(key: string, callback?: (value: any) => void) {
if (window.HomeyReady)
return window.Homey.unset(key, callback);
}
public static get(key: string, callback?: (value: any) => void) {
if (window.HomeyReady) return window.Homey.get(key, callback);
}
public static api(key: string, path: string, body: any, callback?: () => void) {
if (window.HomeyReady) return window.Homey.api(key, path, body, callback);
}
public static alert(message: string, callback?: () => void) {
if (window.HomeyReady) return window.Homey.alert(message, callback);
}
public static confirm(message: string, callback: HomeyEventListener) {
if (window.HomeyReady) return window.Homey.confirm(message, callback);
}
public static popup(url: string) {
if (window.HomeyReady) return window.Homey.popup(url);
}
public static trigger(eventName: string, callback?: (err: any) => void) {
if (window.HomeyReady) return window.Homey.trigger(eventName, callback);
}
}
export interface HomeyEvent {
name: string;
data?: Record<string, unknown>;
}
export interface HomeyEventListener {
(event: HomeyEvent): void;
}
For the full project, take a look here.
Also, I would recommend making a check to see if “window.HomeyReady” is true before displaying any data. Like here.
You can use all the Homey function calling the static Homey file. e.g. Homey.set('myVar', true, (err) => console.log('hello world'));
This is how I used it to get the data when it was needed.
If you have any questions, let me know.
Best regards