Merge pull request #2724 from proddy/dev

fixes to system sensors
This commit is contained in:
Proddy
2025-11-09 15:00:34 +01:00
committed by GitHub
15 changed files with 284 additions and 142 deletions

View File

@@ -96,6 +96,7 @@ const common_theme = {
} }
&:hover .td { &:hover .td {
background-color: #177ac9; background-color: #177ac9;
color: white;
} }
`, `,
Cell: ` Cell: `
@@ -297,7 +298,12 @@ const Sensors = () => {
const onTemperatureDialogSave = useCallback( const onTemperatureDialogSave = useCallback(
async (ts: TemperatureSensor) => { async (ts: TemperatureSensor) => {
await sendTemperatureSensor({ id: ts.id, name: ts.n, offset: ts.o }) await sendTemperatureSensor({
id: ts.id,
name: ts.n,
offset: ts.o,
is_system: ts.s
})
.then(() => { .then(() => {
toast.success(LL.UPDATED_OF(LL.SENSOR(1))); toast.success(LL.UPDATED_OF(LL.SENSOR(1)));
}) })
@@ -342,7 +348,8 @@ const Sensors = () => {
t: 0, t: 0,
f: 1, f: 1,
d: false, d: false,
o_n: '' o_n: '',
s: false
}); });
setAnalogDialogOpen(true); setAnalogDialogOpen(true);
}, []); }, []);
@@ -357,7 +364,8 @@ const Sensors = () => {
factor: as.f, factor: as.f,
uom: as.u, uom: as.u,
type: as.t, type: as.t,
deleted: as.d deleted: as.d,
is_system: as.s
}) })
.then(() => { .then(() => {
toast.success(LL.UPDATED_OF(LL.ANALOG_SENSOR(2))); toast.success(LL.UPDATED_OF(LL.ANALOG_SENSOR(2)));
@@ -431,20 +439,25 @@ const Sensors = () => {
</HeaderRow> </HeaderRow>
</Header> </Header>
<Body> <Body>
{tableList.map((a: AnalogSensor) => ( {tableList.map((as: AnalogSensor) => (
<Row key={a.id} item={a} onClick={() => updateAnalogSensor(a)}> <Row
<Cell stiff>{a.g}</Cell> style={{ color: as.s ? 'grey' : 'inherit' }}
<Cell>{a.n}</Cell> key={as.id}
<Cell stiff>{AnalogTypeNames[a.t]} </Cell> item={as}
{(a.t === AnalogType.DIGITAL_OUT && onClick={() => updateAnalogSensor(as)}
a.g !== GPIO_25 && >
a.g !== GPIO_26) || <Cell stiff>{as.g}</Cell>
a.t === AnalogType.DIGITAL_IN || <Cell>{as.n}</Cell>
a.t === AnalogType.PULSE ? ( <Cell stiff>{AnalogTypeNames[as.t]} </Cell>
<Cell stiff>{a.v ? LL.ON() : LL.OFF()}</Cell> {(as.t === AnalogType.DIGITAL_OUT &&
as.g !== GPIO_25 &&
as.g !== GPIO_26) ||
as.t === AnalogType.DIGITAL_IN ||
as.t === AnalogType.PULSE ? (
<Cell stiff>{as.v ? LL.ON() : LL.OFF()}</Cell>
) : ( ) : (
<Cell stiff> <Cell stiff>
{a.t !== AnalogType.NOTUSED ? formatValue(a.v, a.u) : ''} {as.t !== AnalogType.NOTUSED ? formatValue(as.v, as.u) : ''}
</Cell> </Cell>
)} )}
</Row> </Row>
@@ -506,6 +519,7 @@ const Sensors = () => {
<Body> <Body>
{tableList.map((ts: TemperatureSensor) => ( {tableList.map((ts: TemperatureSensor) => (
<Row <Row
style={{ color: ts.s ? 'grey' : 'inherit' }}
key={ts.id} key={ts.id}
item={ts} item={ts}
onClick={() => updateTemperatureSensor(ts)} onClick={() => updateTemperatureSensor(ts)}

View File

@@ -1,6 +1,7 @@
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import DoneIcon from '@mui/icons-material/Done';
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline'; import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
import WarningIcon from '@mui/icons-material/Warning'; import WarningIcon from '@mui/icons-material/Warning';
import { import {
@@ -441,6 +442,18 @@ const SensorsAnalogDialog = ({
</> </>
)} )}
</Grid> </Grid>
{editItem.s && (
<Grid>
<Typography mt={1} color="warning.main" variant="body2">
<WarningIcon
fontSize="small"
sx={{ mr: 1, verticalAlign: 'middle' }}
color="warning"
/>
{LL.SYSTEM(0)} {LL.SENSOR(0)}
</Typography>
</Grid>
)}
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
{!creating && ( {!creating && (
@@ -465,7 +478,7 @@ const SensorsAnalogDialog = ({
{LL.CANCEL()} {LL.CANCEL()}
</Button> </Button>
<Button <Button
startIcon={<WarningIcon color="warning" />} startIcon={<DoneIcon />}
variant="outlined" variant="outlined"
onClick={save} onClick={save}
color="primary" color="primary"

View File

@@ -1,6 +1,7 @@
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from '@mui/icons-material/Cancel';
import DoneIcon from '@mui/icons-material/Done';
import WarningIcon from '@mui/icons-material/Warning'; import WarningIcon from '@mui/icons-material/Warning';
import { import {
Box, Box,
@@ -139,6 +140,18 @@ const SensorsTemperatureDialog = ({
/> />
</Grid> </Grid>
</Grid> </Grid>
{editItem.s && (
<Grid>
<Typography mt={1} color="warning.main" variant="body2">
<WarningIcon
fontSize="small"
sx={{ mr: 1, verticalAlign: 'middle' }}
color="warning"
/>
{LL.SYSTEM(0)} {LL.SENSOR(0)}
</Typography>
</Grid>
)}
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button <Button
@@ -150,7 +163,7 @@ const SensorsTemperatureDialog = ({
{LL.CANCEL()} {LL.CANCEL()}
</Button> </Button>
<Button <Button
startIcon={<WarningIcon color="warning" />} startIcon={<DoneIcon />}
variant="outlined" variant="outlined"
onClick={save} onClick={save}
color="primary" color="primary"

View File

@@ -82,6 +82,7 @@ export interface TemperatureSensor {
t?: number; // temp, optional t?: number; // temp, optional
o: number; // offset o: number; // offset
u: number; // uom u: number; // uom
s: boolean; // system sensor flag
o_n?: string; o_n?: string;
} }
@@ -95,7 +96,7 @@ export interface AnalogSensor {
f: number; f: number;
t: number; t: number;
d: boolean; // deleted flag d: boolean; // deleted flag
s: boolean; // system customization flag s: boolean; // system sensor flag
o_n?: string; o_n?: string;
} }
@@ -103,6 +104,7 @@ export interface WriteTemperatureSensor {
id: string; id: string;
name: string; name: string;
offset: number; offset: number;
is_system: boolean;
} }
export interface SensorData { export interface SensorData {
@@ -318,6 +320,7 @@ export interface WriteAnalogSensor {
uom: number; uom: number;
type: number; type: number;
deleted: boolean; deleted: boolean;
is_system: boolean;
} }
export enum DeviceEntityMask { export enum DeviceEntityMask {

View File

@@ -276,10 +276,10 @@ function updateMask(entity: any, de: any, dd: any) {
const old_custom_name = dd.nodes[dd_objIndex].cn; const old_custom_name = dd.nodes[dd_objIndex].cn;
console.log( console.log(
'comparing names, old (' + 'comparing names, old (' +
old_custom_name + old_custom_name +
') with new (' + ') with new (' +
new_custom_name + new_custom_name +
')' ')'
); );
if (old_custom_name !== new_custom_name) { if (old_custom_name !== new_custom_name) {
changed = true; changed = true;
@@ -375,15 +375,15 @@ function check_upgrade(version: string) {
console.log( console.log(
'Upgrade this version (' + 'Upgrade this version (' +
THIS_VERSION + THIS_VERSION +
') to dev (' + ') to dev (' +
dev_version + dev_version +
') is ' + ') is ' +
(DEV_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO') + (DEV_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO') +
' and to stable (' + ' and to stable (' +
stable_version + stable_version +
') is ' + ') is ' +
(STABLE_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO') (STABLE_VERSION_IS_UPGRADEABLE ? 'YES' : 'NO')
); );
data = { data = {
emsesp_version: THIS_VERSION, emsesp_version: THIS_VERSION,
@@ -962,11 +962,25 @@ const emsesp_coredata_custom = {
const emsesp_sensordata = { const emsesp_sensordata = {
// ts: [], // ts: [],
ts: [ ts: [
{ id: '28-233D-9497-0C03', n: 'Dallas 1', t: 25.7, o: 1.2, u: 1 }, { id: '28-233D-9497-0C03', n: 'Dallas 1', t: 25.7, o: 1.2, u: 1, s: false },
{ id: '28-243D-7437-1E3A', n: 'Dallas 2 outside', t: 26.1, o: 0, u: 1 }, {
{ id: '28-243E-7437-1E3B', n: 'Zolder', t: 27.1, o: 0, u: 1 }, id: '28-243D-7437-1E3A',
{ id: '28-183D-1892-0C33', n: 'Roof', o: 2, u: 1 }, // no temperature n: 'Dallas 2 outside',
{ id: '28_1767_7B13_2502', n: 'gateway_temperature', t: 28.1, o: 0, u: 1 } // internal system temp t: 26.1,
o: 0,
u: 1,
s: false
},
{ id: '28-243E-7437-1E3B', n: 'Zolder', t: 27.1, o: 0, u: 1, s: false },
{ id: '28-183D-1892-0C33', n: 'Roof', o: 2, u: 1, s: false }, // no temperature
{
id: '28_1767_7B13_2502',
n: 'gateway_temperature',
t: 28.1,
o: 0,
u: 1,
s: true
} // internal system temp
], ],
// as: [], // as: [],
as: [ as: [
@@ -4578,8 +4592,12 @@ router
} }
// add temperature sensor data. no command c // add temperature sensor data. no command c
if (emsesp_sensordata.ts.length > 0) { // remove system sensors first
const sensor_data = emsesp_sensordata.ts.map((item, index) => ({ const enabledTemperatureSensors = emsesp_sensordata.ts.filter(
(item) => !item.s
);
if (enabledTemperatureSensors.length > 0) {
const sensor_data = enabledTemperatureSensors.map((item, index) => ({
id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID * 100 + index, id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID * 100 + index,
dv: { dv: {
id: '00' + item.n, id: '00' + item.n,
@@ -4597,8 +4615,9 @@ router
// add analog sensor data. no command c // add analog sensor data. no command c
// remove disabled sensors first (t = 0) and create data in one pass // remove disabled sensors first (t = 0) and create data in one pass
// remove system sensors first
const enabledAnalogSensors = emsesp_sensordata.as.filter( const enabledAnalogSensors = emsesp_sensordata.as.filter(
(item) => item.t !== 0 (item) => item.t !== 0 && !item.s
); );
if (enabledAnalogSensors.length > 0) { if (enabledAnalogSensors.length > 0) {
const sensor_data = enabledAnalogSensors.map((item, index) => ({ const sensor_data = enabledAnalogSensors.map((item, index) => ({
@@ -4852,6 +4871,7 @@ router
if (objIndex !== -1) { if (objIndex !== -1) {
emsesp_sensordata.ts[objIndex].n = ts.name; emsesp_sensordata.ts[objIndex].n = ts.name;
emsesp_sensordata.ts[objIndex].o = ts.offset; emsesp_sensordata.ts[objIndex].o = ts.offset;
emsesp_sensordata.ts[objIndex].s = ts.is_system;
} }
console.log('temp sensor saved', ts); console.log('temp sensor saved', ts);
return status(200); return status(200);
@@ -4887,6 +4907,7 @@ router
emsesp_sensordata.as[objIndex].o = as.offset; emsesp_sensordata.as[objIndex].o = as.offset;
emsesp_sensordata.as[objIndex].u = as.uom; emsesp_sensordata.as[objIndex].u = as.uom;
emsesp_sensordata.as[objIndex].t = as.type; emsesp_sensordata.as[objIndex].t = as.type;
emsesp_sensordata.as[objIndex].s = as.is_system;
} }
} }
console.log('analog sensor saved', as); console.log('analog sensor saved', as);

View File

@@ -155,7 +155,7 @@ void AnalogSensor::reload(bool get_nvs) {
} }
} }
if (!found) { if (!found) {
sensors_.emplace_back(sensor.gpio, sensor.name, sensor.offset, sensor.factor, sensor.uom, sensor.type); sensors_.emplace_back(sensor.gpio, sensor.name, sensor.offset, sensor.factor, sensor.uom, sensor.type, sensor.is_system);
sensors_.back().ha_registered = false; // this will trigger recreate of the HA config sensors_.back().ha_registered = false; // this will trigger recreate of the HA config
if (sensor.type == AnalogType::COUNTER || sensor.type >= AnalogType::DIGITAL_OUT) { if (sensor.type == AnalogType::COUNTER || sensor.type >= AnalogType::DIGITAL_OUT) {
sensors_.back().set_value(sensor.offset); sensors_.back().set_value(sensor.offset);
@@ -530,7 +530,7 @@ bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, doubl
newSensor.factor = factor; newSensor.factor = factor;
newSensor.uom = uom; newSensor.uom = uom;
newSensor.type = type; newSensor.type = type;
newSensor.is_system = false; newSensor.is_system = is_system;
settings.analogCustomizations.push_back(newSensor); settings.analogCustomizations.push_back(newSensor);
LOG_DEBUG("Adding new customization for analog sensor GPIO %02d", gpio); LOG_DEBUG("Adding new customization for analog sensor GPIO %02d", gpio);
return StateUpdateResult::CHANGED; // persist the change return StateUpdateResult::CHANGED; // persist the change
@@ -871,13 +871,20 @@ void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) {
} }
// this creates the sensor, initializing everything // this creates the sensor, initializing everything
AnalogSensor::Sensor::Sensor(const uint8_t gpio, const std::string & name, const double offset, const double factor, const uint8_t uom, const int8_t type) AnalogSensor::Sensor::Sensor(const uint8_t gpio,
const std::string & name,
const double offset,
const double factor,
const uint8_t uom,
const int8_t type,
const bool is_system)
: gpio_(gpio) : gpio_(gpio)
, name_(name) , name_(name)
, offset_(offset) , offset_(offset)
, factor_(factor) , factor_(factor)
, uom_(uom) , uom_(uom)
, type_(type) { , type_(type)
, is_system_(is_system) {
value_ = 0; // init value to 0 always value_ = 0; // init value to 0 always
} }

View File

@@ -34,7 +34,7 @@ class AnalogSensor {
public: public:
class Sensor { class Sensor {
public: public:
Sensor(const uint8_t gpio, const std::string & name, const double offset, const double factor, const uint8_t uom, const int8_t type); Sensor(const uint8_t gpio, const std::string & name, const double offset, const double factor, const uint8_t uom, const int8_t type, const bool is_system);
~Sensor() = default; ~Sensor() = default;
void set_offset(const double offset) { void set_offset(const double offset) {
@@ -44,7 +44,6 @@ class AnalogSensor {
std::string name() const { std::string name() const {
return name_; return name_;
} }
void set_name(const std::string & name) { void set_name(const std::string & name) {
name_ = name; name_ = name;
} }
@@ -64,11 +63,13 @@ class AnalogSensor {
bool is_system() const { bool is_system() const {
return is_system_; return is_system_;
} }
void set_is_system(const bool is_system) {
is_system_ = is_system;
}
double factor() const { double factor() const {
return factor_; return factor_;
} }
void set_factor(const double factor) { void set_factor(const double factor) {
factor_ = factor; factor_ = factor;
} }
@@ -80,7 +81,6 @@ class AnalogSensor {
void set_uom(const uint8_t uom) { void set_uom(const uint8_t uom) {
uom_ = uom; uom_ = uom;
} }
uint8_t uom() const { uint8_t uom() const {
return uom_; return uom_;
} }
@@ -166,13 +166,15 @@ class AnalogSensor {
size_t count_entities(bool include_disabled = true) const { size_t count_entities(bool include_disabled = true) const {
if (!include_disabled) { if (!include_disabled) {
// count number of items in sensors_ where type is not set to disabled // count number of items in sensors_ where type is not set to disabled and not a system sensor
return std::count_if(sensors_.begin(), sensors_.end(), [](const Sensor & sensor) { return sensor.type() != AnalogSensor::AnalogType::NOTUSED; }); return std::count_if(sensors_.begin(), sensors_.end(), [](const Sensor & sensor) {
return sensor.type() != AnalogSensor::AnalogType::NOTUSED && !sensor.is_system();
});
} }
return sensors_.size(); return sensors_.size();
} }
bool update(uint8_t gpio, std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted = false, bool is_system = false); bool update(uint8_t gpio, std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted, bool is_system);
bool get_value_info(JsonObject output, const char * cmd, const int8_t id = -1); bool get_value_info(JsonObject output, const char * cmd, const int8_t id = -1);
void store_counters(); void store_counters();

View File

@@ -545,16 +545,21 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
for (const auto & sensor : temperaturesensor_.sensors()) { for (const auto & sensor : temperaturesensor_.sensors()) {
if (Helpers::hasValue(sensor.temperature_c)) { if (Helpers::hasValue(sensor.temperature_c)) {
shell.printfln(" %s: %s%s °%c%s (offset %s, ID: %s)", shell.printfln(" %s: %s%s °%c%s (Offset: %s, ID: %s, System: %s)",
sensor.name().c_str(), sensor.name().c_str(),
COLOR_BRIGHT_GREEN, COLOR_BRIGHT_GREEN,
Helpers::render_value(s, sensor.temperature_c, 10, fahrenheit), Helpers::render_value(s, sensor.temperature_c, 10, fahrenheit),
(fahrenheit == 0) ? 'C' : 'F', (fahrenheit == 0) ? 'C' : 'F',
COLOR_RESET, COLOR_RESET,
Helpers::render_value(s2, sensor.offset(), 10, fahrenheit), Helpers::render_value(s2, sensor.offset(), 10, fahrenheit),
sensor.id().c_str()); sensor.id().c_str(),
sensor.is_system() ? "Yes" : "No");
} else { } else {
shell.printfln(" %s (offset %s, ID: %s)", sensor.name().c_str(), Helpers::render_value(s, sensor.offset(), 10, fahrenheit), sensor.id().c_str()); shell.printfln(" %s (Offset: %s, ID: %s, System: %s)",
sensor.name().c_str(),
Helpers::render_value(s, sensor.offset(), 10, fahrenheit),
sensor.id().c_str(),
sensor.is_system() ? "Yes" : "No");
} }
} }
shell.println(); shell.println();
@@ -563,18 +568,20 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
if (analogsensor_.have_sensors()) { if (analogsensor_.have_sensors()) {
char s[10]; char s[10];
char s2[10]; char s2[10];
char s3[10];
shell.printfln("Analog sensors:"); shell.printfln("Analog sensors:");
for (const auto & sensor : analogsensor_.sensors()) { for (const auto & sensor : analogsensor_.sensors()) {
switch (sensor.type()) { switch (sensor.type()) {
case AnalogSensor::AnalogType::ADC: case AnalogSensor::AnalogType::ADC:
shell.printfln(" %s: %s%s %s%s (Type: ADC, Factor: %s, Offset: %d)", shell.printfln(" %s: %s%s %s%s (Type: ADC, Factor: %s, Offset: %s, System: %s)",
sensor.name().c_str(), sensor.name().c_str(),
COLOR_BRIGHT_GREEN, COLOR_BRIGHT_GREEN,
Helpers::render_value(s, sensor.value(), 2), Helpers::render_value(s, sensor.value(), 2),
EMSdevice::uom_to_string(sensor.uom()), EMSdevice::uom_to_string(sensor.uom()),
COLOR_RESET, COLOR_RESET,
Helpers::render_value(s2, sensor.factor(), 4), Helpers::render_value(s2, sensor.factor(), 4),
sensor.offset()); Helpers::render_value(s3, sensor.offset(), 2),
sensor.is_system() ? "Yes" : "No");
break; break;
default: default:
// case AnalogSensor::AnalogType::DIGITAL_IN: // case AnalogSensor::AnalogType::DIGITAL_IN:

View File

@@ -217,11 +217,13 @@ void TemperatureSensor::loop() {
if (!EMSESP::nvs_.isKey("intTemp")) { if (!EMSESP::nvs_.isKey("intTemp")) {
EMSESP::nvs_.putString("intTemp", s->id().c_str()); EMSESP::nvs_.putString("intTemp", s->id().c_str());
} }
s->set_is_system(true); // mark as internal system temperature sensor
EMSESP::webCustomizationService.update([&](WebCustomization & settings) { EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
auto newSensor = SensorCustomization(); auto newSensor = SensorCustomization();
newSensor.id = s->id(); newSensor.id = s->id();
newSensor.name = s->name(); newSensor.name = s->name();
newSensor.offset = 0; newSensor.offset = 0;
newSensor.is_system = s->is_system(); // always true
settings.sensorCustomizations.push_back(newSensor); settings.sensorCustomizations.push_back(newSensor);
return StateUpdateResult::CHANGED; return StateUpdateResult::CHANGED;
}); });
@@ -313,7 +315,7 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) {
} }
// update temperature sensor information name and offset // update temperature sensor information name and offset
bool TemperatureSensor::update(const std::string & id, const std::string & name, int16_t offset) { bool TemperatureSensor::update(const std::string & id, const std::string & name, int16_t offset, bool is_system) {
// find the sensor // find the sensor
for (auto & sensor : sensors_) { for (auto & sensor : sensors_) {
if (sensor.id() == id) { if (sensor.id() == id) {
@@ -329,23 +331,25 @@ bool TemperatureSensor::update(const std::string & id, const std::string & name,
sensor.set_offset(offset); sensor.set_offset(offset);
// store the new name and offset in our configuration // store the new name and offset in our configuration
EMSESP::webCustomizationService.update([&id, &name, &offset, &sensor](WebCustomization & settings) { EMSESP::webCustomizationService.update([&id, &name, &offset, &is_system, &sensor](WebCustomization & settings) {
// look it up to see if it exists // look it up to see if it exists
bool found = false; bool found = false;
for (auto & SensorCustomization : settings.sensorCustomizations) { for (auto & SensorCustomization : settings.sensorCustomizations) {
if (SensorCustomization.id == id) { if (SensorCustomization.id == id) {
SensorCustomization.name = name; SensorCustomization.name = name;
SensorCustomization.offset = offset; SensorCustomization.offset = offset;
found = true; SensorCustomization.is_system = is_system;
found = true;
LOG_DEBUG("Customizing existing sensor ID %s", id.c_str()); LOG_DEBUG("Customizing existing sensor ID %s", id.c_str());
break; break;
} }
} }
if (!found) { if (!found) {
auto newSensor = SensorCustomization(); auto newSensor = SensorCustomization();
newSensor.id = id; newSensor.id = id;
newSensor.name = name; newSensor.name = name;
newSensor.offset = offset; newSensor.offset = offset;
newSensor.is_system = false; // is user defined, not system
settings.sensorCustomizations.push_back(newSensor); settings.sensorCustomizations.push_back(newSensor);
LOG_DEBUG("Adding new customization for sensor ID %s", id.c_str()); LOG_DEBUG("Adding new customization for sensor ID %s", id.c_str());
} }
@@ -628,6 +632,7 @@ void TemperatureSensor::load_test_data() {
sensors_.back().apply_customization(); sensors_.back().apply_customization();
sensors_.back().temperature_c = 123; // 12.3 sensors_.back().temperature_c = 123; // 12.3
sensors_.back().read = true; sensors_.back().read = true;
sensors_.back().set_is_system(false);
publish_sensor(sensors_.back()); // call publish single publish_sensor(sensors_.back()); // call publish single
// Sensor ID: 0B_0C0D_0E0F_1011 // Sensor ID: 0B_0C0D_0E0F_1011
@@ -636,6 +641,16 @@ void TemperatureSensor::load_test_data() {
sensors_.back().apply_customization(); sensors_.back().apply_customization();
sensors_.back().temperature_c = 456; // 45.6 sensors_.back().temperature_c = 456; // 45.6
sensors_.back().read = true; sensors_.back().read = true;
sensors_.back().set_is_system(false);
publish_sensor(sensors_.back()); // call publish single
// Sensor ID: 28_1767_7B13_2502
uint8_t addr3[ADDR_LEN] = {0x28, 0x17, 0x67, 0x7B, 0x13, 0x25, 0x02};
sensors_.emplace_back(addr3);
sensors_.back().apply_customization();
sensors_.back().temperature_c = 281; // 28.1
sensors_.back().read = true;
sensors_.back().set_is_system(true);
publish_sensor(sensors_.back()); // call publish single publish_sensor(sensors_.back()); // call publish single
} }
#endif #endif

View File

@@ -44,6 +44,13 @@ class TemperatureSensor {
return internal_id_; return internal_id_;
} }
bool is_system() const {
return is_system_;
}
void set_is_system(const bool is_system) {
is_system_ = is_system;
}
std::string id() const { std::string id() const {
return id_; return id_;
} }
@@ -72,6 +79,7 @@ class TemperatureSensor {
std::string id_; std::string id_;
std::string name_; std::string name_;
int16_t offset_; int16_t offset_;
bool is_system_;
}; };
TemperatureSensor() = default; TemperatureSensor() = default;
@@ -106,11 +114,13 @@ class TemperatureSensor {
return (!sensors_.empty()); return (!sensors_.empty());
} }
size_t count_entities() const { size_t count_entities(bool include_system = true) const {
return sensors_.size(); return std::count_if(sensors_.begin(), sensors_.end(), [include_system](const Sensor & sensor) {
return include_system ? sensor.is_system() : !sensor.is_system();
});
} }
bool update(const std::string & id, const std::string & name, int16_t offset); bool update(const std::string & id, const std::string & name, int16_t offset, bool is_system);
#if defined(EMSESP_TEST) #if defined(EMSESP_TEST)
void load_test_data(); void load_test_data();

View File

@@ -880,7 +880,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
shell.invoke_command("call system publish"); shell.invoke_command("call system publish");
// rename // rename
EMSESP::temperaturesensor_.update("01_0203_0405_0607", "testtemperature", 2); EMSESP::temperaturesensor_.update("01_0203_0405_0607", "testtemperature", 2, false);
shell.invoke_command("show values"); shell.invoke_command("show values");
shell.invoke_command("call system publish"); shell.invoke_command("call system publish");
ok = true; ok = true;

View File

@@ -52,12 +52,12 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
void WebCustomization::read(WebCustomization & customizations, JsonObject root) { void WebCustomization::read(WebCustomization & customizations, JsonObject root) {
// Temperature Sensor customization // Temperature Sensor customization
JsonArray sensorsJson = root["ts"].to<JsonArray>(); JsonArray sensorsJson = root["ts"].to<JsonArray>();
for (const SensorCustomization & sensor : customizations.sensorCustomizations) { for (const SensorCustomization & sensor : customizations.sensorCustomizations) {
JsonObject sensorJson = sensorsJson.add<JsonObject>(); JsonObject sensorJson = sensorsJson.add<JsonObject>();
sensorJson["id"] = sensor.id; // ID of chip sensorJson["id"] = sensor.id; // ID of chip
sensorJson["name"] = sensor.name; // n sensorJson["name"] = sensor.name; // n
sensorJson["offset"] = sensor.offset; // o sensorJson["offset"] = sensor.offset; // o
sensorJson["is_system"] = sensor.is_system; // s for core_voltage, supply_voltage
} }
// Analog Sensor customization // Analog Sensor customization
@@ -70,7 +70,7 @@ void WebCustomization::read(WebCustomization & customizations, JsonObject root)
sensorJson["factor"] = sensor.factor; // f sensorJson["factor"] = sensor.factor; // f
sensorJson["uom"] = sensor.uom; // u sensorJson["uom"] = sensor.uom; // u
sensorJson["type"] = sensor.type; // t sensorJson["type"] = sensor.type; // t
sensorJson["is_system"] = sensor.is_system; // s sensorJson["is_system"] = sensor.is_system; // s for core_voltage, supply_voltage
} }
// Masked entities customization and custom device name (optional) // Masked entities customization and custom device name (optional)
@@ -105,6 +105,7 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
if (sensor.id == sensor.name) { if (sensor.id == sensor.name) {
sensor.name = ""; // no need to store id as name sensor.name = ""; // no need to store id as name
} }
sensor.is_system = sensorJson["is_system"];
std::replace(sensor.id.begin(), sensor.id.end(), '-', '_'); // change old ids to v3.7 style std::replace(sensor.id.begin(), sensor.id.end(), '-', '_'); // change old ids to v3.7 style
customizations.sensorCustomizations.push_back(sensor); // add to list customizations.sensorCustomizations.push_back(sensor); // add to list
} }
@@ -373,55 +374,78 @@ void WebCustomizationService::load_test_data() {
// Temperature sensors // Temperature sensors
webCustomization.sensorCustomizations.clear(); // delete all existing sensors webCustomization.sensorCustomizations.clear(); // delete all existing sensors
auto sensor = SensorCustomization(); auto sensor1 = SensorCustomization();
sensor.id = "01_0203_0405_0607"; sensor1.id = "01_0203_0405_0607";
sensor.name = "test_tempsensor1"; sensor1.name = "test_tempsensor1";
sensor.offset = 0; sensor1.offset = 0;
webCustomization.sensorCustomizations.push_back(sensor); sensor1.is_system = false;
webCustomization.sensorCustomizations.push_back(sensor1);
auto sensor2 = SensorCustomization(); auto sensor2 = SensorCustomization();
sensor2.id = "0B_0C0D_0E0F_1011"; sensor2.id = "0B_0C0D_0E0F_1011";
sensor2.name = "test_tempsensor2"; sensor2.name = "test_tempsensor2";
sensor2.offset = 4; sensor2.offset = 4;
sensor2.is_system = false;
webCustomization.sensorCustomizations.push_back(sensor2); webCustomization.sensorCustomizations.push_back(sensor2);
auto sensor3 = SensorCustomization();
sensor3.id = "28_1767_7B13_2502";
sensor3.name = "gateway_temperature";
sensor3.offset = 0;
sensor3.is_system = true;
webCustomization.sensorCustomizations.push_back(sensor3);
// Analog sensors // Analog sensors
// This actually adds the sensors as we use customizations to store them // This actually adds the sensors as we use customizations to store them
webCustomization.analogCustomizations.clear(); webCustomization.analogCustomizations.clear();
auto analog = AnalogCustomization(); auto analog = AnalogCustomization();
analog.gpio = 36; analog.gpio = 36;
analog.name = "test_analogsensor1"; analog.name = "test_analogsensor1";
analog.offset = 0; analog.offset = 0;
analog.factor = 0.1; analog.factor = 0.2;
analog.uom = 17; analog.uom = 17;
analog.type = 3; // ADC analog.type = 3; // ADC
analog.is_system = false;
webCustomization.analogCustomizations.push_back(analog); webCustomization.analogCustomizations.push_back(analog);
analog = AnalogCustomization(); analog = AnalogCustomization();
analog.gpio = 37; analog.gpio = 37;
analog.name = "test_analogsensor2"; analog.name = "test_analogsensor2";
analog.offset = 0; analog.offset = 0;
analog.factor = 1; analog.factor = 1;
analog.uom = 0; analog.uom = 0;
analog.type = 1; // DIGITAL_IN analog.type = 1; // DIGITAL_IN
analog.is_system = false;
webCustomization.analogCustomizations.push_back(analog); webCustomization.analogCustomizations.push_back(analog);
analog = AnalogCustomization(); analog = AnalogCustomization();
analog.gpio = 38; analog.gpio = 38;
analog.name = "test_analogsensor3"; analog.name = "test_analogsensor3";
analog.offset = 0; analog.offset = 0;
analog.factor = 1; analog.factor = 1;
analog.uom = 0; analog.uom = 0;
analog.type = 0; // disabled, not-used analog.type = 0; // disabled, not-used
analog.is_system = false;
webCustomization.analogCustomizations.push_back(analog); webCustomization.analogCustomizations.push_back(analog);
analog = AnalogCustomization(); analog = AnalogCustomization();
analog.gpio = 33; analog.gpio = 33;
analog.name = "test_analogsensor4"; analog.name = "test_analogsensor4";
analog.offset = 0; analog.offset = 0;
analog.factor = 1; analog.factor = 1;
analog.uom = 0; analog.uom = 0;
analog.type = 2; // COUNTER analog.type = 2; // COUNTER
analog.is_system = false;
webCustomization.analogCustomizations.push_back(analog);
analog = AnalogCustomization();
analog.gpio = 39;
analog.name = "test_analogsensor5"; // core_voltage
analog.offset = 0;
analog.factor = 0.003771;
analog.uom = 23;
analog.type = 3; // ADC
analog.is_system = true;
webCustomization.analogCustomizations.push_back(analog); webCustomization.analogCustomizations.push_back(analog);
// EMS entities, mark some as favorites // EMS entities, mark some as favorites

View File

@@ -37,6 +37,7 @@ class SensorCustomization {
std::string id; std::string id;
std::string name; std::string name;
uint16_t offset; uint16_t offset;
bool is_system; // if true, the customization is a system customization
}; };
class AnalogCustomization { class AnalogCustomization {
@@ -45,9 +46,9 @@ class AnalogCustomization {
std::string name; std::string name;
double offset; double offset;
double factor; double factor;
uint8_t uom; // 0 is none uint8_t uom; // 0 is none
int8_t type; // -1 is for deletion int8_t type; // -1 is for deletion
bool is_system = false; // if true, the customization is a system customization bool is_system; // if true, the customization is a system customization
// used for removing from a list // used for removing from a list
bool operator==(const AnalogCustomization & a) const { bool operator==(const AnalogCustomization & a) const {

View File

@@ -127,6 +127,7 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
obj["u"] = DeviceValueUOM::DEGREES; obj["u"] = DeviceValueUOM::DEGREES;
obj["o"] = (float)(sensor.offset()) / 10; obj["o"] = (float)(sensor.offset()) / 10;
} }
obj["s"] = sensor.is_system();
} }
} }
@@ -323,7 +324,9 @@ void WebDataService::write_temperature_sensor(AsyncWebServerRequest * request, J
offset10 = offset / 0.18; offset10 = offset / 0.18;
} }
ok = EMSESP::temperaturesensor_.update(id, name, offset10); bool is_system = sensor["is_system"];
ok = EMSESP::temperaturesensor_.update(id, name, offset10, is_system);
} }
AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 400); // bad request AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 400); // bad request
@@ -336,14 +339,15 @@ void WebDataService::write_analog_sensor(AsyncWebServerRequest * request, JsonVa
if (json.is<JsonObject>()) { if (json.is<JsonObject>()) {
JsonObject analog = json; JsonObject analog = json;
uint8_t gpio = analog["gpio"]; uint8_t gpio = analog["gpio"];
std::string name = analog["name"]; std::string name = analog["name"];
double factor = analog["factor"]; double factor = analog["factor"];
double offset = analog["offset"]; double offset = analog["offset"];
uint8_t uom = analog["uom"]; uint8_t uom = analog["uom"];
int8_t type = analog["type"]; int8_t type = analog["type"];
bool deleted = analog["deleted"]; bool deleted = analog["deleted"];
ok = EMSESP::analogsensor_.update(gpio, name, offset, factor, uom, type, deleted); bool is_system = analog["is_system"];
ok = EMSESP::analogsensor_.update(gpio, name, offset, factor, uom, type, deleted, is_system);
} }
AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 400); // ok or bad request AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 400); // ok or bad request
@@ -388,13 +392,17 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) {
} }
// add temperature sensors, if we have any // add temperature sensors, if we have any
if (EMSESP::temperaturesensor_.have_sensors()) { if (EMSESP::temperaturesensor_.count_entities(true)) { // no system sensors
JsonObject obj = nodes.add<JsonObject>(); JsonObject obj = nodes.add<JsonObject>();
obj["id"] = EMSdevice::DeviceTypeUniqueID::TEMPERATURESENSOR_UID; // it's unique id obj["id"] = EMSdevice::DeviceTypeUniqueID::TEMPERATURESENSOR_UID; // it's unique id
obj["t"] = EMSdevice::DeviceType::TEMPERATURESENSOR; // device type number obj["t"] = EMSdevice::DeviceType::TEMPERATURESENSOR; // device type number
JsonArray nodes = obj["nodes"].to<JsonArray>(); JsonArray nodes = obj["nodes"].to<JsonArray>();
uint8_t count = 0; uint8_t count = 0;
for (const auto & sensor : EMSESP::temperaturesensor_.sensors()) { for (const auto & sensor : EMSESP::temperaturesensor_.sensors()) {
// ignore system sensors
if (sensor.is_system()) {
continue;
}
JsonObject node = nodes.add<JsonObject>(); JsonObject node = nodes.add<JsonObject>();
node["id"] = (EMSdevice::DeviceTypeUniqueID::TEMPERATURESENSOR_UID * 100) + count++; node["id"] = (EMSdevice::DeviceTypeUniqueID::TEMPERATURESENSOR_UID * 100) + count++;
@@ -422,6 +430,10 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) {
JsonArray nodes = obj["nodes"].to<JsonArray>(); JsonArray nodes = obj["nodes"].to<JsonArray>();
uint8_t count = 0; uint8_t count = 0;
for (const auto & sensor : EMSESP::analogsensor_.sensors()) { for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
// ignore system sensors
if (sensor.is_system()) {
continue;
}
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) { // ignore disabled if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) { // ignore disabled
JsonObject node = nodes.add<JsonObject>(); JsonObject node = nodes.add<JsonObject>();
node["id"] = (EMSdevice::DeviceTypeUniqueID::ANALOGSENSOR_UID * 100) + count++; node["id"] = (EMSdevice::DeviceTypeUniqueID::ANALOGSENSOR_UID * 100) + count++;

View File

@@ -167,8 +167,8 @@ void test_21() {
"\"cleanSession\":false,\"entityFormat\":1,\"base\":\"ems-esp\",\"discoveryPrefix\":\"homeassistant\",\"discoveryType\":0,\"nestedFormat\":1," "\"cleanSession\":false,\"entityFormat\":1,\"base\":\"ems-esp\",\"discoveryPrefix\":\"homeassistant\",\"discoveryType\":0,\"nestedFormat\":1,"
"\"haEnabled\":true,\"mqttQos\":0,\"mqttRetain\":false,\"publishTimeHeartbeat\":60,\"publishTimeBoiler\":10,\"publishTimeThermostat\":10," "\"haEnabled\":true,\"mqttQos\":0,\"mqttRetain\":false,\"publishTimeHeartbeat\":60,\"publishTimeBoiler\":10,\"publishTimeThermostat\":10,"
"\"publishTimeSolar\":10,\"publishTimeMixer\":10,\"publishTimeWater\":0,\"publishTimeOther\":10,\"publishTimeSensor\":10,\"publishSingle\":false," "\"publishTimeSolar\":10,\"publishTimeMixer\":10,\"publishTimeWater\":0,\"publishTimeOther\":10,\"publishTimeSensor\":10,\"publishSingle\":false,"
"\"publish2command\":false,\"sendResponse\":false},\"syslog\":{\"enabled\":false},\"sensor\":{\"temperatureSensors\":2,\"temperatureSensorReads\":0," "\"publish2command\":false,\"sendResponse\":false},\"syslog\":{\"enabled\":false},\"sensor\":{\"temperatureSensors\":1,\"temperatureSensorReads\":0,"
"\"temperatureSensorFails\":0,\"analogSensors\":4,\"analogSensorReads\":0,\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{" "\"temperatureSensorFails\":0,\"analogSensors\":5,\"analogSensorReads\":0,\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{"
"\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\",\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0," "\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\",\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0,"
"\"busReadsFailed\":0,\"busWritesFailed\":0,\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":" "\"busReadsFailed\":0,\"busWritesFailed\":0,\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":"
"\"en\",\"txMode\":8,\"emsBusID\":11,\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false," "\"en\",\"txMode\":8,\"emsBusID\":11,\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false,"
@@ -180,8 +180,8 @@ void test_21() {
"0x2E " "0x2E "
"0x3B\"},{\"type\":\"thermostat\",\"name\":\"FW120\",\"deviceID\":\"0x10\",\"productID\":192,\"brand\":\"\",\"version\":\"01.00\",\"entities\":15," "0x3B\"},{\"type\":\"thermostat\",\"name\":\"FW120\",\"deviceID\":\"0x10\",\"productID\":192,\"brand\":\"\",\"version\":\"01.00\",\"entities\":15,"
"\"handlersReceived\":\"0x016F\",\"handlersFetched\":\"0x0170 0x0171\",\"handlersPending\":\"0xA3 0x06 0xA2 0x12 0x13 0x0172 0x0165 " "\"handlersReceived\":\"0x016F\",\"handlersFetched\":\"0x0170 0x0171\",\"handlersPending\":\"0xA3 0x06 0xA2 0x12 0x13 0x0172 0x0165 "
"0x0168\"},{\"type\":\"temperaturesensor\",\"name\":\"temperaturesensor\",\"entities\":2},{\"type\":\"analogsensor\",\"name\":\"analogsensor\"," "0x0168\"},{\"type\":\"temperaturesensor\",\"name\":\"temperaturesensor\",\"entities\":1},{\"type\":\"analogsensor\",\"name\":\"analogsensor\","
"\"entities\":4},{\"type\":\"scheduler\",\"name\":\"scheduler\",\"entities\":2},{\"type\":\"custom\",\"name\":\"custom\",\"entities\":4}]}]"; "\"entities\":5},{\"type\":\"scheduler\",\"name\":\"scheduler\",\"entities\":2},{\"type\":\"custom\",\"name\":\"custom\",\"entities\":4}]}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/system")); TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/system"));
} }
@@ -195,8 +195,8 @@ void test_22() {
"\"cleanSession\":false,\"entityFormat\":1,\"base\":\"ems-esp\",\"discoveryPrefix\":\"homeassistant\",\"discoveryType\":0,\"nestedFormat\":1," "\"cleanSession\":false,\"entityFormat\":1,\"base\":\"ems-esp\",\"discoveryPrefix\":\"homeassistant\",\"discoveryType\":0,\"nestedFormat\":1,"
"\"haEnabled\":true,\"mqttQos\":0,\"mqttRetain\":false,\"publishTimeHeartbeat\":60,\"publishTimeBoiler\":10,\"publishTimeThermostat\":10," "\"haEnabled\":true,\"mqttQos\":0,\"mqttRetain\":false,\"publishTimeHeartbeat\":60,\"publishTimeBoiler\":10,\"publishTimeThermostat\":10,"
"\"publishTimeSolar\":10,\"publishTimeMixer\":10,\"publishTimeWater\":0,\"publishTimeOther\":10,\"publishTimeSensor\":10,\"publishSingle\":false," "\"publishTimeSolar\":10,\"publishTimeMixer\":10,\"publishTimeWater\":0,\"publishTimeOther\":10,\"publishTimeSensor\":10,\"publishSingle\":false,"
"\"publish2command\":false,\"sendResponse\":false},\"syslog\":{\"enabled\":false},\"sensor\":{\"temperatureSensors\":2,\"temperatureSensorReads\":0," "\"publish2command\":false,\"sendResponse\":false},\"syslog\":{\"enabled\":false},\"sensor\":{\"temperatureSensors\":1,\"temperatureSensorReads\":0,"
"\"temperatureSensorFails\":0,\"analogSensors\":4,\"analogSensorReads\":0,\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{" "\"temperatureSensorFails\":0,\"analogSensors\":5,\"analogSensorReads\":0,\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{"
"\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\",\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0," "\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\",\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0,"
"\"busReadsFailed\":0,\"busWritesFailed\":0,\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":" "\"busReadsFailed\":0,\"busWritesFailed\":0,\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":"
"\"en\",\"txMode\":8,\"emsBusID\":11,\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false," "\"en\",\"txMode\":8,\"emsBusID\":11,\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false,"
@@ -208,8 +208,8 @@ void test_22() {
"0x2E " "0x2E "
"0x3B\"},{\"type\":\"thermostat\",\"name\":\"FW120\",\"deviceID\":\"0x10\",\"productID\":192,\"brand\":\"\",\"version\":\"01.00\",\"entities\":15," "0x3B\"},{\"type\":\"thermostat\",\"name\":\"FW120\",\"deviceID\":\"0x10\",\"productID\":192,\"brand\":\"\",\"version\":\"01.00\",\"entities\":15,"
"\"handlersReceived\":\"0x016F\",\"handlersFetched\":\"0x0170 0x0171\",\"handlersPending\":\"0xA3 0x06 0xA2 0x12 0x13 0x0172 0x0165 " "\"handlersReceived\":\"0x016F\",\"handlersFetched\":\"0x0170 0x0171\",\"handlersPending\":\"0xA3 0x06 0xA2 0x12 0x13 0x0172 0x0165 "
"0x0168\"},{\"type\":\"temperaturesensor\",\"name\":\"temperaturesensor\",\"entities\":2},{\"type\":\"analogsensor\",\"name\":\"analogsensor\"," "0x0168\"},{\"type\":\"temperaturesensor\",\"name\":\"temperaturesensor\",\"entities\":1},{\"type\":\"analogsensor\",\"name\":\"analogsensor\","
"\"entities\":4},{\"type\":\"scheduler\",\"name\":\"scheduler\",\"entities\":2},{\"type\":\"custom\",\"name\":\"custom\",\"entities\":4}]}]"; "\"entities\":5},{\"type\":\"scheduler\",\"name\":\"scheduler\",\"entities\":2},{\"type\":\"custom\",\"name\":\"custom\",\"entities\":4}]}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/system/info")); TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/system/info"));
} }
@@ -247,12 +247,12 @@ void test_28() {
} }
void test_29() { void test_29() {
auto expected_response = "[{\"test_tempsensor1\":12.3,\"test_tempsensor2\":45.6}]"; auto expected_response = "[{\"test_tempsensor1\":12.3,\"test_tempsensor2\":45.6,\"gateway_temperature\":28.1}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/temperaturesensor")); TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/temperaturesensor"));
} }
void test_30() { void test_30() {
auto expected_response = "[{\"test_tempsensor1\":12.3,\"test_tempsensor2\":45.6}]"; auto expected_response = "[{\"test_tempsensor1\":12.3,\"test_tempsensor2\":45.6,\"gateway_temperature\":28.1}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/temperaturesensor/info")); TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/temperaturesensor/info"));
} }
@@ -274,19 +274,19 @@ void test_33() {
} }
void test_34() { void test_34() {
auto expected_response = "[{\"test_analogsensor1\":0,\"test_analogsensor2\":1,\"test_analogsensor3\":0,\"test_analogsensor4\":0}]"; auto expected_response = "[{\"test_analogsensor1\":0,\"test_analogsensor2\":1,\"test_analogsensor3\":0,\"test_analogsensor4\":0,\"test_analogsensor5\":0}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor")); TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor"));
} }
void test_35() { void test_35() {
auto expected_response = "[{\"test_analogsensor1\":0,\"test_analogsensor2\":1,\"test_analogsensor3\":0,\"test_analogsensor4\":0}]"; auto expected_response = "[{\"test_analogsensor1\":0,\"test_analogsensor2\":1,\"test_analogsensor3\":0,\"test_analogsensor4\":0,\"test_analogsensor5\":0}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor/info")); TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor/info"));
} }
void test_36() { void test_36() {
auto expected_response = auto expected_response =
"[{\"name\":\"test_analogsensor1\",\"fullname\":\"test_analogsensor1\",\"gpio\":36,\"type\":\"number\",\"analog\":\"adc\",\"value\":0,\"readable\":" "[{\"name\":\"test_analogsensor1\",\"fullname\":\"test_analogsensor1\",\"gpio\":36,\"type\":\"number\",\"analog\":\"adc\",\"value\":0,\"readable\":"
"true,\"writeable\":false,\"visible\":true,\"is_system\":true,\"offset\":0,\"factor\":0.1,\"uom\":\"mV\"}]"; "true,\"writeable\":false,\"visible\":true,\"is_system\":false,\"offset\":0,\"factor\":0.2,\"uom\":\"mV\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor/test_analogsensor1")); TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor/test_analogsensor1"));
} }
@@ -437,4 +437,4 @@ void run_tests() {
RUN_TEST(test_54); RUN_TEST(test_54);
} }
// ---------- END - CUT HERE ---------- // ---------- END - CUT HERE ----------