mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
@@ -4,13 +4,15 @@
|
|||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
- Translations in Web UI and all device entity names to German. [#22](https://github.com/emsesp/EMS-ESP32/issues/22)
|
- Translations in Web UI and all device entity names (DE, NL, SE, PL, NO, ...) [#22](https://github.com/emsesp/EMS-ESP32/issues/22)
|
||||||
- Add support for Lolin C3 mini [#620](https://github.com/emsesp/EMS-ESP32/pull/620)
|
- Add support for Lolin C3 mini [#620](https://github.com/emsesp/EMS-ESP32/pull/620)
|
||||||
- Add Greenstar 30Ri boiler
|
- Add support for ESP32-S2 [#667](https://github.com/emsesp/EMS-ESP32/pull/667)
|
||||||
|
- Add devices: Greenstar 30Ri boiler, Junkers FW500 thermostat, Buderus BC30 controller
|
||||||
- Add program memory info
|
- Add program memory info
|
||||||
|
- Add mqtt queue and connection infos
|
||||||
- Add min/max setting to customizations
|
- Add min/max setting to customizations
|
||||||
- Adapt min/max if ems-value is not in this range
|
- Adapt min/max if ems-value is not in this range
|
||||||
- Add heatpump settings for inputs and limits
|
- Add heat pump settings for inputs and limits
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
@@ -20,6 +22,8 @@
|
|||||||
|
|
||||||
- Discovery in HomeAssistant don't work with custom base topic. [#596](https://github.com/emsesp/EMS-ESP32/issues/596) Base topic containing `/` are changed to `_`
|
- Discovery in HomeAssistant don't work with custom base topic. [#596](https://github.com/emsesp/EMS-ESP32/issues/596) Base topic containing `/` are changed to `_`
|
||||||
- RF room temperature sensor are shown as thermostat
|
- RF room temperature sensor are shown as thermostat
|
||||||
|
- render mqtt float json values with trailing zero
|
||||||
|
- removed flash strings
|
||||||
|
|
||||||
## **BREAKING CHANGES:**
|
## **BREAKING CHANGES:**
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import { ReactComponent as NLflag } from './i18n/NL.svg';
|
|||||||
import { ReactComponent as DEflag } from './i18n/DE.svg';
|
import { ReactComponent as DEflag } from './i18n/DE.svg';
|
||||||
import { ReactComponent as GBflag } from './i18n/GB.svg';
|
import { ReactComponent as GBflag } from './i18n/GB.svg';
|
||||||
import { ReactComponent as SEflag } from './i18n/SE.svg';
|
import { ReactComponent as SEflag } from './i18n/SE.svg';
|
||||||
|
import { ReactComponent as PLflag } from './i18n/PL.svg';
|
||||||
|
import { ReactComponent as NOflag } from './i18n/NO.svg';
|
||||||
|
|
||||||
const SignIn: FC = () => {
|
const SignIn: FC = () => {
|
||||||
const authenticationContext = useContext(AuthenticationContext);
|
const authenticationContext = useContext(AuthenticationContext);
|
||||||
@@ -123,6 +125,19 @@ const SignIn: FC = () => {
|
|||||||
<SEflag style={{ width: 24 }} />
|
<SEflag style={{ width: 24 }} />
|
||||||
SE
|
SE
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button size="small" variant={locale === 'pl' ? 'contained' : 'outlined'} onClick={() => selectLocale('pl')}>
|
||||||
|
<PLflag style={{ width: 24 }} />
|
||||||
|
PL
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
disabled
|
||||||
|
size="small"
|
||||||
|
variant={locale === 'no' ? 'contained' : 'outlined'}
|
||||||
|
onClick={() => selectLocale('no')}
|
||||||
|
>
|
||||||
|
<NOflag style={{ width: 24 }} />
|
||||||
|
NO
|
||||||
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<ValidatedTextField
|
<ValidatedTextField
|
||||||
|
|||||||
@@ -92,3 +92,14 @@ board_upload.flash_size = 4MB
|
|||||||
board_build.partitions = esp32_partition_4M.csv
|
board_build.partitions = esp32_partition_4M.csv
|
||||||
build_flags = ${common.build_flags}
|
build_flags = ${common.build_flags}
|
||||||
build_unflags = ${common.unbuild_flags}
|
build_unflags = ${common.unbuild_flags}
|
||||||
|
|
||||||
|
[env:lolin_s2_mini]
|
||||||
|
extra_scripts =
|
||||||
|
pre:scripts/build_interface.py
|
||||||
|
scripts/rename_fw.py
|
||||||
|
board = lolin_s2_mini
|
||||||
|
platform = espressif32
|
||||||
|
board_upload.flash_size = 4MB
|
||||||
|
board_build.partitions = esp32_partition_4M.csv
|
||||||
|
build_flags = ${common.build_flags}
|
||||||
|
build_unflags = ${common.unbuild_flags}
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ void AnalogSensor::publish_values(const bool force) {
|
|||||||
case AnalogType::PWM_0:
|
case AnalogType::PWM_0:
|
||||||
case AnalogType::PWM_1:
|
case AnalogType::PWM_1:
|
||||||
case AnalogType::PWM_2:
|
case AnalogType::PWM_2:
|
||||||
dataSensor["value"] = sensor.value(); // float
|
dataSensor["value"] = serialized(Helpers::render_value(s, sensor.value(), 2)); // float
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dataSensor["value"] = (uint8_t)sensor.value(); // convert to char for 1 or 0
|
dataSensor["value"] = (uint8_t)sensor.value(); // convert to char for 1 or 0
|
||||||
|
|||||||
@@ -25,8 +25,10 @@
|
|||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
|
#ifndef ARDUINO_LOLIN_S2_MINI
|
||||||
#include <esp_bt.h>
|
#include <esp_bt.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <uuid/log.h>
|
#include <uuid/log.h>
|
||||||
|
|
||||||
|
|||||||
@@ -360,14 +360,15 @@ bool DallasSensor::command_info(const char * value, const int8_t id, JsonObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto & sensor : sensors_) {
|
for (const auto & sensor : sensors_) {
|
||||||
|
char val[10];
|
||||||
if (id == -1) { // show number and id
|
if (id == -1) { // show number and id
|
||||||
JsonObject dataSensor = output.createNestedObject(sensor.name());
|
JsonObject dataSensor = output.createNestedObject(sensor.name());
|
||||||
dataSensor["id"] = sensor.id();
|
dataSensor["id"] = sensor.id();
|
||||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||||
dataSensor["temp"] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
|
dataSensor["temp"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||||
}
|
}
|
||||||
} else if (Helpers::hasValue(sensor.temperature_c)) {
|
} else if (Helpers::hasValue(sensor.temperature_c)) {
|
||||||
output[sensor.name()] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
|
output[sensor.name()] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,14 +393,18 @@ bool DallasSensor::get_value_info(JsonObject & output, const char * cmd, const i
|
|||||||
if (strcmp(command_s, sensor.name().c_str()) == 0) {
|
if (strcmp(command_s, sensor.name().c_str()) == 0) {
|
||||||
output["id"] = sensor.id();
|
output["id"] = sensor.id();
|
||||||
output["name"] = sensor.name();
|
output["name"] = sensor.name();
|
||||||
|
char val[10];
|
||||||
|
|
||||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||||
output["value"] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
|
output["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
output["type"] = F_(number);
|
output["type"] = F_(number);
|
||||||
output["min"] = Helpers::transformNumFloat(-55, 0, EMSESP::system_.fahrenheit() ? 2 : 0);
|
output["min"] = serialized(Helpers::render_value(val, -55, 0, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||||
output["max"] = Helpers::transformNumFloat(125, 0, EMSESP::system_.fahrenheit() ? 2 : 0);
|
output["max"] = serialized(Helpers::render_value(val, 125, 0, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||||
output["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
|
output["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
|
||||||
output["writeable"] = false;
|
output["writeable"] = false;
|
||||||
|
|
||||||
// if we're filtering on an attribute, go find it
|
// if we're filtering on an attribute, go find it
|
||||||
if (attribute_s) {
|
if (attribute_s) {
|
||||||
if (output.containsKey(attribute_s)) {
|
if (output.containsKey(attribute_s)) {
|
||||||
@@ -469,14 +474,15 @@ void DallasSensor::publish_values(const bool force) {
|
|||||||
|
|
||||||
for (auto & sensor : sensors_) {
|
for (auto & sensor : sensors_) {
|
||||||
bool has_value = Helpers::hasValue(sensor.temperature_c);
|
bool has_value = Helpers::hasValue(sensor.temperature_c);
|
||||||
|
char val[10];
|
||||||
if (Mqtt::is_nested()) {
|
if (Mqtt::is_nested()) {
|
||||||
JsonObject dataSensor = doc.createNestedObject(sensor.id());
|
JsonObject dataSensor = doc.createNestedObject(sensor.id());
|
||||||
dataSensor["name"] = sensor.name();
|
dataSensor["name"] = sensor.name();
|
||||||
if (has_value) {
|
if (has_value) {
|
||||||
dataSensor["temp"] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
|
dataSensor["temp"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||||
}
|
}
|
||||||
} else if (has_value) {
|
} else if (has_value) {
|
||||||
doc[sensor.name()] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
|
doc[sensor.name()] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the HA MQTT config
|
// create the HA MQTT config
|
||||||
|
|||||||
@@ -110,6 +110,7 @@
|
|||||||
{109, DeviceType::THERMOSTAT, "FB10", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
{109, DeviceType::THERMOSTAT, "FB10", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||||
{110, DeviceType::THERMOSTAT, "FB100", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
{110, DeviceType::THERMOSTAT, "FB100", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||||
{111, DeviceType::THERMOSTAT, "FR10", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
{111, DeviceType::THERMOSTAT, "FR10", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||||
|
{116, DeviceType::THERMOSTAT, "FW500", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||||
{147, DeviceType::THERMOSTAT, "FR50", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD},
|
{147, DeviceType::THERMOSTAT, "FR50", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD},
|
||||||
{191, DeviceType::THERMOSTAT, "FR120", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
{191, DeviceType::THERMOSTAT, "FR120", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_OLD}, // older model
|
||||||
{192, DeviceType::THERMOSTAT, "FW120", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
{192, DeviceType::THERMOSTAT, "FW120", DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||||
|
|||||||
@@ -686,7 +686,13 @@ void Thermostat::process_JunkersSet(std::shared_ptr<const Telegram> telegram) {
|
|||||||
has_update(telegram, hc->control, 1); // remote: 0-off, 1-FB10, 2-FB100
|
has_update(telegram, hc->control, 1); // remote: 0-off, 1-FB10, 2-FB100
|
||||||
has_enumupdate(telegram, hc->program, 13, 1); // 1-6: 1 = A, 2 = B,...
|
has_enumupdate(telegram, hc->program, 13, 1); // 1-6: 1 = A, 2 = B,...
|
||||||
has_enumupdate(telegram, hc->mode, 14, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto
|
has_enumupdate(telegram, hc->mode, 14, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto
|
||||||
has_update(telegram, hc->roomsensor, 9); // 1-intern, 2-extern, 3-autoselect the lower value
|
has_update(telegram, hc->daytemp, 17); // is * 2
|
||||||
|
has_update(telegram, hc->nighttemp, 16); // is * 2
|
||||||
|
has_update(telegram, hc->nofrosttemp, 15); // is * 2
|
||||||
|
has_update(telegram, hc->control, 1); // remote: 0-off, 1-FB10, 2-FB100
|
||||||
|
has_enumupdate(telegram, hc->program, 13, 1); // 1-6: 1 = A, 2 = B,...
|
||||||
|
has_enumupdate(telegram, hc->mode, 14, 1); // 0 = nofrost, 1 = eco, 2 = heat, 3 = auto
|
||||||
|
has_enumupdate(telegram, hc->roomsensor, 9, 1); // 1-intern, 2-extern, 3-autoselect the lower value
|
||||||
}
|
}
|
||||||
|
|
||||||
// type 0x0179, ff
|
// type 0x0179, ff
|
||||||
@@ -1365,9 +1371,11 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
|||||||
has_update(dateTime_, newdatetime, sizeof(dateTime_));
|
has_update(dateTime_, newdatetime, sizeof(dateTime_));
|
||||||
|
|
||||||
bool ivtclock = (telegram->message_data[0] & 0x80) == 0x80; // dont sync ivt-clock, #439
|
bool ivtclock = (telegram->message_data[0] & 0x80) == 0x80; // dont sync ivt-clock, #439
|
||||||
|
bool junkersclock = model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS;
|
||||||
time_t ttime = mktime(tm_); // thermostat time
|
time_t ttime = mktime(tm_); // thermostat time
|
||||||
|
|
||||||
// correct thermostat clock if we have valid ntp time, and could write the command
|
// correct thermostat clock if we have valid ntp time, and could write the command
|
||||||
if (!ivtclock && tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) {
|
if (!ivtclock && !junkersclock && tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) {
|
||||||
double difference = difftime(now, ttime);
|
double difference = difftime(now, ttime);
|
||||||
if (difference > 15 || difference < -15) {
|
if (difference > 15 || difference < -15) {
|
||||||
set_datetime("ntp", -1); // set from NTP
|
set_datetime("ntp", -1); // set from NTP
|
||||||
@@ -1717,7 +1725,7 @@ bool Thermostat::set_roomsensor(const char * value, const int8_t id) {
|
|||||||
uint8_t ctrl = 0;
|
uint8_t ctrl = 0;
|
||||||
if (model() == EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) {
|
if (model() == EMS_DEVICE_FLAG_JUNKERS && !has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) {
|
||||||
if (Helpers::value2enum(value, ctrl, FL_(enum_roomsensor))) {
|
if (Helpers::value2enum(value, ctrl, FL_(enum_roomsensor))) {
|
||||||
write_command(set_typeids[hc->hc()], 9, ctrl);
|
write_command(set_typeids[hc->hc()], 9, ctrl + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2165,6 +2173,10 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
|||||||
data[5] = tm_->tm_sec;
|
data[5] = tm_->tm_sec;
|
||||||
data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su
|
data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su
|
||||||
data[7] = tm_->tm_isdst + 2; // set DST and flag for ext. clock
|
data[7] = tm_->tm_isdst + 2; // set DST and flag for ext. clock
|
||||||
|
if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||||
|
data[6]++; // Junkers use 1-7;
|
||||||
|
data[7] = 0;
|
||||||
|
}
|
||||||
} else if (dt.length() == 23) {
|
} else if (dt.length() == 23) {
|
||||||
data[0] = (dt[7] - '0') * 100 + (dt[8] - '0') * 10 + (dt[9] - '0'); // year
|
data[0] = (dt[7] - '0') * 100 + (dt[8] - '0') * 10 + (dt[9] - '0'); // year
|
||||||
data[1] = (dt[3] - '0') * 10 + (dt[4] - '0'); // month
|
data[1] = (dt[3] - '0') * 10 + (dt[4] - '0'); // month
|
||||||
@@ -2174,6 +2186,9 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
|||||||
data[5] = (dt[17] - '0') * 10 + (dt[18] - '0'); // sec
|
data[5] = (dt[17] - '0') * 10 + (dt[18] - '0'); // sec
|
||||||
data[6] = (dt[20] - '0'); // day of week, Mo:0
|
data[6] = (dt[20] - '0'); // day of week, Mo:0
|
||||||
data[7] = (dt[22] - '0') + 2; // DST and flag
|
data[7] = (dt[22] - '0') + 2; // DST and flag
|
||||||
|
if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||||
|
data[7] = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING("Set date: invalid data, wrong length");
|
LOG_WARNING("Set date: invalid data, wrong length");
|
||||||
return false;
|
return false;
|
||||||
@@ -3846,8 +3861,9 @@ void Thermostat::register_device_values() {
|
|||||||
MAKE_CF_CB(set_wwVacation));
|
MAKE_CF_CB(set_wwVacation));
|
||||||
break;
|
break;
|
||||||
case EMS_DEVICE_FLAG_JUNKERS:
|
case EMS_DEVICE_FLAG_JUNKERS:
|
||||||
if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) {
|
|
||||||
// FR100 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/536
|
// FR100 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/536
|
||||||
|
// FW500 is not writable, see. https://github.com/emsesp/EMS-ESP32/issues/666
|
||||||
|
if (has_flags(EMS_DEVICE_FLAG_JUNKERS_OLD)) {
|
||||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(tpl_datetime), FL_(dateTime), DeviceValueUOM::NONE);
|
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(tpl_datetime), FL_(dateTime), DeviceValueUOM::NONE);
|
||||||
} else {
|
} else {
|
||||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
|
||||||
|
|||||||
@@ -790,9 +790,9 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
|||||||
} else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
|
} else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
|
||||||
obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
|
obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
|
||||||
} else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
} else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||||
obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
|
obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator);
|
||||||
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||||
obj["v"] = dv.numeric_operator ? (*(uint32_t *)(dv.value_p) / dv.numeric_operator) : *(uint32_t *)(dv.value_p);
|
obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator);
|
||||||
} else {
|
} else {
|
||||||
obj["v"] = ""; // must have a value for sorting to work
|
obj["v"] = ""; // must have a value for sorting to work
|
||||||
}
|
}
|
||||||
@@ -891,40 +891,18 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
|||||||
|
|
||||||
// handle Integers and Floats
|
// handle Integers and Floats
|
||||||
else {
|
else {
|
||||||
int8_t num_op = dv.numeric_operator;
|
|
||||||
bool make_float;
|
|
||||||
if (num_op == 0) {
|
|
||||||
// no changes to number
|
|
||||||
make_float = false;
|
|
||||||
num_op = 1; // so it gets *1
|
|
||||||
} else if (num_op < 0) {
|
|
||||||
// negative numbers, convert to a positive multiplier
|
|
||||||
make_float = false;
|
|
||||||
num_op *= -1;
|
|
||||||
} else {
|
|
||||||
// has a divider, make it a float
|
|
||||||
make_float = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// always convert temperatures to floats with 1 decimal place
|
|
||||||
if ((dv.uom == DeviceValueUOM::DEGREES) || (dv.uom == DeviceValueUOM::DEGREES_R)) {
|
|
||||||
make_float = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dv.type == DeviceValueType::INT) {
|
if (dv.type == DeviceValueType::INT) {
|
||||||
obj["v"] = make_float ? Helpers::transformNumFloat(*(int8_t *)(dv.value_p), num_op, fahrenheit) : *(int8_t *)(dv.value_p) * num_op;
|
obj["v"] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
|
||||||
} else if (dv.type == DeviceValueType::UINT) {
|
} else if (dv.type == DeviceValueType::UINT) {
|
||||||
obj["v"] = make_float ? Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), num_op, fahrenheit) : *(uint8_t *)(dv.value_p) * num_op;
|
obj["v"] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
|
||||||
} else if (dv.type == DeviceValueType::SHORT) {
|
} else if (dv.type == DeviceValueType::SHORT) {
|
||||||
obj["v"] = make_float ? Helpers::transformNumFloat(*(int16_t *)(dv.value_p), num_op, fahrenheit) : *(int16_t *)(dv.value_p) * num_op;
|
obj["v"] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
|
||||||
} else if (dv.type == DeviceValueType::USHORT) {
|
} else if (dv.type == DeviceValueType::USHORT) {
|
||||||
obj["v"] = make_float ? Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), num_op, fahrenheit) : *(uint16_t *)(dv.value_p) * num_op;
|
obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
|
||||||
} else if (dv.type == DeviceValueType::ULONG) {
|
} else if (dv.type == DeviceValueType::ULONG) {
|
||||||
obj["v"] = make_float ? Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op) : *(uint32_t *)(dv.value_p) * num_op;
|
obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator);
|
||||||
} else if (dv.type == DeviceValueType::TIME) {
|
} else if (dv.type == DeviceValueType::TIME) {
|
||||||
// sometimes we need to divide by 60
|
obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator);
|
||||||
obj["v"] = (num_op == DeviceValueNumOp::DV_NUMOP_DIV60) ? (uint32_t)Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op)
|
|
||||||
: *(uint32_t *)(dv.value_p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1091,8 +1069,6 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
|||||||
// search device value with this tag
|
// search device value with this tag
|
||||||
for (auto & dv : devicevalues_) {
|
for (auto & dv : devicevalues_) {
|
||||||
if (!strcmp(command_s, dv.short_name) && (tag <= 0 || tag == dv.tag)) {
|
if (!strcmp(command_s, dv.short_name) && (tag <= 0 || tag == dv.tag)) {
|
||||||
int8_t num_op = dv.numeric_operator;
|
|
||||||
|
|
||||||
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
||||||
|
|
||||||
const char * type = "type";
|
const char * type = "type";
|
||||||
@@ -1113,6 +1089,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
|||||||
json["circuit"] = tag_to_mqtt(dv.tag);
|
json["circuit"] = tag_to_mqtt(dv.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char val[10];
|
||||||
switch (dv.type) {
|
switch (dv.type) {
|
||||||
case DeviceValueType::ENUM: {
|
case DeviceValueType::ENUM: {
|
||||||
if (*(uint8_t *)(dv.value_p) < dv.options_size) {
|
if (*(uint8_t *)(dv.value_p) < dv.options_size) {
|
||||||
@@ -1132,35 +1109,35 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
|||||||
|
|
||||||
case DeviceValueType::USHORT:
|
case DeviceValueType::USHORT:
|
||||||
if (Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
|
if (Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
|
||||||
json[value] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), num_op, fahrenheit);
|
json[value] = serialized(Helpers::render_value(val, *(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
}
|
}
|
||||||
json[type] = F_(number);
|
json[type] = F_(number);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DeviceValueType::UINT:
|
case DeviceValueType::UINT:
|
||||||
if (Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
if (Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
|
||||||
json[value] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), num_op, fahrenheit);
|
json[value] = serialized(Helpers::render_value(val, *(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
}
|
}
|
||||||
json[type] = F_(number);
|
json[type] = F_(number);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DeviceValueType::SHORT:
|
case DeviceValueType::SHORT:
|
||||||
if (Helpers::hasValue(*(int16_t *)(dv.value_p))) {
|
if (Helpers::hasValue(*(int16_t *)(dv.value_p))) {
|
||||||
json[value] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), num_op, fahrenheit);
|
json[value] = serialized(Helpers::render_value(val, *(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
}
|
}
|
||||||
json[type] = F_(number);
|
json[type] = F_(number);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DeviceValueType::INT:
|
case DeviceValueType::INT:
|
||||||
if (Helpers::hasValue(*(int8_t *)(dv.value_p))) {
|
if (Helpers::hasValue(*(int8_t *)(dv.value_p))) {
|
||||||
json[value] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), num_op, fahrenheit);
|
json[value] = serialized(Helpers::render_value(val, *(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
}
|
}
|
||||||
json[type] = F_(number);
|
json[type] = F_(number);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DeviceValueType::ULONG:
|
case DeviceValueType::ULONG:
|
||||||
if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||||
json[value] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op);
|
json[value] = serialized(Helpers::render_value(val, *(uint32_t *)(dv.value_p), dv.numeric_operator));
|
||||||
}
|
}
|
||||||
json[type] = F_(number);
|
json[type] = F_(number);
|
||||||
break;
|
break;
|
||||||
@@ -1182,7 +1159,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
|||||||
|
|
||||||
case DeviceValueType::TIME:
|
case DeviceValueType::TIME:
|
||||||
if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||||
json[value] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op);
|
json[value] = serialized(Helpers::render_value(val, *(uint32_t *)(dv.value_p), dv.numeric_operator));
|
||||||
}
|
}
|
||||||
json[type] = F_(number);
|
json[type] = F_(number);
|
||||||
break;
|
break;
|
||||||
@@ -1364,64 +1341,22 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
|||||||
: (dv.uom == DeviceValueUOM::DEGREES) ? 2
|
: (dv.uom == DeviceValueUOM::DEGREES) ? 2
|
||||||
: (dv.uom == DeviceValueUOM::DEGREES_R) ? 1
|
: (dv.uom == DeviceValueUOM::DEGREES_R) ? 1
|
||||||
: 0;
|
: 0;
|
||||||
|
char val[10];
|
||||||
int8_t num_op = dv.numeric_operator;
|
|
||||||
bool make_float;
|
|
||||||
if (num_op == 0) {
|
|
||||||
// no changes to number
|
|
||||||
make_float = false;
|
|
||||||
num_op = 1; // so it gets *1
|
|
||||||
} else if (num_op < 0) {
|
|
||||||
// negative numbers, convert to a positive multiplier
|
|
||||||
make_float = false;
|
|
||||||
num_op *= -1;
|
|
||||||
} else {
|
|
||||||
// has a divider, make it a float
|
|
||||||
make_float = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// always convert temperatures to floats with 1 decimal place
|
|
||||||
if ((dv.uom == DeviceValueUOM::DEGREES) || (dv.uom == DeviceValueUOM::DEGREES_R)) {
|
|
||||||
make_float = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dv.type == DeviceValueType::INT) {
|
if (dv.type == DeviceValueType::INT) {
|
||||||
if (make_float) {
|
json[name] = serialized(Helpers::render_value(val, *(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
json[name] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), num_op, fahrenheit);
|
|
||||||
} else {
|
|
||||||
json[name] = *(int8_t *)(dv.value_p) * num_op;
|
|
||||||
}
|
|
||||||
} else if (dv.type == DeviceValueType::UINT) {
|
} else if (dv.type == DeviceValueType::UINT) {
|
||||||
if (make_float) {
|
json[name] = serialized(Helpers::render_value(val, *(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
json[name] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), num_op, fahrenheit);
|
|
||||||
} else {
|
|
||||||
json[name] = *(uint8_t *)(dv.value_p) * num_op;
|
|
||||||
}
|
|
||||||
} else if (dv.type == DeviceValueType::SHORT) {
|
} else if (dv.type == DeviceValueType::SHORT) {
|
||||||
if (make_float) {
|
json[name] = serialized(Helpers::render_value(val, *(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
json[name] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), num_op, fahrenheit);
|
|
||||||
} else {
|
|
||||||
json[name] = *(int16_t *)(dv.value_p) * num_op;
|
|
||||||
}
|
|
||||||
} else if (dv.type == DeviceValueType::USHORT) {
|
} else if (dv.type == DeviceValueType::USHORT) {
|
||||||
if (make_float) {
|
json[name] = serialized(Helpers::render_value(val, *(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit));
|
||||||
json[name] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), num_op, fahrenheit);
|
|
||||||
} else {
|
|
||||||
json[name] = *(uint16_t *)(dv.value_p) * num_op;
|
|
||||||
}
|
|
||||||
} else if (dv.type == DeviceValueType::ULONG) {
|
} else if (dv.type == DeviceValueType::ULONG) {
|
||||||
if (make_float) {
|
json[name] = serialized(Helpers::render_value(val, *(uint32_t *)(dv.value_p), dv.numeric_operator));
|
||||||
json[name] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op, fahrenheit);
|
|
||||||
} else {
|
|
||||||
json[name] = *(uint32_t *)(dv.value_p) * num_op;
|
|
||||||
}
|
|
||||||
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
|
||||||
uint32_t time_value;
|
uint32_t time_value = *(uint32_t *)(dv.value_p);
|
||||||
if (num_op == DeviceValueNumOp::DV_NUMOP_DIV60) {
|
if (dv.numeric_operator == DeviceValueNumOp::DV_NUMOP_DIV60) {
|
||||||
// sometimes we need to divide by 60
|
time_value /= 60; // sometimes we need to divide by 60
|
||||||
time_value = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op);
|
|
||||||
} else {
|
|
||||||
time_value = *(uint32_t *)(dv.value_p);
|
|
||||||
}
|
}
|
||||||
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
|
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
|
||||||
char time_s[60];
|
char time_s[60];
|
||||||
|
|||||||
@@ -29,7 +29,9 @@
|
|||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
#ifndef ARDUINO_LOLIN_S2_MINI
|
||||||
#include <esp_bt.h>
|
#include <esp_bt.h>
|
||||||
|
#endif
|
||||||
#include <ETH.h>
|
#include <ETH.h>
|
||||||
#include <uuid/syslog.h>
|
#include <uuid/syslog.h>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
#define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK
|
#define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK
|
||||||
|
|
||||||
#ifdef ARDUINO_LOLIN_C3_MINI
|
#if (defined(ARDUINO_LOLIN_C3_MINI)) || (defined(ARDUINO_LOLIN_S2_MINI))
|
||||||
#define EMSUART_NUM UART_NUM_1 // on C3 mini we're using UART1
|
#define EMSUART_NUM UART_NUM_1 // on C3 and S2 we're using UART1
|
||||||
#else
|
#else
|
||||||
#define EMSUART_NUM UART_NUM_2 // on the ESP32 we're using UART2
|
#define EMSUART_NUM UART_NUM_2 // on the ESP32 we're using UART2
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user