mirror of https://github.com/espruino/BangleApps
hadash: remember scoll positions of menus; "silent" option for service calls
parent
b54b0539c3
commit
3b955b6d12
|
@ -1 +1,2 @@
|
||||||
1.00: initial release
|
1.00: initial release
|
||||||
|
1.01: remember scoll positions of menus; "silent" option for service calls
|
||||||
|
|
|
@ -58,8 +58,6 @@ that token in case your watch is stolen or lost.
|
||||||
## To-Do
|
## To-Do
|
||||||
|
|
||||||
- A better way to configure the menu structure would be useful, something like a custom editor (replacing the jsoneditor).
|
- A better way to configure the menu structure would be useful, something like a custom editor (replacing the jsoneditor).
|
||||||
- After showing a state or call a service, return to the same point in the menu.
|
|
||||||
- Config option for service calls to not show a "successful" prompt
|
|
||||||
|
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
const APP_NAME = 'hadash';
|
const APP_NAME = 'hadash';
|
||||||
|
|
||||||
|
var scroller;
|
||||||
|
|
||||||
// Load settings
|
// Load settings
|
||||||
var settings = Object.assign({
|
var settings = Object.assign({
|
||||||
menu: [
|
menu: [
|
||||||
|
@ -13,7 +15,7 @@ var settings = Object.assign({
|
||||||
{ type: 'menu', title: 'Sub-menu', data:
|
{ type: 'menu', title: 'Sub-menu', data:
|
||||||
[
|
[
|
||||||
{ type: 'state', title: 'Check for Supervisor updates', id: 'update.home_assistant_supervisor_update' },
|
{ type: 'state', title: 'Check for Supervisor updates', id: 'update.home_assistant_supervisor_update' },
|
||||||
{ type: 'service', title: 'Restart HA', domain: 'homeassistant', service: 'restart', data: {} }
|
{ type: 'service', title: 'Restart HA', domain: 'homeassistant', service: 'restart', silent: true, data: {} }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ type: 'service', title: 'Custom Notification', domain: 'persistent_notification', service: 'create',
|
{ type: 'service', title: 'Custom Notification', domain: 'persistent_notification', service: 'create',
|
||||||
|
@ -28,6 +30,7 @@ var settings = Object.assign({
|
||||||
|
|
||||||
// query an entity state
|
// query an entity state
|
||||||
function queryState(title, id, level) {
|
function queryState(title, id, level) {
|
||||||
|
menus[level][''].scroll = scroller.scroll;
|
||||||
E.showMessage('Fetching entity state from HA', { title: title });
|
E.showMessage('Fetching entity state from HA', { title: title });
|
||||||
Bangle.http(settings.HAbaseUrl+'/states/'+id, {
|
Bangle.http(settings.HAbaseUrl+'/states/'+id, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -45,16 +48,17 @@ function queryState(title, id, level) {
|
||||||
if ('unit_of_measurement' in HAresp.attributes)
|
if ('unit_of_measurement' in HAresp.attributes)
|
||||||
msg += HAresp.attributes.unit_of_measurement;
|
msg += HAresp.attributes.unit_of_measurement;
|
||||||
}
|
}
|
||||||
E.showPrompt(msg, { title: title4prompt, buttons: {OK: true} }).then((v) => { E.showMenu(menus[level]); });
|
E.showPrompt(msg, { title: title4prompt, buttons: {OK: true} }).then((v) => { scroller = E.showMenu(menus[level]).scroller; });
|
||||||
}).catch( error => {
|
}).catch( error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
E.showPrompt('Error querying state!', { title: title, buttons: {OK: true} }).then((v) => { E.showMenu(menus[level]); });
|
E.showPrompt('Error querying state!', { title: title, buttons: {OK: true} }).then((v) => { scroller = E.showMenu(menus[level]).scroller; });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// call a service
|
// call a service
|
||||||
function callService(title, domain, service, data, level) {
|
function callService(title, domain, service, data, level, silent) {
|
||||||
|
menus[level][''].scroll = scroller.scroll;
|
||||||
E.showMessage('Calling HA service', { title: title });
|
E.showMessage('Calling HA service', { title: title });
|
||||||
Bangle.http(settings.HAbaseUrl+'/services/'+domain+'/'+service, {
|
Bangle.http(settings.HAbaseUrl+'/services/'+domain+'/'+service, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -65,10 +69,14 @@ function callService(title, domain, service, data, level) {
|
||||||
},
|
},
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
//console.log(data);
|
//console.log(data);
|
||||||
E.showPrompt('Service called successfully', { title: title, buttons: {OK: true} }).then((v) => { E.showMenu(menus[level]); });
|
if (silent) {
|
||||||
|
scroller = E.showMenu(menus[level]).scroller;
|
||||||
|
} else {
|
||||||
|
E.showPrompt('Service called successfully', { title: title, buttons: {OK: true} }).then((v) => { scroller = E.showMenu(menus[level]).scroller; });
|
||||||
|
}
|
||||||
}).catch( error => {
|
}).catch( error => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
E.showPrompt('Error calling service!', { title: title, buttons: {OK: true} }).then((v) => { E.showMenu(menus[level]); });
|
E.showPrompt('Error calling service!', { title: title, buttons: {OK: true} }).then((v) => { scroller = E.showMenu(menus[level]).scroller; });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,10 +96,11 @@ function serviceInputFreeform(key, entry, level) {
|
||||||
|
|
||||||
// get input data before calling a service
|
// get input data before calling a service
|
||||||
function getServiceInputData(entry, level) {
|
function getServiceInputData(entry, level) {
|
||||||
|
menus[level][''].scroll = scroller.scroll;
|
||||||
let serviceInputMenu = {
|
let serviceInputMenu = {
|
||||||
'': {
|
'': {
|
||||||
'title': entry.title,
|
'title': entry.title,
|
||||||
'back': () => E.showMenu(menus[level])
|
'back': () => scroller = E.showMenu(menus[level]).scroller
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let CBs = {};
|
let CBs = {};
|
||||||
|
@ -130,7 +139,7 @@ function getServiceInputData(entry, level) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// menu entry to actually call the service:
|
// menu entry to actually call the service:
|
||||||
serviceInputMenu['Call service'] = function() { callService(entry.title, entry.domain, entry.service, entry.data, level); };
|
serviceInputMenu['Call service'] = function() { callService(entry.title, entry.domain, entry.service, entry.data, level, entry.silent); };
|
||||||
E.showMenu(serviceInputMenu);
|
E.showMenu(serviceInputMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +172,8 @@ function addMenuEntries(level, entries) {
|
||||||
/*
|
/*
|
||||||
* call HA service
|
* call HA service
|
||||||
*/
|
*/
|
||||||
|
if (! ('silent' in entry))
|
||||||
|
entry.silent = false;
|
||||||
if ('domain' in entry && entry.domain && 'service' in entry && entry.service) {
|
if ('domain' in entry && entry.domain && 'service' in entry && entry.service) {
|
||||||
if (! ('data' in entry))
|
if (! ('data' in entry))
|
||||||
entry.data = {};
|
entry.data = {};
|
||||||
|
@ -171,7 +182,7 @@ function addMenuEntries(level, entries) {
|
||||||
entryCB = () => setTimeout(getServiceInputData, 10, entry, level);
|
entryCB = () => setTimeout(getServiceInputData, 10, entry, level);
|
||||||
} else {
|
} else {
|
||||||
// call service straight away
|
// call service straight away
|
||||||
entryCB = () => setTimeout(callService, 10, entry.title, entry.domain, entry.service, entry.data, level);
|
entryCB = () => setTimeout(callService, 10, entry.title, entry.domain, entry.service, entry.data, level, entry.silent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -196,14 +207,15 @@ function addMenuEntries(level, entries) {
|
||||||
|
|
||||||
// create and show a sub menu
|
// create and show a sub menu
|
||||||
function showSubMenu(level, title, entries) {
|
function showSubMenu(level, title, entries) {
|
||||||
|
menus[level - 1][''].scroll = scroller.scroll;
|
||||||
menus[level] = {
|
menus[level] = {
|
||||||
'': {
|
'': {
|
||||||
'title': title,
|
'title': title,
|
||||||
'back': () => E.showMenu(menus[level - 1])
|
'back': () => scroller = E.showMenu(menus[level - 1]).scroller
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
addMenuEntries(level, entries);
|
addMenuEntries(level, entries);
|
||||||
E.showMenu(menus[level]);
|
scroller = E.showMenu(menus[level]).scroller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,8 +232,8 @@ addMenuEntries(0, settings.menu);
|
||||||
|
|
||||||
// check required configuration
|
// check required configuration
|
||||||
if (! settings.HAbaseUrl || ! settings.HAtoken) {
|
if (! settings.HAbaseUrl || ! settings.HAtoken) {
|
||||||
E.showAlert('The app is not yet configured!', 'HA-Dash').then(() => E.showMenu(menus[0]));
|
E.showAlert('The app is not yet configured!', 'HA-Dash').then(() => scroller = E.showMenu(menus[0]).scroller);
|
||||||
} else {
|
} else {
|
||||||
E.showMenu(menus[0]);
|
scroller = E.showMenu(menus[0]).scroller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
"title": "Menu entry title",
|
"title": "Menu entry title",
|
||||||
"domain": "HA Domain",
|
"domain": "HA Domain",
|
||||||
"service": "HA Service",
|
"service": "HA Service",
|
||||||
|
"silent": (true|false),
|
||||||
"data": {
|
"data": {
|
||||||
"key": "value"
|
"key": "value"
|
||||||
}
|
}
|
||||||
|
@ -64,8 +65,10 @@
|
||||||
under the Developer tools -> Services. Use the "Go to YAML Mode"
|
under the Developer tools -> Services. Use the "Go to YAML Mode"
|
||||||
function to see the actual names and values. The domain and service
|
function to see the actual names and values. The domain and service
|
||||||
parts are the 2 parts of the service name which are separated by a dot.
|
parts are the 2 parts of the service name which are separated by a dot.
|
||||||
Any (optional) data key/value pairs can be added under the "data"
|
If the optional "silent" boolean is set to true (false is default),
|
||||||
field. For example, here's a service call YAML:
|
there will be no message in case of a successful call. Any (optional)
|
||||||
|
data key/value pairs can be added under the "data" field. For example,
|
||||||
|
here's a service call YAML:
|
||||||
<pre class="code" data-lang="YAML">
|
<pre class="code" data-lang="YAML">
|
||||||
service: persistent_notification.create
|
service: persistent_notification.create
|
||||||
data:
|
data:
|
||||||
|
@ -207,7 +210,7 @@ target:
|
||||||
{ type: 'menu', title: 'Sub-menu', data:
|
{ type: 'menu', title: 'Sub-menu', data:
|
||||||
[
|
[
|
||||||
{ type: 'state', title: 'Check for Supervisor updates', id: 'update.home_assistant_supervisor_update' },
|
{ type: 'state', title: 'Check for Supervisor updates', id: 'update.home_assistant_supervisor_update' },
|
||||||
{ type: 'service', title: 'Restart HA', domain: 'homeassistant', service: 'restart', data: {} }
|
{ type: 'service', title: 'Restart HA', domain: 'homeassistant', service: 'restart', silent: true, data: {} }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ type: 'service', title: 'Custom Notification', domain: 'persistent_notification', service: 'create',
|
{ type: 'service', title: 'Custom Notification', domain: 'persistent_notification', service: 'create',
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "hadash",
|
"id": "hadash",
|
||||||
"name": "Home-Assistant Dashboard",
|
"name": "Home-Assistant Dashboard",
|
||||||
"shortName":"HA-Dash",
|
"shortName":"HA-Dash",
|
||||||
"version":"1.00",
|
"version":"1.01",
|
||||||
"description": "Interact with Home-Assistant (query states, call services)",
|
"description": "Interact with Home-Assistant (query states, call services)",
|
||||||
"icon": "hadash.png",
|
"icon": "hadash.png",
|
||||||
"screenshots": [{ "url": "screenshot.png" }],
|
"screenshots": [{ "url": "screenshot.png" }],
|
||||||
|
|
Loading…
Reference in New Issue