hadash: remember scoll positions of menus; "silent" option for service calls

pull/3599/head
Flaparoo 2024-10-01 19:59:13 +08:00
parent b54b0539c3
commit 3b955b6d12
5 changed files with 33 additions and 19 deletions

View File

@ -1 +1,2 @@
1.00: initial release
1.01: remember scoll positions of menus; "silent" option for service calls

View File

@ -58,8 +58,6 @@ that token in case your watch is stolen or lost.
## To-Do
- 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

View File

@ -4,6 +4,8 @@
const APP_NAME = 'hadash';
var scroller;
// Load settings
var settings = Object.assign({
menu: [
@ -13,7 +15,7 @@ var settings = Object.assign({
{ type: 'menu', title: 'Sub-menu', data:
[
{ 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',
@ -28,6 +30,7 @@ var settings = Object.assign({
// query an entity state
function queryState(title, id, level) {
menus[level][''].scroll = scroller.scroll;
E.showMessage('Fetching entity state from HA', { title: title });
Bangle.http(settings.HAbaseUrl+'/states/'+id, {
headers: {
@ -45,16 +48,17 @@ function queryState(title, id, level) {
if ('unit_of_measurement' in HAresp.attributes)
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 => {
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
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 });
Bangle.http(settings.HAbaseUrl+'/services/'+domain+'/'+service, {
method: 'POST',
@ -65,10 +69,14 @@ function callService(title, domain, service, data, level) {
},
}).then(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 => {
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
function getServiceInputData(entry, level) {
menus[level][''].scroll = scroller.scroll;
let serviceInputMenu = {
'': {
'title': entry.title,
'back': () => E.showMenu(menus[level])
'back': () => scroller = E.showMenu(menus[level]).scroller
},
};
let CBs = {};
@ -130,7 +139,7 @@ function getServiceInputData(entry, level) {
}
}
// 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);
}
@ -163,6 +172,8 @@ function addMenuEntries(level, entries) {
/*
* call HA service
*/
if (! ('silent' in entry))
entry.silent = false;
if ('domain' in entry && entry.domain && 'service' in entry && entry.service) {
if (! ('data' in entry))
entry.data = {};
@ -171,7 +182,7 @@ function addMenuEntries(level, entries) {
entryCB = () => setTimeout(getServiceInputData, 10, entry, level);
} else {
// 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;
@ -196,14 +207,15 @@ function addMenuEntries(level, entries) {
// create and show a sub menu
function showSubMenu(level, title, entries) {
menus[level - 1][''].scroll = scroller.scroll;
menus[level] = {
'': {
'title': title,
'back': () => E.showMenu(menus[level - 1])
'back': () => scroller = E.showMenu(menus[level - 1]).scroller
},
};
addMenuEntries(level, entries);
E.showMenu(menus[level]);
scroller = E.showMenu(menus[level]).scroller;
}
@ -220,8 +232,8 @@ addMenuEntries(0, settings.menu);
// check required configuration
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 {
E.showMenu(menus[0]);
scroller = E.showMenu(menus[0]).scroller;
}

View File

@ -55,6 +55,7 @@
"title": "Menu entry title",
"domain": "HA Domain",
"service": "HA Service",
"silent": (true|false),
"data": {
"key": "value"
}
@ -64,8 +65,10 @@
under the Developer tools -> Services. Use the "Go to YAML Mode"
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.
Any (optional) data key/value pairs can be added under the "data"
field. For example, here's a service call YAML:
If the optional "silent" boolean is set to true (false is default),
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">
service: persistent_notification.create
data:
@ -207,7 +210,7 @@ target:
{ type: 'menu', title: 'Sub-menu', data:
[
{ 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',

View File

@ -2,7 +2,7 @@
"id": "hadash",
"name": "Home-Assistant Dashboard",
"shortName":"HA-Dash",
"version":"1.00",
"version":"1.01",
"description": "Interact with Home-Assistant (query states, call services)",
"icon": "hadash.png",
"screenshots": [{ "url": "screenshot.png" }],