mirror of https://github.com/espruino/BangleApps
Export a library for other apps
parent
02ca72a222
commit
eee3a8c0af
|
@ -1 +1,2 @@
|
||||||
0.01: Release
|
0.01: Release
|
||||||
|
0.02: Includeas the ha.lib.js library that can be used by other apps or clocks.
|
|
@ -1,13 +1,15 @@
|
||||||
# Home Assistant
|
# Home Assistant
|
||||||
This app integrates your BangleJs into the HomeAssistant.
|
This app integrates your BangleJs into the HomeAssistant.
|
||||||
|
|
||||||
|
|
||||||
# How to use
|
# How to use
|
||||||
Click on the left and right side of the screen to select the triggers that you
|
Click on the left and right side of the screen to select the triggers that you
|
||||||
configured. Click in the middle of the screen to send the trigger to HomeAssistant.
|
configured. Click in the middle of the screen to send the trigger to HomeAssistant.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# First Setup
|
|
||||||
|
# Initial Setup
|
||||||
1.) First of all, make sure that HomeAssistant and the HomeAssistant Android App works.
|
1.) First of all, make sure that HomeAssistant and the HomeAssistant Android App works.
|
||||||
|
|
||||||
2.) Open your BangleJs Gadgetbridge App, click on the Settings icon of your BangleJs and enable "Allow Intent Access"
|
2.) Open your BangleJs Gadgetbridge App, click on the Settings icon of your BangleJs and enable "Allow Intent Access"
|
||||||
|
@ -22,6 +24,7 @@ configured. Click in the middle of the screen to send the trigger to HomeAssista
|
||||||
This setup must be done only once -- now you are ready to configure your BangleJS to
|
This setup must be done only once -- now you are ready to configure your BangleJS to
|
||||||
control some devices or entities in your HomeAssistant :)
|
control some devices or entities in your HomeAssistant :)
|
||||||
|
|
||||||
|
|
||||||
# Setup Trigger
|
# Setup Trigger
|
||||||
1.) Upload the app and all corresponding triggers through the AppStore UI. You must specify
|
1.) Upload the app and all corresponding triggers through the AppStore UI. You must specify
|
||||||
the display name, the trigger as well as an icon.
|
the display name, the trigger as well as an icon.
|
||||||
|
@ -38,12 +41,36 @@ The following icons are currently supported:
|
||||||
|
|
||||||
3.) Don't forget to select the action that should be executed at the bottom of each automation.
|
3.) Don't forget to select the action that should be executed at the bottom of each automation.
|
||||||
|
|
||||||
|
|
||||||
# Default Trigger
|
# Default Trigger
|
||||||
This app also implements two default trigger that can always be used:
|
This app also implements two default trigger that can always be used:
|
||||||
- APP_STARTED -- Will be sent whenever the app is started. So you could do some actions already when the app is sarted without the need of any user interaction.
|
- APP_STARTED -- Will be sent whenever the app is started. So you could do some actions already when the app is sarted without the need of any user interaction.
|
||||||
- TRIGGER -- Will be sent whenever some trigger is executed. So you could generically listen to that.
|
- TRIGGER -- Will be sent whenever some trigger is executed. So you could generically listen to that.
|
||||||
|
|
||||||
|
|
||||||
|
# How to use the library (ha.lib.js) in my own app/clk
|
||||||
|
This app inlcludes a library that can be used by other apps or clocks
|
||||||
|
to read all configured intents or to send a trigger. Example code:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// First of all impport the library
|
||||||
|
var ha = require("ha.lib.js");
|
||||||
|
|
||||||
|
// You can read all triggers that a user configured simply via
|
||||||
|
var triggers = ha.getTriggers();
|
||||||
|
|
||||||
|
// Get display name and icon of trigger
|
||||||
|
var display = triggers[0].display;
|
||||||
|
var icon = triggers[0].getIcon();
|
||||||
|
|
||||||
|
// Trigger the first configured trigger
|
||||||
|
ha.sendTrigger(triggers[0].trigger);
|
||||||
|
|
||||||
|
// Send a custom trigger that is not configured by a user
|
||||||
|
ha.sendTrigger("MY_CUSTOM_TRIGGER");
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
|
|
||||||
## Sometimes the trigger is not executed
|
## Sometimes the trigger is not executed
|
||||||
|
|
|
@ -1,72 +1,10 @@
|
||||||
var storage = require("Storage");
|
/**
|
||||||
|
* This app uses the ha library to send trigger to HomeAssistant.
|
||||||
|
*/
|
||||||
|
var ha = require("ha.lib.js");
|
||||||
var W = g.getWidth(), H = g.getHeight();
|
var W = g.getWidth(), H = g.getHeight();
|
||||||
var position=0;
|
var position=0;
|
||||||
|
var triggers = ha.getTriggers();
|
||||||
|
|
||||||
// Note: All icons should have 48x48 pixels
|
|
||||||
function getIcon(icon){
|
|
||||||
if(icon == "light"){
|
|
||||||
return {
|
|
||||||
width : 48, height : 48, bpp : 1,
|
|
||||||
transparent : 0,
|
|
||||||
buffer : require("heatshrink").decompress(atob("AAMBwAFE4AFDgYFJjgFBnAFBjwXBvAFBh4jBuAFCAQPwAQMHAQPgEQQCBEgcf/AvDn/8Aof//5GDAoJOBh+BAoOB+EP8YFB4fwgfnAoPnGANHAoPjHYQFBHYQFd44pDg47C4/gh/DIIZNFLIplGgF//wFIgZ9BRIUHRII7Ch4FBUIUOAoKzCjwFEhgCBmDpIVooFFh4oCAA4LFC5b7BAob1BAYI="))
|
|
||||||
};
|
|
||||||
} else if(icon == "door"){
|
|
||||||
return {
|
|
||||||
width : 48, height : 48, bpp : 1,
|
|
||||||
transparent : 0,
|
|
||||||
buffer : require("heatshrink").decompress(atob("AAM4Aok/4AED///Aov4Aon8DgQGBAv4FpnIFKJv4FweAQFFAgQFB8AFDnADC"))
|
|
||||||
};
|
|
||||||
} else if (icon == "fire"){
|
|
||||||
return {
|
|
||||||
width : 48, height : 48, bpp : 1,
|
|
||||||
transparent : 0,
|
|
||||||
buffer : require("heatshrink").decompress(atob("ABsDAokBwAFE4AFE8AFE+AFE/AFJgf8Aon+AocHAokP/8QAokYAoUfAok//88ApF//4kDAo//AgMQAgIFCjgFEjwFCOYIFFHQIFDn/+AoJ/BAoIqBAoN//xCBAoI5BDIPAgP//gFB8AFChYFBgf//EJAogOBAoSgBAoMHAQIFEFgXAAoJEBv4FCNoQFGVYd/wAFEYYIFIvwCBDoV8UwQCBcgUPwDwDfQMBaIYADA"))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default is always the HA icon
|
|
||||||
return {
|
|
||||||
width : 48, height : 48, bpp : 1,
|
|
||||||
transparent : 0,
|
|
||||||
buffer : require("heatshrink").decompress(atob("AD8BwAFDg/gAocP+AFDj4FEn/8Aod//wFD/1+FAf4j+8AoMD+EPDAUH+OPAoUP+fPAoUfBYk/C4l/EYIwC//8n//FwIFEgYFD4EH+E8nkP8BdBAonjjk44/wj/nzk58/4gAFDF4PgCIMHAoPwhkwh4FB/EEkEfIIWAHwIFC4A+BAoXgg4FDL4IFDL4IFDLIYFkAEQA=="))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to read custom actions, otherwise use default
|
|
||||||
var triggers = [
|
|
||||||
{display: "Not found.", trigger: "NOP", icon: "ha"},
|
|
||||||
];
|
|
||||||
|
|
||||||
try{
|
|
||||||
triggers = storage.read("ha.trigger.json");
|
|
||||||
triggers = JSON.parse(triggers);
|
|
||||||
} catch(e) {
|
|
||||||
// In case there are no user triggers yet, we show the default...
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function sendIntent(trigger){
|
|
||||||
var retries=3;
|
|
||||||
|
|
||||||
while(retries > 0){
|
|
||||||
try{
|
|
||||||
// Send a startup trigger such that we could also execute
|
|
||||||
// an action when the app is started :)
|
|
||||||
Bluetooth.println(JSON.stringify({
|
|
||||||
t:"intent",
|
|
||||||
action:"com.espruino.gadgetbridge.banglejs.HA",
|
|
||||||
extra:{
|
|
||||||
trigger: trigger
|
|
||||||
}})
|
|
||||||
);
|
|
||||||
retries = -1;
|
|
||||||
|
|
||||||
} catch(e){
|
|
||||||
retries--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
|
@ -78,7 +16,7 @@ function draw() {
|
||||||
var w = g.stringWidth(trigger.display);
|
var w = g.stringWidth(trigger.display);
|
||||||
|
|
||||||
g.setFontAlign(-1,-1);
|
g.setFontAlign(-1,-1);
|
||||||
var icon = getIcon(trigger.icon);
|
var icon = ha.getIcon(trigger.getIcon());
|
||||||
g.setColor(g.theme.fg).drawImage(icon, 12, H/5-2);
|
g.setColor(g.theme.fg).drawImage(icon, 12, H/5-2);
|
||||||
g.drawString("Home", icon.width + 20, H/5);
|
g.drawString("Home", icon.width + 20, H/5);
|
||||||
g.drawString("Assistant", icon.width + 18, H/5+24);
|
g.drawString("Assistant", icon.width + 18, H/5+24);
|
||||||
|
@ -112,13 +50,9 @@ Bangle.on('touch', function(btn, e){
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isRight && !isLeft){
|
if(!isRight && !isLeft){
|
||||||
|
|
||||||
// Send a default intent that we triggered something.
|
|
||||||
sendIntent("TRIGGER");
|
|
||||||
|
|
||||||
// Now send the selected trigger
|
// Now send the selected trigger
|
||||||
Bangle.buzz(80, 0.6).then(()=>{
|
Bangle.buzz(80, 0.6).then(()=>{
|
||||||
sendIntent(triggers[position].trigger);
|
ha.sendTrigger(triggers[position].trigger);
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
Bangle.buzz(80, 0.6);
|
Bangle.buzz(80, 0.6);
|
||||||
}, 250);
|
}, 250);
|
||||||
|
@ -126,12 +60,14 @@ Bangle.on('touch', function(btn, e){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Send intent that the we started the app.
|
// Send intent that the we started the app.
|
||||||
sendIntent("APP_STARTED");
|
ha.sendTrigger("APP_STARTED");
|
||||||
|
|
||||||
// Next load the widgets and draw the app
|
// Next load the widgets and draw the app
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
|
// Draw app
|
||||||
draw();
|
draw();
|
||||||
setWatch(_=>load(), BTN1);
|
setWatch(_=>load(), BTN1);
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* This library can be used to read all triggers that a user
|
||||||
|
* configured and send a trigger to homeassistant.
|
||||||
|
*/
|
||||||
|
function _getIcon(trigger){
|
||||||
|
icon = trigger.icon;
|
||||||
|
if(icon == "light"){
|
||||||
|
return {
|
||||||
|
width : 48, height : 48, bpp : 1,
|
||||||
|
transparent : 0,
|
||||||
|
buffer : require("heatshrink").decompress(atob("AAMBwAFE4AFDgYFJjgFBnAFBjwXBvAFBh4jBuAFCAQPwAQMHAQPgEQQCBEgcf/AvDn/8Aof//5GDAoJOBh+BAoOB+EP8YFB4fwgfnAoPnGANHAoPjHYQFBHYQFd44pDg47C4/gh/DIIZNFLIplGgF//wFIgZ9BRIUHRII7Ch4FBUIUOAoKzCjwFEhgCBmDpIVooFFh4oCAA4LFC5b7BAob1BAYI="))
|
||||||
|
};
|
||||||
|
} else if(icon == "door"){
|
||||||
|
return {
|
||||||
|
width : 48, height : 48, bpp : 1,
|
||||||
|
transparent : 0,
|
||||||
|
buffer : require("heatshrink").decompress(atob("AAM4Aok/4AED///Aov4Aon8DgQGBAv4FpnIFKJv4FweAQFFAgQFB8AFDnADC"))
|
||||||
|
};
|
||||||
|
} else if (icon == "fire"){
|
||||||
|
return {
|
||||||
|
width : 48, height : 48, bpp : 1,
|
||||||
|
transparent : 0,
|
||||||
|
buffer : require("heatshrink").decompress(atob("ABsDAokBwAFE4AFE8AFE+AFE/AFJgf8Aon+AocHAokP/8QAokYAoUfAok//88ApF//4kDAo//AgMQAgIFCjgFEjwFCOYIFFHQIFDn/+AoJ/BAoIqBAoN//xCBAoI5BDIPAgP//gFB8AFChYFBgf//EJAogOBAoSgBAoMHAQIFEFgXAAoJEBv4FCNoQFGVYd/wAFEYYIFIvwCBDoV8UwQCBcgUPwDwDfQMBaIYADA"))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default is always the HA icon
|
||||||
|
return {
|
||||||
|
width : 48, height : 48, bpp : 1,
|
||||||
|
transparent : 0,
|
||||||
|
buffer : require("heatshrink").decompress(atob("AD8BwAFDg/gAocP+AFDj4FEn/8Aod//wFD/1+FAf4j+8AoMD+EPDAUH+OPAoUP+fPAoUfBYk/C4l/EYIwC//8n//FwIFEgYFD4EH+E8nkP8BdBAonjjk44/wj/nzk58/4gAFDF4PgCIMHAoPwhkwh4FB/EEkEfIIWAHwIFC4A+BAoXgg4FDL4IFDL4IFDLIYFkAEQA=="))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getTriggers = function(){
|
||||||
|
var triggers = [
|
||||||
|
{display: "Empty", trigger: "NOP", icon: "ha"},
|
||||||
|
];
|
||||||
|
|
||||||
|
try{
|
||||||
|
triggers = require("Storage").read("ha.trigger.json");
|
||||||
|
triggers = JSON.parse(triggers);
|
||||||
|
|
||||||
|
// We lazy load all icons, otherwise, we have to keep
|
||||||
|
// all the icons n times in memory which can be
|
||||||
|
// problematic for embedded devices. Therefore,
|
||||||
|
// we lazy load icons only if needed using the getIcon
|
||||||
|
// method of each trigger...
|
||||||
|
triggers.forEach(trigger => {
|
||||||
|
trigger.getIcon = function(){
|
||||||
|
return _getIcon(trigger);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch(e) {
|
||||||
|
// In case there are no user triggers yet, we show the default...
|
||||||
|
}
|
||||||
|
|
||||||
|
return triggers;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.sendTrigger = function(triggerName){
|
||||||
|
var retries=3;
|
||||||
|
|
||||||
|
while(retries > 0){
|
||||||
|
try{
|
||||||
|
// First send a generic trigger which can be used
|
||||||
|
// to listen to all trigger send.
|
||||||
|
Bluetooth.println(JSON.stringify({
|
||||||
|
t:"intent",
|
||||||
|
action:"com.espruino.gadgetbridge.banglejs.HA",
|
||||||
|
extra:{
|
||||||
|
trigger: "TRIGGER"
|
||||||
|
}})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Now lets send the trigger that we sould send.
|
||||||
|
Bluetooth.println(JSON.stringify({
|
||||||
|
t:"intent",
|
||||||
|
action:"com.espruino.gadgetbridge.banglejs.HA",
|
||||||
|
extra:{
|
||||||
|
trigger: triggerName
|
||||||
|
}})
|
||||||
|
);
|
||||||
|
retries = -1;
|
||||||
|
|
||||||
|
} catch(e){
|
||||||
|
retries--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "ha",
|
"id": "ha",
|
||||||
"name": "HomeAssistant",
|
"name": "HomeAssistant",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "Integrates your BangleJS into HomeAssistant.",
|
"description": "Integrates your BangleJS into HomeAssistant.",
|
||||||
"icon": "ha.png",
|
"icon": "ha.png",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
],
|
],
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"ha.app.js","url":"ha.app.js"},
|
{"name":"ha.app.js","url":"ha.app.js"},
|
||||||
|
{"name":"ha.lib.js","url":"ha.lib.js"},
|
||||||
{"name":"ha.img","url":"ha.icon.js","evaluate":true}
|
{"name":"ha.img","url":"ha.icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue