Skip to content

Feature/display data from response #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 65 additions & 22 deletions Sources/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ function APIRequest(jsonObj) {
key_state = null;

function restartPeriodicPoll() {
const frequency = settings.poll_status_frequency || 15;
const frequency = settings.poll_status_frequency || settings.poll_status_data_frequency || 15;

destroy();

if (settings.advanced_settings && settings.poll_status) {
if (settings.advanced_settings && (settings.poll_status || settings.poll_status_data)) {
sendRequest(do_status_poll = true);

poll_timer = setInterval(function() {
Expand All @@ -95,18 +95,22 @@ function APIRequest(jsonObj) {
}

if (do_status_poll) {
if (!Boolean(settings.response_parse) || !Boolean(settings.poll_status)) return;
if (!settings.poll_status_url) return;
// We check the parent-child relationship between settings to skip early when not needed
// (left-side: parsing for background && right-side: parsing for displaying data)
if (!Boolean(settings.response_parse) && !Boolean(settings.response_data)) return;
if (!Boolean(settings.poll_status) && !Boolean(settings.poll_status_data)) return;
if (!settings.poll_status_url && !settings.poll_status_data_url) return;
}

let url = settings.request_url;
let body = undefined;
let method = 'GET';
if (settings.advanced_settings) {
if (do_status_poll) url = settings.poll_status_url;
if (do_status_poll) url = settings.poll_status_url ?? settings.poll_status_data_url;
if (settings.request_parameters) {
body = settings.request_body;
method = (do_status_poll ? settings.poll_status_method : settings.request_method) ?? method;
body = settings.request_body;
poll_method = settings.poll_status_method ?? settings.poll_status_data_method;
method = (do_status_poll ? poll_method : settings.request_method) ?? method;
}
}

Expand Down Expand Up @@ -172,39 +176,78 @@ function APIRequest(jsonObj) {
}

async function updateImage(resp, do_status_poll) {
if (!settings.advanced_settings || !settings.response_parse || !settings.image_matched || !settings.image_unmatched)
/*
* Making sure we run only in one of the 2 relevant cases:
* (1) when asked to parse and match to define the background image
* (2) when asked to parse and display the data from the response on the key
*/

// Common / top-level options
if (!settings.advanced_settings || (!settings.response_parse && !settings.response_data))
return;

// Case 1 missing config detection
if (settings.response_parse && (!settings.image_matched || !settings.image_unmatched))
return;

// Case 2 missing config detection (could be commented if we decide that the background image is optional)
if (settings.response_data && !settings.background_image)
return;

let json, body;
var new_key_state = key_state;
const want_data = (settings.response_data) ? true : false;
const field_name = (want_data) ? 'data' : 'parse';

const prefix = (do_status_poll && settings.poll_status && settings.poll_status_parse) ? 'poll_status' : 'response';
const field = Utils.getProp(settings, `${prefix}_parse_field`, undefined);
const field = Utils.getProp(settings, `${prefix}_${field_name}_field`, undefined);
const value = Utils.getProp(settings, `${prefix}_parse_value`, undefined);

if (field !== undefined && value !== undefined) {
json = await resp.json();
new_key_state = (Utils.getProperty(json, field) == value);
} else if (field !== undefined) {
json = await resp.json();
new_key_state = !(['false', '0', '', 'undefined'].indexOf(String(Utils.getProperty(json, field)).toLowerCase().trim()) + 1);
} else if (value !== undefined) {
body = await resp.text();
new_key_state = body.includes(value);
// The value will always be undef in Case 2...

if (want_data) {
if (field !== undefined) {
json = await resp.json();
new_key_state = Utils.getProperty(json, field);
} else {
new_key_state = '?????';
}
} else {
if (field !== undefined && value !== undefined) {
json = await resp.json();
new_key_state = (Utils.getProperty(json, field) == value);
} else if (field !== undefined) {
json = await resp.json();
new_key_state = !(['false', '0', '', 'undefined'].indexOf(String(Utils.getProperty(json, field)).toLowerCase().trim()) + 1);
} else if (value !== undefined) {
body = await resp.text();
new_key_state = body.includes(value);
}
}

if (new_key_state == key_state) return;

key_state = new_key_state;

path = key_state
? settings.image_matched
: settings.image_unmatched;
// adapting the background image to the Case we are working for
if (want_data) {
path = settings.background_image;
} else {
path = key_state
? settings.image_matched
: settings.image_unmatched;
}

log('updateImage(): FILE:', path, 'JSON:', json, 'BODY:', body);

Utils.loadImage(path, img => $SD.api.setImage(context, img));

// Defining the text that must be rendered over the image
if (want_data) {
var name = (settings.response_data_name) ? `${settings.response_data_name}\n\n` : '';
var unit = (settings.response_data_unit) ? ` ${settings.response_data_unit}` : '';
$SD.api.setTitle(context, `${name}${new_key_state}${unit}`, null);
}

return resp;
}

Expand Down
90 changes: 90 additions & 0 deletions Sources/propertyinspector/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,96 @@
</div>
</div>

<div class="sdpi-item">
<div style="width: 15px;"></div>
<div class="sdpi-item-value">
<div class="sdpi-item-child">
<input id="response_data" type="checkbox">
<label for="response_data" class="sdpi-item-label"><span></span>Button shows data from response</label>
</div>
</div>
</div>
<div id="response_data_container" style="display:none">
<details>
<summary>Expand for Response data display instructions</summary>
<p>Specify the JSON path in the API response whose value will show up on the key.</p>
<p>A missing path will only display question marks.</p>
<p>YOU MUST NOT USE THE TITLE OTHERWISE IT WILL HIDE THE DATA RETURNED</p>
<p>(but you can use the title color and size config to adjust the data displayed).</p>
<p>If you want to make the data nicer, you can use the extra fields 'Name' and 'Unit'</p>
<p>to put text before and after the data from the response.</p>
</details>
<div class="sdpi-item">
<div class="sdpi-item-label">JSON Path</div>
<input class="sdpi-item-value" type="text" id="response_data_field">
</div>
<div class="sdpi-item">Background</div>
<div class="sdpi-item">
<div class="sdpi-item-group file" id="matchedfilepickergroup">
<input class="sdpi-item-value" type="file" id="background_image" accept=".jpg, .jpeg, .png, .ico, .gif, .bmp, .tiff">
<label class="sdpi-file-info " for="background_image">No file...</label>
<label class="sdpi-file-label" for="background_image">Choose file...</label>
</div>
</div>
<div class="sdpi-item">
<div class="sdpi-item-label">Name</div>
<input class="sdpi-item-value" type="text" id="response_data_name">
</div>
<div class="sdpi-item">
<div class="sdpi-item-label">Unit</div>
<input class="sdpi-item-value" type="text" id="response_data_unit">
</div>
<div class="sdpi-item">
<div style="width: 15px;"></div>
<div class="sdpi-item-value">
<div class="sdpi-item-child">
<input id="poll_status_data" type="checkbox">
<label for="poll_status_data" class="sdpi-item-label"><span></span>Periodically poll a URL for status</label>
</div>
</div>
</div>
<div id="poll_status_data_container" style="display:none">
<div class="sdpi-item">
<div class="sdpi-item-label">Status URL</div>
<input class="sdpi-item-value" type="text" id="poll_status_data_url">
</div>
<div class="sdpi-item">
<div class="sdpi-item-label">HTTP Method</div>
<select class="sdpi-item-value select" id="poll_status_data_method">
<option value="GET" selected>GET</option>
<option value="POST">POST</option>
<option value="HEAD">HEAD</option>
<option value="PUT">PUT</option>
<option value="PATCH">PATCH</option>
<option value="DELETE">DELETE</option>
</select>
</div>
<div class="sdpi-item">
<div class="sdpi-item-label">Poll Frequency</div>
<input class="sdpi-item-value max10" type="text" id="poll_status_data_frequency" pattern="\d+" value="15"> seconds
</div>
<div class="sdpi-item">
<div style="width: 15px;"></div>
<div class="sdpi-item-value">
<div class="sdpi-item-child">
<input id="poll_status_parse" type="checkbox">
<label for="poll_status_data_parse" class="sdpi-item-label"><span></span>Parse a different field and value from response</label>
</div>
</div>
</div>
<div id="poll_status_data_parse_container" style="display:none">
<div class="sdpi-item">
<div class="sdpi-item-label">JSON Path</div>
<input class="sdpi-item-value" type="text" id="poll_status_data_parse_field">
</div>
<div class="sdpi-item">
<div class="sdpi-item-label">Expected Value</div>
<input class="sdpi-item-value" type="text" id="poll_status_data_parse_value">
</div>
</div>
</div>
</div>

<div class="sdpi-item">
<div style="width: 15px;"></div>
<div class="sdpi-item-value">
Expand Down
9 changes: 9 additions & 0 deletions Sources/propertyinspector/index_pi.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,14 +342,23 @@ function showHideSettings() {
d = document.getElementById('request_parameters_container');
d.style.display = settings.request_parameters ? "" : "none";

d = document.getElementById('response_data_container');
d.style.display = settings.response_data ? "" : "none";

d = document.getElementById('response_parse_container');
d.style.display = settings.response_parse ? "" : "none";

d = document.getElementById('poll_status_container');
d.style.display = settings.poll_status ? "" : "none";

d = document.getElementById('poll_status_data_container');
d.style.display = settings.poll_status_data ? "" : "none";

d = document.getElementById('poll_status_parse_container');
d.style.display = settings.poll_status_parse ? "" : "none";

d = document.getElementById('poll_status_data_parse_container');
d.style.display = settings.poll_status_data_parse ? "" : "none";
}

function localize(s) {
Expand Down