option to set how booleans are rendered - #509

This commit is contained in:
proddy
2020-09-23 19:27:45 +02:00
parent 4f05a0c695
commit d8bbdb504a
11 changed files with 84 additions and 22 deletions

View File

@@ -8,12 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2.1]
### Added
- boiler heatingactivated, automatic select parameter telegrams for write
- boiler wWType parameter, in Console and MQTT
- boiler `heatingactivated`, automatic select parameter telegrams for write
- boiler `wWType` parameter, in Console and MQTT
- support for uploading compressed firmware binaries in web UI
- setting to manually override the MQTT retain flag
- New API via HTTP REST API. See https://emsesp.github.io/docs/#/API
- New API via HTTP REST API to read and set values. See https://emsesp.github.io/docs/#/API
- `show commands` command
- exporting of system settings using the `system info` command in Web and Console. Added link into the Web's Settings page.
- setting to change how booleans are rendered in MQTT (on/off, true/false, 1/0)
### Fixed
- fix wwontime readback

View File

@@ -14,6 +14,8 @@ import { EMSESPSettings } from './EMSESPtypes';
export const EMSESP_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "emsespSettings";
export const WebAPISystemInfo = window.location.origin + "/api?device=system&cmd=info";
type EMSESPSettingsControllerProps = RestControllerProps<EMSESPSettings>;
class EMSESPSettingsController extends Component<EMSESPSettingsControllerProps> {
@@ -49,6 +51,7 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
<Box bgcolor="info.main" p={2} mt={2} mb={2}>
<Typography variant="body1">
Customize EMS-ESP by modifying the default settings here. Refer to the <Link href="https://emsesp.github.io/docs/#/Configure-firmware?id=settings" color="primary">{'Documentation'}</Link>&nbsp;for descriptions of each setting.
<p>You can also <Link target="_blank" href={WebAPISystemInfo} color="primary">{'export'}</Link>&nbsp; all the system settings to make a backup.</p>
</Typography>
</Box>
<br></br>
@@ -194,6 +197,17 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
}
label="Enable WEB API (for write commands)"
/>
<SelectValidator name="bool_format"
label="Boolean Format"
value={data.bool_format}
fullWidth
variant="outlined"
onChange={handleValueChange('bool_format')}
margin="normal">
<MenuItem value={1}>on/off</MenuItem>
<MenuItem value={2}>true/false</MenuItem>
<MenuItem value={3}>1/0</MenuItem>
</SelectValidator>
<br></br>
<Typography variant="h6" color="primary" >
Syslog

View File

@@ -14,6 +14,7 @@ export interface EMSESPSettings {
led_gpio: number;
hide_led: boolean;
api_enabled: boolean;
bool_format: number;
}
export enum busConnectionStatus {

View File

@@ -44,6 +44,7 @@ class DummySettings {
uint16_t publish_time_mixing;
uint16_t publish_time_other;
uint16_t publish_time_sensor;
uint8_t bool_format;
static void read(DummySettings & settings, JsonObject & root){};
static void read(DummySettings & settings){};

View File

@@ -43,6 +43,7 @@ void EMSESPSettings::read(EMSESPSettings & settings, JsonObject & root) {
root["led_gpio"] = settings.led_gpio;
root["hide_led"] = settings.hide_led;
root["api_enabled"] = settings.api_enabled;
root["bool_format"] = settings.bool_format;
}
StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & settings) {
@@ -61,6 +62,7 @@ StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & set
settings.led_gpio = root["led_gpio"] | EMSESP_DEFAULT_LED_GPIO;
settings.hide_led = root["hide_led"] | EMSESP_DEFAULT_HIDE_LED;
settings.api_enabled = root["api_enabled"] | EMSESP_DEFAULT_API_ENABLED;
settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT;
return StateUpdateResult::CHANGED;
}
@@ -69,11 +71,10 @@ StateUpdateResult EMSESPSettings::update(JsonObject & root, EMSESPSettings & set
// either via the Web UI or via the Console
void EMSESPSettingsService::onUpdate() {
EMSESP::shower_.start();
// EMSESP::system_.syslog_init(); // changing SysLog will require a restart
EMSESP::init_tx();
System::set_led();
Sensor sensor_; // Dallas sensors
sensor_.start();
System::init();
}
void EMSESPSettingsService::begin() {

View File

@@ -36,6 +36,7 @@
#define EMSESP_DEFAULT_HIDE_LED false
#define EMSESP_DEFAULT_DALLAS_PARASITE false
#define EMSESP_DEFAULT_API_ENABLED true
#define EMSESP_DEFAULT_BOOL_FORMAT 1 // on/off
// Default GPIO PIN definitions
#if defined(ESP8266)
@@ -77,6 +78,7 @@ class EMSESPSettings {
uint8_t led_gpio;
bool hide_led;
bool api_enabled;
uint8_t bool_format;
static void read(EMSESPSettings & settings, JsonObject & root);
static StateUpdateResult update(JsonObject & root, EMSESPSettings & settings);

View File

@@ -156,6 +156,7 @@ class EMSdevice {
// format:
// for ints its 0=no division, 255=handle as boolean, other divide by the value given and render with a decimal point
// for floats its the precision in number of decimal places from 0 to 8
// for bools its EMS_VALUE_BOOL (0xFF)
template <typename Value>
static void print_value(uuid::console::Shell & shell,
uint8_t padding,

View File

@@ -20,6 +20,8 @@
namespace emsesp {
uint8_t Helpers::bool_format_ = 1; // on/off
// like itoa but for hex, and quicker
char * Helpers::hextoa(char * result, const uint8_t value) {
char * p = result;
@@ -120,17 +122,28 @@ char * Helpers::smallitoa(char * result, const uint16_t value) {
return result;
}
// work out how to display booleans
void Helpers::render_boolean(char * result, bool value) {
if (bool_format() == 1) {
strlcpy(result, value ? "on" : "off", 5);
} else if (bool_format() == 2) {
strlcpy(result, value ? "true" : "false", 7);
} else {
strlcpy(result, value ? "1" : "0", 2);
}
}
// convert unsigned int (single byte) to text value and returns it
// format: 255=boolean, 0=no formatting, otherwise divide by format
// format: 255(0xFF)=boolean, 0=no formatting, otherwise divide by format
char * Helpers::render_value(char * result, uint8_t value, uint8_t format) {
// special check if its a boolean
if (format == EMS_VALUE_BOOL) {
if (value == EMS_VALUE_BOOL_OFF) {
strlcpy(result, "off", 5);
render_boolean(result, false);
} else if (value == EMS_VALUE_BOOL_NOTSET) {
return nullptr;
} else {
strlcpy(result, "on", 5); // assume on. could have value 0x01 or 0xFF
render_boolean(result, true); // assume on. could have value 0x01 or 0xFF
}
return result;
}
@@ -169,9 +182,11 @@ char * Helpers::render_value(char * result, const float value, const uint8_t for
char * ret = result;
long whole = (long)value;
Helpers::itoa(result, whole, 10);
while (*result != '\0') {
result++;
}
*result++ = '.';
long decimal = abs((long)((value - whole) * p[format]));
itoa(result, decimal, 10);
@@ -329,27 +344,27 @@ bool Helpers::check_abs(const int32_t i) {
}
// for booleans, use isBool true (EMS_VALUE_BOOL)
bool Helpers::hasValue(const uint8_t &v, const uint8_t isBool) {
bool Helpers::hasValue(const uint8_t & v, const uint8_t isBool) {
if (isBool == EMS_VALUE_BOOL) {
return (v != EMS_VALUE_BOOL_NOTSET);
}
return (v != EMS_VALUE_UINT_NOTSET);
}
bool Helpers::hasValue(const int8_t &v) {
bool Helpers::hasValue(const int8_t & v) {
return (v != EMS_VALUE_INT_NOTSET);
}
// for short these are typically 0x8300, 0x7D00 and sometimes 0x8000
bool Helpers::hasValue(const int16_t &v) {
bool Helpers::hasValue(const int16_t & v) {
return (abs(v) < EMS_VALUE_USHORT_NOTSET);
}
bool Helpers::hasValue(const uint16_t &v) {
bool Helpers::hasValue(const uint16_t & v) {
return (v < EMS_VALUE_USHORT_NOTSET);
}
bool Helpers::hasValue(const uint32_t &v) {
bool Helpers::hasValue(const uint32_t & v) {
return (v != EMS_VALUE_ULONG_NOTSET);
}

View File

@@ -38,6 +38,8 @@ class Helpers {
static char * render_value(char * result, const uint32_t value, const uint8_t format);
static char * render_value(char * result, const int16_t value, const uint8_t format);
static void render_boolean(char * result, bool value);
static char * smallitoa(char * result, const uint8_t value);
static char * smallitoa(char * result, const uint16_t value);
static char * itoa(char * result, int16_t value, const uint8_t base = 10);
@@ -46,15 +48,23 @@ class Helpers {
static bool check_abs(const int32_t i);
static double round2(double value);
static void bool_format(uint8_t bool_format) {
bool_format_ = bool_format;
}
static uint8_t bool_format() {
return bool_format_;
}
#ifdef EMSESP_STANDALONE
static char * ultostr(char * ptr, uint32_t value, const uint8_t base);
#endif
static bool hasValue(const uint8_t &v, const uint8_t isBool = 0);
static bool hasValue(const int8_t &v);
static bool hasValue(const int16_t &v);
static bool hasValue(const uint16_t &v);
static bool hasValue(const uint32_t &v);
static bool hasValue(const uint8_t & v, const uint8_t isBool = 0);
static bool hasValue(const int8_t & v);
static bool hasValue(const int16_t & v);
static bool hasValue(const uint16_t & v);
static bool hasValue(const uint32_t & v);
static std::string toLower(std::string const & s);
@@ -62,6 +72,9 @@ class Helpers {
static bool value2float(const char * v, float & value);
static bool value2bool(const char * v, bool & value);
static bool value2string(const char * v, std::string & value);
private:
static uint8_t bool_format_;
};
} // namespace emsesp

View File

@@ -152,9 +152,6 @@ void System::start() {
EMSESP::esp8266React.getWiFiSettingsService()->read(
[&](WiFiSettings & wifiSettings) { LOG_INFO(F("System %s booted (EMS-ESP version %s)"), wifiSettings.hostname.c_str(), EMSESP_APP_VERSION); });
syslog_init(); // init SysLog
set_led(); // init LED
// these commands respond to the topic "system" and take a payload like {cmd:"", data:"", id:""}
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) {
Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F("pin"), System::command_pin);
@@ -162,6 +159,18 @@ void System::start() {
Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F("info"), System::command_info);
});
syslog_init(); // init SysLog
init();
}
// init stuff. This is called when settings are changed in the web
void System::init() {
set_led(); // init LED
// set the boolean format used for rendering booleans
EMSESP::emsespSettingsService.read([&](EMSESPSettings & settings) { Helpers::bool_format(settings.bool_format); });
EMSESP::init_tx(); // start UART
}
@@ -897,6 +906,8 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
node["dallas_parasite"] = settings.dallas_parasite;
node["led_gpio"] = settings.led_gpio;
node["hide_led"] = settings.hide_led;
node["api_enabled"] = settings.api_enabled;
node["bool_format"] = settings.bool_format;
});
#endif

View File

@@ -57,6 +57,7 @@ class System {
static bool upload_status();
static void show_mem(const char * note);
static void set_led();
static void init();
bool check_upgrade();
void syslog_init();