diff --git a/apps/ha/ChangeLog b/apps/ha/ChangeLog index 07afedd21..e78b4ccd0 100644 --- a/apps/ha/ChangeLog +++ b/apps/ha/ChangeLog @@ -1 +1,2 @@ -0.01: Release \ No newline at end of file +0.01: Release +0.02: Includeas the ha.lib.js library that can be used by other apps or clocks. \ No newline at end of file diff --git a/apps/ha/README.md b/apps/ha/README.md index 8005421f1..654a262c8 100644 --- a/apps/ha/README.md +++ b/apps/ha/README.md @@ -1,13 +1,15 @@ # Home Assistant This app integrates your BangleJs into the HomeAssistant. + # How to use 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. ![](screenshot.png) -# First Setup + +# Initial Setup 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" @@ -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 control some devices or entities in your HomeAssistant :) + # Setup Trigger 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. @@ -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. + # Default Trigger 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. - 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 ## Sometimes the trigger is not executed diff --git a/apps/ha/ha.app.js b/apps/ha/ha.app.js index 85f926138..9ad8db8fa 100644 --- a/apps/ha/ha.app.js +++ b/apps/ha/ha.app.js @@ -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 position=0; - - -// 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--; - } - } -} +var triggers = ha.getTriggers(); function draw() { @@ -78,7 +16,7 @@ function draw() { var w = g.stringWidth(trigger.display); 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.drawString("Home", icon.width + 20, H/5); g.drawString("Assistant", icon.width + 18, H/5+24); @@ -112,13 +50,9 @@ Bangle.on('touch', function(btn, e){ } if(!isRight && !isLeft){ - - // Send a default intent that we triggered something. - sendIntent("TRIGGER"); - // Now send the selected trigger Bangle.buzz(80, 0.6).then(()=>{ - sendIntent(triggers[position].trigger); + ha.sendTrigger(triggers[position].trigger); setTimeout(()=>{ Bangle.buzz(80, 0.6); }, 250); @@ -126,12 +60,14 @@ Bangle.on('touch', function(btn, e){ } }); + // Send intent that the we started the app. -sendIntent("APP_STARTED"); +ha.sendTrigger("APP_STARTED"); // Next load the widgets and draw the app Bangle.loadWidgets(); Bangle.drawWidgets(); +// Draw app draw(); setWatch(_=>load(), BTN1); diff --git a/apps/ha/ha.lib.js b/apps/ha/ha.lib.js new file mode 100644 index 000000000..0de98d62a --- /dev/null +++ b/apps/ha/ha.lib.js @@ -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--; + } + } +} \ No newline at end of file diff --git a/apps/ha/metadata.json b/apps/ha/metadata.json index 0f9929d8c..63308b933 100644 --- a/apps/ha/metadata.json +++ b/apps/ha/metadata.json @@ -1,7 +1,7 @@ { "id": "ha", "name": "HomeAssistant", - "version": "0.01", + "version": "0.02", "description": "Integrates your BangleJS into HomeAssistant.", "icon": "ha.png", "type": "app", @@ -19,6 +19,7 @@ ], "storage": [ {"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} ] }