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.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 ## 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

View File

@ -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;
} }

View File

@ -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',

View File

@ -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" }],