sns: report both used & supported units to the webui

Generic way to find out which units the magnitude type supports.
Clean-up UI related to temperature, energy and power units.
Resolves #2482

Also apply some refactoring to the 'schema'-generated
payloads by using the EnumerableConfig helper class.
Class received some new features:
- optional callback, verifying that index should be used at all
  specific use-case is magnitudes list that needs only 'counted' ones
- std::iota / ranges::iota_view -like helper object for sequences
  starting with something other than 0

Reordered payloads, prefer queueing over sending everything at once.
This commit is contained in:
Maxim Prokhorov
2021-10-24 14:10:14 +03:00
parent a2c02a38e5
commit eb59726b4f
9 changed files with 662 additions and 361 deletions

View File

@@ -64,7 +64,6 @@ h2 {
color:inherit;
}
legend.module,
.module {
display: none;
}

View File

@@ -65,8 +65,10 @@ var Rfm69 = {
var Magnitudes = [];
var MagnitudeErrors = {};
var MagnitudeNames = {};
var MagnitudeUnits = {};
var MagnitudeTypePrefixes = {};
var MagnitudePrefixTypes = {};
//endRemoveIf(!sensor)
// -----------------------------------------------------------------------------
@@ -1272,21 +1274,24 @@ function createRelayList(values, container, template_name) {
//removeIf(!sensor)
function createMagnitudeList(data, container, template_name) {
let target = document.getElementById(container);
function createMagnitudeList(data) {
const targetId = `${data.prefix}Magnitudes`;
let target = document.getElementById(targetId);
if (target.childElementCount > 0) { return; }
data.values.forEach((values) => {
let [type, index_global, index_module] = values;
const entry = fromSchema(values, data.schema);
let line = loadConfigTemplate(template_name);
let line = loadConfigTemplate("module-magnitude");
line.querySelector("label").textContent =
MagnitudeNames[type].concat(" #").concat(parseInt(index_global, 10));
`${MagnitudeNames[entry.type]} #${entry.index_global}`;
line.querySelector("div.hint").textContent =
Magnitudes[index_global].description;
Magnitudes[entry.index_global].description;
let input = line.querySelector("input");
input.value = index_module;
input.name = `${data.prefix}Magnitude`;
input.value = entry.index_module;
input.dataset["original"] = input.value;
mergeTemplate(target, line);
@@ -1559,12 +1564,7 @@ function initRelayConfig(id, cfg) {
//removeIf(!sensor)
function initMagnitudes(data) {
let container = document.getElementById("magnitudes");
if (container.childElementCount > 0) {
return;
}
function initMagnitudesTypes(data) {
data.types.values.forEach((cfg) => {
const info = fromSchema(cfg, data.types.schema);
MagnitudeNames[info.type] = info.name;
@@ -1577,6 +1577,42 @@ function initMagnitudes(data) {
MagnitudeErrors[error.type] = error.name;
});
data.units.values.forEach((cfg) => {
const unit = fromSchema(cfg, data.units.schema);
// XXX: schema, too?
let options = [];
unit.supported.forEach(([id, name]) => {
MagnitudeUnits[id] = name;
options.push({id, name});
});
// no need for the select when there's no choice
if (options.length < 2) {
return;
}
let line = loadTemplate("sns-units");
line.querySelector("label").textContent =
`${MagnitudeNames[unit.type]} #${unit.index_global}`;
let select = line.querySelector("select");
select.setAttribute("name",
`${MagnitudeTypePrefixes[unit.type]}Units${unit.index_global}`);
initSelect(select, options);
setOriginalsFromValuesForNode(line, [select]);
mergeTemplate(document.getElementById("sns-units-config"), line);
});
}
function initMagnitudes(data) {
let container = document.getElementById("magnitudes");
if (container.childElementCount > 0) {
return;
}
data.magnitudes.values.forEach((cfg, index) => {
const magnitude = fromSchema(cfg, data.magnitudes.schema);
@@ -1584,7 +1620,7 @@ function initMagnitudes(data) {
.concat(" #").concat(parseInt(magnitude.index_global, 10));
Magnitudes.push({
name: prettyName,
units: magnitude.units,
units: MagnitudeUnits[magnitude.units],
description: magnitude.description
});
@@ -1604,9 +1640,11 @@ function updateMagnitudes(data) {
const magnitude = fromSchema(cfg, data.schema);
let input = document.querySelector(`input[name='magnitude'][data-id='${id}']`);
input.value = (0 === magnitude.error)
? (magnitude.value + Magnitudes[id].units)
: MagnitudeErrors[magnitude.error];
input.value = (0 !== magnitude.error)
? MagnitudeErrors[magnitude.error]
: (("nan" === magnitude.value)
? ""
: `${magnitude.value}${Magnitudes[id].units}`);
if (magnitude.info.length) {
let info = input.parentElement.parentElement.querySelector("div.sns-info");
@@ -2195,11 +2233,21 @@ function processData(data) {
//removeIf(!sensor)
if ("magnitudesTypes" === key) {
initMagnitudesTypes(value);
return;
}
if ("magnitudesConfig" === key) {
initMagnitudes(value);
return;
}
if ("magnitudesModule" === key) {
createMagnitudeList(value);
return;
}
if ("magnitudes" === key) {
updateMagnitudes(value);
return;
@@ -2295,41 +2343,19 @@ function processData(data) {
}
// ---------------------------------------------------------------------
// Domoticz
// Special mapping for domoticz and thingspeak
// ---------------------------------------------------------------------
// Domoticz - Relays
if ("dczRelays" === key) {
createRelayList(value, "dczRelays", "dcz-relay");
return;
}
// Domoticz - Magnitudes
//removeIf(!sensor)
if ("dczMagnitudes" === key) {
createMagnitudeList(value, "dczMagnitudes", "dcz-magnitude");
return;
}
//endRemoveIf(!sensor)
// ---------------------------------------------------------------------
// Thingspeak
// ---------------------------------------------------------------------
// Thingspeak - Relays
if ("tspkRelays" === key) {
createRelayList(value, "tspkRelays", "tspk-relay");
return;
}
// Thingspeak - Magnitudes
//removeIf(!sensor)
if ("tspkMagnitudes" === key) {
createMagnitudeList(value, "tspkMagnitudes", "tspk-magnitude");
return;
}
//endRemoveIf(!sensor)
// ---------------------------------------------------------------------
// General
// ---------------------------------------------------------------------

View File

@@ -1774,30 +1774,10 @@
</div>
</div>
<div class="pure-g module module-pwr">
<label class="pure-u-1 pure-u-lg-1-4">Power units</label>
<select name="pwrUnits0" class="pure-u-1 pure-u-lg-1-4">
<option value="13">Watts (W)</option>
<option value="14">Kilowatts (kW)</option>
</select>
</div>
</fieldset>
<div class="pure-g module module-pwr">
<label class="pure-u-1 pure-u-lg-1-4">Energy units</label>
<select name="eneUnits0" class="pure-u-1 pure-u-lg-1-4">
<option value="15">Joules (J)</option>
<option value="16">Kilowatts·hour (kWh)</option>
</select>
</div>
<div class="pure-g module module-tmp">
<label class="pure-u-1 pure-u-lg-1-4">Temperature units</label>
<select name="tmpUnits0" class="pure-u-1 pure-u-lg-1-4">
<option value="2">Celsius (&deg;C)</option>
<option value="3">Fahrenheit (&deg;F)</option>
<option value="4">Kelvin (K)</option>
</select>
</div>
<fieldset class="module module-mics">
<legend>Calibration</legend>
<div class="pure-g module module-mics">
<label class="pure-u-1 pure-u-lg-1-4">Calibrate gas sensor</label>
@@ -1808,8 +1788,8 @@
</div>
</fieldset>
<fieldset>
<legend class="module module-hlw module-cse module-emon">Energy monitor</legend>
<fieldset class="module module-emon module-cse module-hlw">
<legend>Energy monitor</legend>
<div class="pure-g module module-emon">
<label class="pure-u-1 pure-u-lg-1-4">Voltage</label>
@@ -1863,6 +1843,13 @@
</div>
</fieldset>
<fieldset>
<legend>Units</legend>
<div id="sns-units-config" class="pure-control-group settings-group">
</div>
</fieldset>
</div>
</div>
@@ -2175,6 +2162,24 @@
</div>
</template>
<!-- removeIf(!sensor) -->
<template id="template-sns-units">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4"></label>
<select class="pure-u-1 pure-u-lg-1-4">
</select>
</div>
</template>
<template id="template-module-magnitude">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Magnitude</label>
<div class="pure-u-1 pure-u-lg-1-4"><input class="pure-u-1 pure-u-lg-23-24" type="number" min="0"></div>
<div class="pure-u-1 pure-u-lg-1-2 hint center"></div>
</div>
</template>
<!-- endRemoveIf(!sensor) -->
<template id="template-dcz-relay">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Switch</label>
@@ -2182,16 +2187,6 @@
</div>
</template>
<!-- removeIf(!sensor) -->
<template id="template-dcz-magnitude">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Magnitude</label>
<div class="pure-u-1 pure-u-lg-1-4"><input class="pure-u-1 pure-u-lg-23-24" name="dczMagnitude" type="number" min="0"></div>
<div class="pure-u-1 pure-u-lg-1-2 hint center"></div>
</div>
</template>
<!-- endRemoveIf(!sensor) -->
<template id="template-tspk-relay" class="template">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Switch</label>
@@ -2199,16 +2194,6 @@
</div>
</template>
<!-- removeIf(!sensor) -->
<template id="template-tspk-magnitude" class="template">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Magnitude</label>
<div class="pure-u-1 pure-u-lg-1-4"><input class="pure-u-1 pure-u-lg-23-24 center" name="tspkMagnitude" type="number" min="0"></div>
<div class="pure-u-1 pure-u-lg-1-2 hint center"></div>
</div>
</template>
<!-- endRemoveIf(!sensor) -->
<!-- removeIf(!light) -->
<template id="template-brightness-control">
<div class="pure-g">