mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 00:39:50 +03:00
Merge branch 'dev11' into dev
This commit is contained in:
@@ -301,7 +301,8 @@ void AnalogSensor::loop() {
|
||||
}
|
||||
|
||||
// update analog information name and offset
|
||||
bool AnalogSensor::update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type) {
|
||||
// a type of -1 is used to delete the sensor
|
||||
bool AnalogSensor::update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted) {
|
||||
boolean found_sensor = false; // see if we can find the sensor in our customization list
|
||||
|
||||
EMSESP::webCustomizationService.update(
|
||||
@@ -313,7 +314,7 @@ bool AnalogSensor::update(uint8_t gpio, const std::string & name, double offset,
|
||||
if (AnalogCustomization.gpio == gpio) {
|
||||
found_sensor = true; // found the record
|
||||
// see if it's marked for deletion
|
||||
if (type == AnalogType::MARK_DELETED) {
|
||||
if (deleted) {
|
||||
LOG_DEBUG("Removing analog sensor GPIO %02d", gpio);
|
||||
settings.analogCustomizations.remove(AnalogCustomization);
|
||||
} else {
|
||||
|
||||
@@ -112,8 +112,7 @@ class AnalogSensor {
|
||||
~AnalogSensor() = default;
|
||||
|
||||
enum AnalogType : int8_t {
|
||||
MARK_DELETED = -1, // mark for deletion
|
||||
NOTUSED, // 0 - disabled
|
||||
NOTUSED, // 0 - disabled
|
||||
DIGITAL_IN,
|
||||
COUNTER,
|
||||
ADC,
|
||||
@@ -157,7 +156,7 @@ class AnalogSensor {
|
||||
return sensors_.size();
|
||||
}
|
||||
|
||||
bool update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type);
|
||||
bool update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted = false);
|
||||
bool get_value_info(JsonObject & output, const char * cmd, const int8_t id) const;
|
||||
|
||||
#if defined(EMSESP_TEST)
|
||||
|
||||
@@ -380,7 +380,7 @@ void Command::add(const uint8_t device_type, const uint8_t device_id, const char
|
||||
}
|
||||
|
||||
// add a command with no json output
|
||||
// system/dallas/analog devices uses device_id 0
|
||||
// system/temperature/analog devices uses device_id 0
|
||||
void Command::add(const uint8_t device_type, const char * cmd, const cmd_function_p cb, const char * const * description, uint8_t flags) {
|
||||
add(device_type, 0, cmd, cb, description, flags);
|
||||
}
|
||||
@@ -543,8 +543,8 @@ bool Command::device_has_commands(const uint8_t device_type) {
|
||||
return (EMSESP::webEntityService.count_entities() != 0);
|
||||
}
|
||||
|
||||
if (device_type == EMSdevice::DeviceType::DALLASSENSOR) {
|
||||
return (EMSESP::dallassensor_.have_sensors());
|
||||
if (device_type == EMSdevice::DeviceType::TEMPERATURESENSOR) {
|
||||
return (EMSESP::temperaturesensor_.have_sensors());
|
||||
}
|
||||
|
||||
if (device_type == EMSdevice::DeviceType::ANALOGSENSOR) {
|
||||
@@ -572,8 +572,8 @@ void Command::show_devices(uuid::console::Shell & shell) {
|
||||
if (EMSESP::webSchedulerService.has_commands()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
|
||||
}
|
||||
if (EMSESP::dallassensor_.have_sensors()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR));
|
||||
if (EMSESP::temperaturesensor_.have_sensors()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
|
||||
}
|
||||
if (EMSESP::analogsensor_.have_sensors()) {
|
||||
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR));
|
||||
@@ -616,12 +616,12 @@ void Command::show_all(uuid::console::Shell & shell) {
|
||||
}
|
||||
|
||||
// show sensors
|
||||
if (EMSESP::dallassensor_.have_sensors()) {
|
||||
if (EMSESP::temperaturesensor_.have_sensors()) {
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
shell.print(COLOR_YELLOW);
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR));
|
||||
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
|
||||
shell.print(COLOR_RESET);
|
||||
show(shell, EMSdevice::DeviceType::DALLASSENSOR, true);
|
||||
show(shell, EMSdevice::DeviceType::TEMPERATURESENSOR, true);
|
||||
}
|
||||
if (EMSESP::analogsensor_.have_sensors()) {
|
||||
shell.print(COLOR_BOLD_ON);
|
||||
|
||||
@@ -107,7 +107,7 @@ class Command {
|
||||
const char * const * description,
|
||||
uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
||||
|
||||
// same for system/dallas/analog devices
|
||||
// same for system/temperature/analog devices
|
||||
static void add(const uint8_t device_type,
|
||||
const char * cmd,
|
||||
const cmd_function_p cb,
|
||||
|
||||
@@ -569,7 +569,7 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
|
||||
if (current_arguments.size() == 0) {
|
||||
std::vector<std::string> devices_list;
|
||||
devices_list.emplace_back(EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM));
|
||||
devices_list.emplace_back(EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::DALLASSENSOR));
|
||||
devices_list.emplace_back(EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
|
||||
devices_list.emplace_back(EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR));
|
||||
for (const auto & device_class : EMSFactory::device_handlers()) {
|
||||
if (Command::device_has_commands(device_class.first)) {
|
||||
@@ -619,12 +619,12 @@ void EMSESPShell::stopped() {
|
||||
// show welcome banner
|
||||
void EMSESPShell::display_banner() {
|
||||
println();
|
||||
printfln("┌──────────────────────────────────────┐");
|
||||
printfln("│ %sEMS-ESP version %-12s%s │", COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF);
|
||||
printfln("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │", COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ │");
|
||||
printfln("│ type %shelp%s to show available commands │", COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("└──────────────────────────────────────┘");
|
||||
printfln("┌───────────────────────────────────────┐");
|
||||
printfln("│ %sEMS-ESP version %-12s%s │", COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_BOLD_OFF);
|
||||
printfln("│ %s%shttps://github.com/emsesp/EMS-ESP32%s │", COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("│ │");
|
||||
printfln("│ type %shelp%s to show available commands │", COLOR_UNDERLINE, COLOR_RESET);
|
||||
printfln("└───────────────────────────────────────┘");
|
||||
println();
|
||||
|
||||
// set console name
|
||||
|
||||
@@ -833,7 +833,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
|
||||
// Check if hot tap water or heating is active
|
||||
// Values will always be posted first time as heatingActive_ and tapwaterActive_ will have values EMS_VALUE_BOOL_NOTSET
|
||||
void Boiler::check_active(const bool force) {
|
||||
void Boiler::check_active() {
|
||||
if (!Helpers::hasValue(boilerState_)) {
|
||||
return;
|
||||
}
|
||||
@@ -844,7 +844,7 @@ void Boiler::check_active(const bool force) {
|
||||
// check if heating is active, bits 2 and 4 must be set
|
||||
b = ((boilerState_ & 0x09) == 0x09);
|
||||
val = b ? EMS_VALUE_BOOL_ON : EMS_VALUE_BOOL_OFF;
|
||||
if (heatingActive_ != val || force) {
|
||||
if (heatingActive_ != val) {
|
||||
heatingActive_ = val;
|
||||
char s[12];
|
||||
Mqtt::queue_publish(F_(heating_active), Helpers::render_boolean(s, b));
|
||||
@@ -868,7 +868,7 @@ void Boiler::check_active(const bool force) {
|
||||
}
|
||||
|
||||
val = b ? EMS_VALUE_BOOL_ON : EMS_VALUE_BOOL_OFF;
|
||||
if (tapwaterActive_ != val || force) {
|
||||
if (tapwaterActive_ != val) {
|
||||
tapwaterActive_ = val;
|
||||
char s[12];
|
||||
Mqtt::queue_publish(F_(tapwater_active), Helpers::render_boolean(s, b));
|
||||
|
||||
@@ -35,7 +35,7 @@ class Boiler : public EMSdevice {
|
||||
return (flags() & 0x0F);
|
||||
}
|
||||
|
||||
void check_active(const bool force = false);
|
||||
void check_active();
|
||||
|
||||
uint8_t boilerState_ = EMS_VALUE_UINT_NOTSET; // Boiler state flag - FOR INTERNAL USE
|
||||
|
||||
|
||||
@@ -119,8 +119,8 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
||||
return F_(connect);
|
||||
case DeviceType::MIXER:
|
||||
return F_(mixer);
|
||||
case DeviceType::DALLASSENSOR:
|
||||
return F_(dallassensor);
|
||||
case DeviceType::TEMPERATURESENSOR:
|
||||
return F_(temperaturesensor);
|
||||
case DeviceType::ANALOGSENSOR:
|
||||
return F_(analogsensor);
|
||||
case DeviceType::CONTROLLER:
|
||||
@@ -145,7 +145,7 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) {
|
||||
}
|
||||
|
||||
// returns the translated name of a specific EMS device
|
||||
// excludes dallassensor, analogsensor and system
|
||||
// excludes temperaturesensor, analogsensor and system
|
||||
const char * EMSdevice::device_type_2_device_name_translated() {
|
||||
switch (device_type_) {
|
||||
case DeviceType::BOILER:
|
||||
@@ -214,8 +214,8 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) {
|
||||
if (!strcmp(lowtopic, F_(mixer))) {
|
||||
return DeviceType::MIXER;
|
||||
}
|
||||
if (!strcmp(lowtopic, F_(dallassensor))) {
|
||||
return DeviceType::DALLASSENSOR;
|
||||
if (!strcmp(lowtopic, F_(temperaturesensor))) {
|
||||
return DeviceType::TEMPERATURESENSOR;
|
||||
}
|
||||
if (!strcmp(lowtopic, F_(analogsensor))) {
|
||||
return DeviceType::ANALOGSENSOR;
|
||||
@@ -520,7 +520,7 @@ void EMSdevice::add_device_value(uint8_t tag, // to b
|
||||
// get fullname, getting translation if it exists
|
||||
const char * const * fullname;
|
||||
if (Helpers::count_items(name) == 1) {
|
||||
fullname = nullptr; // no translations available, use empty
|
||||
fullname = nullptr; // no translations available, use empty
|
||||
} else {
|
||||
fullname = &name[1]; // translations start at index 1
|
||||
}
|
||||
@@ -845,7 +845,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
||||
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value
|
||||
uint8_t fahrenheit = 0;
|
||||
|
||||
// handle Booleans (true, false), use strings, no native true/false)
|
||||
// handle Booleans (true, false), output as strings according to the user settings
|
||||
if (dv.type == DeviceValueType::BOOL) {
|
||||
auto value_b = (bool)*(uint8_t *)(dv.value_p);
|
||||
char s[12];
|
||||
@@ -929,20 +929,19 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
||||
}
|
||||
}
|
||||
// handle INTs
|
||||
// add steps to numeric values with numeric_operator
|
||||
// add min and max values and steps, as integer values
|
||||
else {
|
||||
char s[10];
|
||||
if (dv.numeric_operator > 0) {
|
||||
obj["s"] = Helpers::render_value(s, (float)1 / dv.numeric_operator, 1);
|
||||
obj["s"] = (float)1 / dv.numeric_operator;
|
||||
} else if (dv.numeric_operator < 0) {
|
||||
obj["s"] = Helpers::render_value(s, (float)(-1) * dv.numeric_operator, 0);
|
||||
obj["s"] = (float)(-1) * dv.numeric_operator;
|
||||
}
|
||||
|
||||
int16_t dv_set_min;
|
||||
uint16_t dv_set_max;
|
||||
if (dv.get_min_max(dv_set_min, dv_set_max)) {
|
||||
obj["m"] = Helpers::render_value(s, dv_set_min, 0);
|
||||
obj["x"] = Helpers::render_value(s, dv_set_max, 0);
|
||||
obj["m"] = dv_set_min;
|
||||
obj["x"] = dv_set_max;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1035,9 +1034,8 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
||||
int16_t dv_set_min;
|
||||
uint16_t dv_set_max;
|
||||
if (dv.get_min_max(dv_set_min, dv_set_max)) {
|
||||
char s[10];
|
||||
obj["mi"] = Helpers::render_value(s, dv_set_min, 0, fahrenheit);
|
||||
obj["ma"] = Helpers::render_value(s, dv_set_max, 0, fahrenheit);
|
||||
obj["mi"] = dv_set_min;
|
||||
obj["ma"] = dv_set_max;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1312,7 +1310,7 @@ void EMSdevice::dump_value_info() {
|
||||
if (dv.type == DeviceValueType::BOOL) {
|
||||
snprintf(entityid, sizeof(entityid), "binary_sensor.%s", entity_with_tag); // binary sensor (for booleans)
|
||||
} else {
|
||||
snprintf(entityid, sizeof(entityid), "sensor.%s", entity_with_tag); // normal HA sensor
|
||||
snprintf(entityid, sizeof(entityid), "sensor.%s", entity_with_tag); // normal HA sensor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -319,9 +319,9 @@ class EMSdevice {
|
||||
};
|
||||
|
||||
enum DeviceType : uint8_t {
|
||||
SYSTEM = 0, // this is us (EMS-ESP)
|
||||
DALLASSENSOR, // for internal dallas sensors
|
||||
ANALOGSENSOR, // for internal analog sensors
|
||||
SYSTEM = 0, // this is us (EMS-ESP)
|
||||
TEMPERATURESENSOR, // for internal temperature sensors
|
||||
ANALOGSENSOR, // for internal analog sensors
|
||||
SCHEDULER,
|
||||
BOILER,
|
||||
THERMOSTAT,
|
||||
|
||||
@@ -62,13 +62,13 @@ uuid::syslog::SyslogService System::syslog_;
|
||||
#endif
|
||||
|
||||
// The services
|
||||
RxService EMSESP::rxservice_; // incoming Telegram Rx handler
|
||||
TxService EMSESP::txservice_; // outgoing Telegram Tx handler
|
||||
Mqtt EMSESP::mqtt_; // mqtt handler
|
||||
System EMSESP::system_; // core system services
|
||||
DallasSensor EMSESP::dallassensor_; // Dallas sensors
|
||||
AnalogSensor EMSESP::analogsensor_; // Analog sensors
|
||||
Shower EMSESP::shower_; // Shower logic
|
||||
RxService EMSESP::rxservice_; // incoming Telegram Rx handler
|
||||
TxService EMSESP::txservice_; // outgoing Telegram Tx handler
|
||||
Mqtt EMSESP::mqtt_; // mqtt handler
|
||||
System EMSESP::system_; // core system services
|
||||
TemperatureSensor EMSESP::temperaturesensor_; // Temperature sensors
|
||||
AnalogSensor EMSESP::analogsensor_; // Analog sensors
|
||||
Shower EMSESP::shower_; // Shower logic
|
||||
|
||||
// static/common variables
|
||||
uint16_t EMSESP::watch_id_ = WATCH_ID_NONE; // for when log is TRACE. 0 means no trace set
|
||||
@@ -408,15 +408,15 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) {
|
||||
}
|
||||
}
|
||||
|
||||
// show Dallas temperature sensors and Analog sensors
|
||||
// show temperature sensors and Analog sensors
|
||||
void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
|
||||
if (dallassensor_.have_sensors()) {
|
||||
if (temperaturesensor_.have_sensors()) {
|
||||
shell.printfln("Temperature sensors:");
|
||||
char s[10];
|
||||
char s2[10];
|
||||
uint8_t fahrenheit = EMSESP::system_.fahrenheit() ? 2 : 0;
|
||||
|
||||
for (const auto & sensor : dallassensor_.sensors()) {
|
||||
for (const auto & sensor : temperaturesensor_.sensors()) {
|
||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||
shell.printfln(" %s: %s%s °%c%s (offset %s, ID: %s)",
|
||||
sensor.name().c_str(),
|
||||
@@ -481,7 +481,7 @@ void EMSESP::publish_all(bool force) {
|
||||
publish_other_values(); // switch and heat pump, ...
|
||||
webSchedulerService.publish();
|
||||
webEntityService.publish();
|
||||
publish_sensor_values(true); // includes dallas and analog sensors
|
||||
publish_sensor_values(true); // includes temperature and analog sensors
|
||||
system_.send_heartbeat();
|
||||
}
|
||||
}
|
||||
@@ -541,8 +541,8 @@ void EMSESP::reset_mqtt_ha() {
|
||||
emsdevice->ha_config_clear();
|
||||
}
|
||||
|
||||
// force the re-creating of the dallas and analog sensor topics (for HA)
|
||||
dallassensor_.reload();
|
||||
// force the re-creating of the temperature and analog sensor topics (for HA)
|
||||
temperaturesensor_.reload();
|
||||
analogsensor_.reload();
|
||||
}
|
||||
|
||||
@@ -606,11 +606,11 @@ void EMSESP::publish_other_values() {
|
||||
webEntityService.publish();
|
||||
}
|
||||
|
||||
// publish both the dallas and analog sensor values
|
||||
// publish both the temperature and analog sensor values
|
||||
void EMSESP::publish_sensor_values(const bool time, const bool force) {
|
||||
if (dallas_enabled()) {
|
||||
if (dallassensor_.updated_values() || time || force) {
|
||||
dallassensor_.publish_values(force);
|
||||
if (sensor_enabled()) {
|
||||
if (temperaturesensor_.updated_values() || time || force) {
|
||||
temperaturesensor_.publish_values(force);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
|
||||
Mqtt::queue_publish("response", doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
// builds json with the detail of each value, for a specific EMS device type or the dallas sensor
|
||||
// builds json with the detail of each value, for a specific EMS device type or the temperature sensor
|
||||
bool EMSESP::get_device_value_info(JsonObject & root, const char * cmd, const int8_t id, const uint8_t devicetype) {
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice->device_type() == devicetype) {
|
||||
@@ -654,9 +654,9 @@ bool EMSESP::get_device_value_info(JsonObject & root, const char * cmd, const in
|
||||
}
|
||||
}
|
||||
|
||||
// specific for the dallassensor
|
||||
if (devicetype == DeviceType::DALLASSENSOR) {
|
||||
return EMSESP::dallassensor_.get_value_info(root, cmd, id);
|
||||
// specific for the temperaturesensor
|
||||
if (devicetype == DeviceType::TEMPERATURESENSOR) {
|
||||
return EMSESP::temperaturesensor_.get_value_info(root, cmd, id);
|
||||
}
|
||||
|
||||
// analog sensor
|
||||
@@ -1489,10 +1489,10 @@ void EMSESP::start() {
|
||||
|
||||
LOG_INFO(("Starting EMS-ESP version %s (hostname: %s)"), EMSESP_APP_VERSION, system_.hostname().c_str()); // welcome message
|
||||
|
||||
shower_.start(); // initialize shower timer and shower alert
|
||||
dallassensor_.start(); // Dallas external sensors
|
||||
analogsensor_.start(); // Analog external sensors
|
||||
webLogService.start(); // apply settings to weblog service
|
||||
shower_.start(); // initialize shower timer and shower alert
|
||||
temperaturesensor_.start(); // Temperature external sensors
|
||||
analogsensor_.start(); // Analog external sensors
|
||||
webLogService.start(); // apply settings to weblog service
|
||||
|
||||
// Load our library of known devices into stack mem. Names are stored in Flash memory
|
||||
device_library_ = {
|
||||
@@ -1518,7 +1518,7 @@ void EMSESP::loop() {
|
||||
webLogService.loop(); // log in Web UI
|
||||
rxservice_.loop(); // process any incoming Rx telegrams
|
||||
shower_.loop(); // check for shower on/off
|
||||
dallassensor_.loop(); // read dallas sensor temperatures
|
||||
temperaturesensor_.loop(); // read sensor temperatures
|
||||
analogsensor_.loop(); // read analog sensor values
|
||||
publish_all_loop(); // with HA messages in parts to avoid flooding the mqtt queue
|
||||
mqtt_.loop(); // sends out anything in the MQTT queue
|
||||
|
||||
20
src/emsesp.h
20
src/emsesp.h
@@ -54,7 +54,7 @@
|
||||
#include "telegram.h"
|
||||
#include "mqtt.h"
|
||||
#include "system.h"
|
||||
#include "dallassensor.h"
|
||||
#include "temperaturesensor.h"
|
||||
#include "analogsensor.h"
|
||||
#include "console.h"
|
||||
#include "console_stream.h"
|
||||
@@ -148,8 +148,8 @@ class EMSESP {
|
||||
|
||||
static void incoming_telegram(uint8_t * data, const uint8_t length);
|
||||
|
||||
static bool dallas_enabled() {
|
||||
return (dallassensor_.dallas_enabled());
|
||||
static bool sensor_enabled() {
|
||||
return (temperaturesensor_.sensor_enabled());
|
||||
}
|
||||
|
||||
static bool analog_enabled() {
|
||||
@@ -214,13 +214,13 @@ class EMSESP {
|
||||
static std::vector<std::unique_ptr<EMSdevice>> emsdevices;
|
||||
|
||||
// services
|
||||
static Mqtt mqtt_;
|
||||
static System system_;
|
||||
static DallasSensor dallassensor_;
|
||||
static AnalogSensor analogsensor_;
|
||||
static Shower shower_;
|
||||
static RxService rxservice_;
|
||||
static TxService txservice_;
|
||||
static Mqtt mqtt_;
|
||||
static System system_;
|
||||
static TemperatureSensor temperaturesensor_;
|
||||
static AnalogSensor analogsensor_;
|
||||
static Shower shower_;
|
||||
static RxService rxservice_;
|
||||
static TxService txservice_;
|
||||
|
||||
// web controllers
|
||||
static ESP8266React esp8266React;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "system.h"
|
||||
#include "mqtt.h"
|
||||
#include "dallassensor.h"
|
||||
#include "temperaturesensor.h"
|
||||
#include "version.h"
|
||||
#include "default_settings.h"
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
namespace emsesp {
|
||||
class EMSESP {
|
||||
public:
|
||||
static Mqtt mqtt_;
|
||||
static System system_;
|
||||
static DallasSensor dallassensor_;
|
||||
static Mqtt mqtt_;
|
||||
static System system_;
|
||||
static TemperatureSensor temperaturesensor_;
|
||||
|
||||
static uuid::log::Logger logger();
|
||||
static ESP8266React esp8266React;
|
||||
|
||||
@@ -93,7 +93,7 @@ MAKE_WORD(connect)
|
||||
MAKE_WORD(heatpump)
|
||||
MAKE_WORD(generic)
|
||||
MAKE_WORD(analogsensor)
|
||||
MAKE_WORD(dallassensor)
|
||||
MAKE_WORD(temperaturesensor)
|
||||
MAKE_WORD(alert)
|
||||
MAKE_WORD(pump)
|
||||
MAKE_WORD(heatsource)
|
||||
@@ -199,13 +199,13 @@ MAKE_NOTRANSLATION(L3, "L3")
|
||||
MAKE_NOTRANSLATION(L4, "L4")
|
||||
|
||||
// templates - this are not translated and will be saved under options_single
|
||||
MAKE_NOTRANSLATION(tpl_datetime, "Format: < NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >")
|
||||
MAKE_NOTRANSLATION(tpl_switchtime, "Format: <nn> [ not_set | day hh:mm on|off ]")
|
||||
MAKE_NOTRANSLATION(tpl_switchtime1, "Format: <nn> [ not_set | day hh:mm Tn ]")
|
||||
MAKE_NOTRANSLATION(tpl_holidays, "Format: < dd.mm.yyyy-dd.mm.yyyy >")
|
||||
MAKE_NOTRANSLATION(tpl_date, "Format: < dd.mm.yyyy >")
|
||||
MAKE_NOTRANSLATION(tpl_input, "Format: <inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv><prot><press><pump%>]")
|
||||
MAKE_NOTRANSLATION(tpl_input4, "Format: <inv>[<comp><aux><cool><heat><dhw><pv><prot><press><pump%>]")
|
||||
MAKE_NOTRANSLATION(tpl_datetime, "< NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >")
|
||||
MAKE_NOTRANSLATION(tpl_switchtime, "<nn> [ not_set | day hh:mm on|off ]")
|
||||
MAKE_NOTRANSLATION(tpl_switchtime1, "<nn> [ not_set | day hh:mm Tn ]")
|
||||
MAKE_NOTRANSLATION(tpl_holidays, "< dd.mm.yyyy-dd.mm.yyyy >")
|
||||
MAKE_NOTRANSLATION(tpl_date, "< dd.mm.yyyy >")
|
||||
MAKE_NOTRANSLATION(tpl_input, "<inv>[<evu1><evu2><evu3><comp><aux><cool><heat><dhw><pv>]")
|
||||
MAKE_NOTRANSLATION(tpl_input4, "<inv>[<comp><aux><cool><heat><dhw><pv>]")
|
||||
|
||||
#if defined(EMSESP_TEST)
|
||||
MAKE_NOTRANSLATION(test_cmd, "run a test")
|
||||
|
||||
@@ -49,7 +49,8 @@ MAKE_WORD_TRANSLATION(pump_device, "Pump Module", "Pumpenmodul", "Pump Module",
|
||||
MAKE_WORD_TRANSLATION(heatsource_device, "Heatsource", "Heizquelle", "Heatsource", "Värmekälla", "Źródło ciepła", "Varmekilde", "", "Isı Kaynağı") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(sensors_device, "Sensors", "Sensoren", "Sensoren", "Sensorer", "Czujniki", "Sensorer", "Capteurs", "Sensör Cihazı")
|
||||
MAKE_WORD_TRANSLATION(unknown_device, "Unknown", "Unbekannt", "Onbekend", "Okänt", "Nieznane urządzenie", "Ukjent", "Inconnu", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(custom_device, "User defined entities", "Nutzer deklarierte Entitäten", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(custom_device, "Custom", "", "", "", "Niestandardowe", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer deklarierte Entitäten", "", "", "Encje zdefiniowane przez użytkownika", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "", "", "", "", "", "") // TODO translate
|
||||
|
||||
// commands
|
||||
@@ -62,11 +63,11 @@ MAKE_WORD_TRANSLATION(setiovalue_cmd, "set io value", "Setze Wertevorgabe", "",
|
||||
MAKE_WORD_TRANSLATION(changeloglevel_cmd, "change log level", "Ändere Sysloglevel", "", "", "zmień poziom log-u", "endre loggnivå", "", "Kayıt seviyesini değiştir") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(fetch_cmd, "refresh all EMS values", "Lese alle EMS-Werte neu", "", "", "odśwież wszystkie wartości EMS", "oppfrisk alle EMS verdier", "", "Bütün EMS değerlerini yenile") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(restart_cmd, "restart EMS-ESP", "Neustart", "", "", "uruchom ponownie EMS-ESP", "restart EMS-ESP", "", "EMS-ESPyi yeniden başlat") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehende Telegramme", "", "", "obserwuj przyczodzące telegramy", "se innkommende telegrammer", "", "Gelen telegramları ") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehende Telegramme", "", "", "obserwuj przychodzące telegramy", "se innkommende telegrammer", "", "Gelen telegramları ") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "", "", "opublikuj wszystko na MQTT", "Publiser alt til MQTT", "", "Hepsini MQTTye gönder") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "", "", "aktywuj wybrany harmonogram", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "", "", "", "", "", "") // TODO translate
|
||||
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "", "", "wyślij własną wartość na EMS", "", "", "") // TODO translate
|
||||
|
||||
// tags
|
||||
MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS")
|
||||
|
||||
@@ -149,7 +149,7 @@ void Mqtt::loop() {
|
||||
EMSESP::system_.send_heartbeat(); // send heartbeat
|
||||
}
|
||||
|
||||
// dallas publish on change
|
||||
// temperature and analog sensor publish on change
|
||||
if (!publish_time_sensor_) {
|
||||
EMSESP::publish_sensor_values(false);
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ bool System::command_publish(const char * value, const int8_t id) {
|
||||
} else if (value_s == "other") {
|
||||
EMSESP::publish_other_values(); // switch and heat pump
|
||||
return true;
|
||||
} else if ((value_s == (F_(dallassensor))) || (value_s == (F_(analogsensor)))) {
|
||||
} else if ((value_s == (F_(temperaturesensor))) || (value_s == (F_(analogsensor)))) {
|
||||
EMSESP::publish_sensor_values(true);
|
||||
return true;
|
||||
}
|
||||
@@ -611,9 +611,9 @@ bool System::heartbeat_json(JsonObject & output) {
|
||||
output["apicalls"] = WebAPIService::api_count(); // + WebAPIService::api_fails();
|
||||
output["apifails"] = WebAPIService::api_fails();
|
||||
|
||||
if (EMSESP::dallas_enabled() || EMSESP::analog_enabled()) {
|
||||
output["sensorreads"] = EMSESP::dallassensor_.reads() + EMSESP::analogsensor_.reads();
|
||||
output["sensorfails"] = EMSESP::dallassensor_.fails() + EMSESP::analogsensor_.fails();
|
||||
if (EMSESP::sensor_enabled() || EMSESP::analog_enabled()) {
|
||||
output["sensorreads"] = EMSESP::temperaturesensor_.reads() + EMSESP::analogsensor_.reads();
|
||||
output["sensorfails"] = EMSESP::temperaturesensor_.fails() + EMSESP::analogsensor_.fails();
|
||||
}
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
@@ -1267,10 +1267,10 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
|
||||
|
||||
// Sensor Status
|
||||
node = output.createNestedObject("Sensor Info");
|
||||
if (EMSESP::dallas_enabled()) {
|
||||
node["temperature sensors"] = EMSESP::dallassensor_.no_sensors();
|
||||
node["temperature sensor reads"] = EMSESP::dallassensor_.reads();
|
||||
node["temperature sensor fails"] = EMSESP::dallassensor_.fails();
|
||||
if (EMSESP::sensor_enabled()) {
|
||||
node["temperature sensors"] = EMSESP::temperaturesensor_.no_sensors();
|
||||
node["temperature sensor reads"] = EMSESP::temperaturesensor_.reads();
|
||||
node["temperature sensor fails"] = EMSESP::temperaturesensor_.fails();
|
||||
}
|
||||
if (EMSESP::analog_enabled()) {
|
||||
node["analog sensors"] = EMSESP::analogsensor_.no_sensors();
|
||||
@@ -1418,7 +1418,7 @@ bool System::load_board_profile(std::vector<int8_t> & data, const std::string &
|
||||
} else if (board_profile == "LOLIN") {
|
||||
data = {2, 18, 17, 16, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin D32
|
||||
} else if (board_profile == "OLIMEX") {
|
||||
data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, -1, 0, 0}; // Olimex ESP32-EVB (uses U1TXD/U1RXD/BUTTON, no LED or Dallas)
|
||||
data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, -1, 0, 0}; // Olimex ESP32-EVB (uses U1TXD/U1RXD/BUTTON, no LED or Temperature sensor)
|
||||
} else if (board_profile == "OLIMEXPOE") {
|
||||
data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, 12, 0, 3}; // Olimex ESP32-POE
|
||||
} else if (board_profile == "C3MINI") {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
// code originally written by nomis - https://github.com/nomis
|
||||
|
||||
#include "dallassensor.h"
|
||||
#include "temperaturesensor.h"
|
||||
#include "emsesp.h"
|
||||
|
||||
#ifdef ESP32
|
||||
@@ -29,10 +29,10 @@
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
uuid::log::Logger DallasSensor::logger_{F_(dallassensor), uuid::log::Facility::DAEMON};
|
||||
uuid::log::Logger TemperatureSensor::logger_{F_(temperaturesensor), uuid::log::Facility::DAEMON};
|
||||
|
||||
// start the 1-wire
|
||||
void DallasSensor::start() {
|
||||
void TemperatureSensor::start() {
|
||||
reload();
|
||||
|
||||
if (!dallas_gpio_) {
|
||||
@@ -42,32 +42,32 @@ void DallasSensor::start() {
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
bus_.begin(dallas_gpio_);
|
||||
LOG_INFO("Starting Dallas sensor service");
|
||||
LOG_INFO("Starting Temperature sensor service");
|
||||
#endif
|
||||
|
||||
// Add API calls
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::DALLASSENSOR,
|
||||
EMSdevice::DeviceType::TEMPERATURESENSOR,
|
||||
F_(info),
|
||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_info(value, id, output); },
|
||||
FL_(info_cmd));
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::DALLASSENSOR,
|
||||
EMSdevice::DeviceType::TEMPERATURESENSOR,
|
||||
F_(values),
|
||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_info(value, 0, output); },
|
||||
nullptr,
|
||||
CommandFlag::HIDDEN); // this command is hidden
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::DALLASSENSOR,
|
||||
EMSdevice::DeviceType::TEMPERATURESENSOR,
|
||||
F_(commands),
|
||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
||||
FL_(commands_cmd));
|
||||
|
||||
Mqtt::subscribe(EMSdevice::DeviceType::DALLASSENSOR, "dallasssensor/#", nullptr); // use empty function callback
|
||||
Mqtt::subscribe(EMSdevice::DeviceType::TEMPERATURESENSOR, "temperaturesensor/#", nullptr); // use empty function callback
|
||||
}
|
||||
|
||||
// load settings
|
||||
void DallasSensor::reload() {
|
||||
void TemperatureSensor::reload() {
|
||||
// load the service settings
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||
dallas_gpio_ = settings.dallas_gpio;
|
||||
@@ -80,7 +80,7 @@ void DallasSensor::reload() {
|
||||
}
|
||||
}
|
||||
|
||||
void DallasSensor::loop() {
|
||||
void TemperatureSensor::loop() {
|
||||
if (!dallas_gpio_) {
|
||||
return; // dallas gpio is 0 (disabled)
|
||||
}
|
||||
@@ -119,13 +119,13 @@ void DallasSensor::loop() {
|
||||
} else if (state_ == State::READING) {
|
||||
if (temperature_convert_complete() && (time_now - last_activity_ > CONVERSION_MS)) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_DEBUG("Scanning for sensors");
|
||||
LOG_DEBUG("Scanning for temperature sensors");
|
||||
#endif
|
||||
bus_.reset_search();
|
||||
state_ = State::SCANNING;
|
||||
} else if (time_now - last_activity_ > READ_TIMEOUT_MS) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_WARNING("Dallas sensor read timeout");
|
||||
LOG_WARNING("Sensor read timeout");
|
||||
#endif
|
||||
state_ = State::IDLE;
|
||||
sensorfails_++;
|
||||
@@ -133,7 +133,7 @@ void DallasSensor::loop() {
|
||||
} else if (state_ == State::SCANNING) {
|
||||
if (time_now - last_activity_ > SCAN_TIMEOUT_MS) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_ERROR("Dallas sensor scan timeout");
|
||||
LOG_ERROR("Sensor scan timeout");
|
||||
#endif
|
||||
state_ = State::IDLE;
|
||||
sensorfails_++;
|
||||
@@ -188,12 +188,12 @@ void DallasSensor::loop() {
|
||||
|
||||
default:
|
||||
sensorfails_++;
|
||||
LOG_ERROR("Unknown dallas sensor %s", Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Unknown sensor %s", Sensor(addr).id().c_str());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
sensorfails_++;
|
||||
LOG_ERROR("Invalid dallas sensor %s", Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Invalid sensor %s", Sensor(addr).id().c_str());
|
||||
}
|
||||
} else {
|
||||
if (!parasite_) {
|
||||
@@ -211,7 +211,7 @@ void DallasSensor::loop() {
|
||||
scancnt_ = 0;
|
||||
} else if (scancnt_ == SCAN_START + 1) { // startup
|
||||
firstscan_ = sensors_.size();
|
||||
// LOG_DEBUG("Adding %d dallas sensor(s) from first scan", firstscan_);
|
||||
// LOG_DEBUG("Adding %d sensor(s) from first scan", firstscan_);
|
||||
} else if ((scancnt_ <= 0) && (firstscan_ != sensors_.size())) { // check 2 times for no change of sensor #
|
||||
scancnt_ = SCAN_START;
|
||||
sensors_.clear(); // restart scanning and clear to get correct numbering
|
||||
@@ -223,7 +223,7 @@ void DallasSensor::loop() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DallasSensor::temperature_convert_complete() {
|
||||
bool TemperatureSensor::temperature_convert_complete() {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (parasite_) {
|
||||
return true; // don't care, use the minimum time in loop
|
||||
@@ -234,7 +234,7 @@ bool DallasSensor::temperature_convert_complete() {
|
||||
#endif
|
||||
}
|
||||
|
||||
int16_t DallasSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (!bus_.reset()) {
|
||||
LOG_ERROR("Bus reset failed before reading scratchpad from %s", Sensor(addr).id().c_str());
|
||||
@@ -297,8 +297,8 @@ int16_t DallasSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// update dallas information name and offset
|
||||
bool DallasSensor::update(const std::string & id, const std::string & name, int16_t offset) {
|
||||
// update temperature sensor information name and offset
|
||||
bool TemperatureSensor::update(const std::string & id, const std::string & name, int16_t offset) {
|
||||
// find the sensor
|
||||
for (auto & sensor : sensors_) {
|
||||
if (sensor.id() == id) {
|
||||
@@ -346,7 +346,7 @@ bool DallasSensor::update(const std::string & id, const std::string & name, int1
|
||||
}
|
||||
|
||||
// check to see if values have been updated
|
||||
bool DallasSensor::updated_values() {
|
||||
bool TemperatureSensor::updated_values() {
|
||||
if (changed_) {
|
||||
changed_ = false;
|
||||
return true;
|
||||
@@ -355,13 +355,13 @@ bool DallasSensor::updated_values() {
|
||||
}
|
||||
|
||||
// list commands
|
||||
bool DallasSensor::command_commands(const char * value, const int8_t id, JsonObject & output) {
|
||||
return Command::list(EMSdevice::DeviceType::DALLASSENSOR, output);
|
||||
bool TemperatureSensor::command_commands(const char * value, const int8_t id, JsonObject & output) {
|
||||
return Command::list(EMSdevice::DeviceType::TEMPERATURESENSOR, output);
|
||||
}
|
||||
|
||||
// creates JSON doc from values
|
||||
// returns false if there are no sensors
|
||||
bool DallasSensor::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||
bool TemperatureSensor::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||
if (sensors_.empty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -387,7 +387,7 @@ bool DallasSensor::command_info(const char * value, const int8_t id, JsonObject
|
||||
}
|
||||
|
||||
// called from emsesp.cpp, similar to the emsdevice->get_value_info
|
||||
bool DallasSensor::get_value_info(JsonObject & output, const char * cmd, const int8_t id) {
|
||||
bool TemperatureSensor::get_value_info(JsonObject & output, const char * cmd, const int8_t id) {
|
||||
if (sensors_.empty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -438,13 +438,13 @@ bool DallasSensor::get_value_info(JsonObject & output, const char * cmd, const i
|
||||
}
|
||||
|
||||
// publish a single sensor to MQTT
|
||||
void DallasSensor::publish_sensor(const Sensor & sensor) {
|
||||
void TemperatureSensor::publish_sensor(const Sensor & sensor) {
|
||||
if (Mqtt::enabled() && Mqtt::publish_single()) {
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
if (Mqtt::publish_single2cmd()) {
|
||||
snprintf(topic, sizeof(topic), "%s/%s", (F_(dallassensor)), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s", (F_(temperaturesensor)), sensor.name().c_str());
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", (F_(dallassensor)), "_data", sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", (F_(temperaturesensor)), "_data", sensor.name().c_str());
|
||||
}
|
||||
char payload[10];
|
||||
Mqtt::queue_publish(topic, Helpers::render_value(payload, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||
@@ -452,7 +452,7 @@ void DallasSensor::publish_sensor(const Sensor & sensor) {
|
||||
}
|
||||
|
||||
// send empty config topic to remove the entry from HA
|
||||
void DallasSensor::remove_ha_topic(const std::string & id) {
|
||||
void TemperatureSensor::remove_ha_topic(const std::string & id) {
|
||||
if (!Mqtt::ha_enabled()) {
|
||||
return;
|
||||
}
|
||||
@@ -461,12 +461,12 @@ void DallasSensor::remove_ha_topic(const std::string & id) {
|
||||
std::string sensorid = id;
|
||||
std::replace(sensorid.begin(), sensorid.end(), '-', '_');
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/dallassensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str());
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/temperaturesensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str());
|
||||
Mqtt::queue_remove_topic(topic);
|
||||
}
|
||||
|
||||
// send all dallas sensor values as a JSON package to MQTT
|
||||
void DallasSensor::publish_values(const bool force) {
|
||||
// send all temperature sensor values as a JSON package to MQTT
|
||||
void TemperatureSensor::publish_values(const bool force) {
|
||||
if (!Mqtt::enabled()) {
|
||||
return;
|
||||
}
|
||||
@@ -499,7 +499,7 @@ void DallasSensor::publish_values(const bool force) {
|
||||
}
|
||||
|
||||
// create the HA MQTT config
|
||||
// to e.g. homeassistant/sensor/ems-esp/dallassensor_28-233D-9497-0C03/config
|
||||
// to e.g. homeassistant/sensor/ems-esp/temperaturesensor_28-233D-9497-0C03/config
|
||||
if (Mqtt::ha_enabled()) {
|
||||
if (!has_value && sensor.ha_registered) {
|
||||
remove_ha_topic(sensor.id());
|
||||
@@ -511,7 +511,7 @@ void DallasSensor::publish_values(const bool force) {
|
||||
config["dev_cla"] = "temperature";
|
||||
|
||||
char stat_t[50];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/dallassensor_data", Mqtt::base().c_str()); // use base path
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/temperaturesensor_data", Mqtt::base().c_str()); // use base path
|
||||
config["stat_t"] = stat_t;
|
||||
|
||||
config["unit_of_meas"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
|
||||
@@ -529,9 +529,9 @@ void DallasSensor::publish_values(const bool force) {
|
||||
|
||||
char uniq_s[70];
|
||||
if (Mqtt::entity_format() == Mqtt::entitiyFormat::MULTI_SHORT) {
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_dallassensor_%s", Mqtt::basename().c_str(), sensor.id().c_str());
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_temperaturesensor_%s", Mqtt::basename().c_str(), sensor.id().c_str());
|
||||
} else {
|
||||
snprintf(uniq_s, sizeof(uniq_s), "dallassensor_%s", sensor.id().c_str());
|
||||
snprintf(uniq_s, sizeof(uniq_s), "temperaturesensor_%s", sensor.id().c_str());
|
||||
}
|
||||
|
||||
config["obj_id"] = uniq_s;
|
||||
@@ -553,7 +553,7 @@ void DallasSensor::publish_values(const bool force) {
|
||||
std::string sensorid = sensor.id();
|
||||
std::replace(sensorid.begin(), sensorid.end(), '-', '_');
|
||||
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/dallassensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str());
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/temperaturesensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str());
|
||||
|
||||
Mqtt::queue_ha(topic, config.as<JsonObject>());
|
||||
|
||||
@@ -562,12 +562,12 @@ void DallasSensor::publish_values(const bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
Mqtt::queue_publish("dallassensor_data", doc.as<JsonObject>());
|
||||
Mqtt::queue_publish("temperaturesensor_data", doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
|
||||
// skip crc from id
|
||||
DallasSensor::Sensor::Sensor(const uint8_t addr[])
|
||||
TemperatureSensor::Sensor::Sensor(const uint8_t addr[])
|
||||
: internal_id_(((uint64_t)addr[0] << 48) | ((uint64_t)addr[1] << 40) | ((uint64_t)addr[2] << 32) | ((uint64_t)addr[3] << 24) | ((uint64_t)addr[4] << 16)
|
||||
| ((uint64_t)addr[5] << 8) | ((uint64_t)addr[6])) {
|
||||
// create ID string
|
||||
@@ -584,14 +584,14 @@ DallasSensor::Sensor::Sensor(const uint8_t addr[])
|
||||
offset_ = 0; // 0 degrees offset
|
||||
}
|
||||
|
||||
uint64_t DallasSensor::get_id(const uint8_t addr[]) {
|
||||
uint64_t TemperatureSensor::get_id(const uint8_t addr[]) {
|
||||
return (((uint64_t)addr[0] << 48) | ((uint64_t)addr[1] << 40) | ((uint64_t)addr[2] << 32) | ((uint64_t)addr[3] << 24) | ((uint64_t)addr[4] << 16)
|
||||
| ((uint64_t)addr[5] << 8) | ((uint64_t)addr[6]));
|
||||
}
|
||||
|
||||
// find the name from the customization service
|
||||
// if empty, return the ID as a string
|
||||
std::string DallasSensor::Sensor::name() const {
|
||||
std::string TemperatureSensor::Sensor::name() const {
|
||||
if (name_.empty()) {
|
||||
return id_;
|
||||
}
|
||||
@@ -600,12 +600,12 @@ std::string DallasSensor::Sensor::name() const {
|
||||
|
||||
// look up in customization service for a specific sensor
|
||||
// and set the name and offset from that entry if it exists
|
||||
bool DallasSensor::Sensor::apply_customization() {
|
||||
bool TemperatureSensor::Sensor::apply_customization() {
|
||||
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
|
||||
auto sensors = settings.sensorCustomizations;
|
||||
if (!sensors.empty()) {
|
||||
for (const auto & sensor : sensors) {
|
||||
LOG_DEBUG("Loading customization for dallas sensor %s", sensor.id.c_str());
|
||||
LOG_DEBUG("Loading customization for temperature sensor %s", sensor.id.c_str());
|
||||
if (id_ == sensor.id) {
|
||||
set_name(sensor.name);
|
||||
set_offset(sensor.offset);
|
||||
@@ -621,8 +621,8 @@ bool DallasSensor::Sensor::apply_customization() {
|
||||
|
||||
// hard coded tests
|
||||
#if defined(EMSESP_TEST)
|
||||
void DallasSensor::test() {
|
||||
// add 2 dallas sensors
|
||||
void TemperatureSensor::test() {
|
||||
// add 2 temperature sensors
|
||||
uint8_t addr[ADDR_LEN] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
sensors_.emplace_back(addr);
|
||||
sensors_.back().temperature_c = 123;
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
// code originally written by nomis - https://github.com/nomis
|
||||
|
||||
#ifndef EMSESP_DALLASSENSOR_H
|
||||
#define EMSESP_DALLASSENSOR_H
|
||||
#ifndef EMSESP_TEMPERATURESENSOR_H
|
||||
#define EMSESP_TEMPERATURESENSOR_H
|
||||
|
||||
#include "helpers.h"
|
||||
#include "mqtt.h"
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
class DallasSensor {
|
||||
class TemperatureSensor {
|
||||
public:
|
||||
class Sensor {
|
||||
public:
|
||||
@@ -73,8 +73,8 @@ class DallasSensor {
|
||||
int16_t offset_;
|
||||
};
|
||||
|
||||
DallasSensor() = default;
|
||||
~DallasSensor() = default;
|
||||
TemperatureSensor() = default;
|
||||
~TemperatureSensor() = default;
|
||||
|
||||
void start();
|
||||
void loop();
|
||||
@@ -97,7 +97,7 @@ class DallasSensor {
|
||||
return sensorfails_;
|
||||
}
|
||||
|
||||
bool dallas_enabled() {
|
||||
bool sensor_enabled() {
|
||||
return (dallas_gpio_ != 0);
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ class DallasSensor {
|
||||
static constexpr size_t SCRATCHPAD_CONFIG = 4;
|
||||
static constexpr size_t SCRATCHPAD_CNT_REM = 6;
|
||||
|
||||
// dallas chips
|
||||
// dallas chip types
|
||||
static constexpr uint8_t TYPE_DS18B20 = 0x28;
|
||||
static constexpr uint8_t TYPE_DS18S20 = 0x10;
|
||||
static constexpr uint8_t TYPE_DS1822 = 0x22;
|
||||
@@ -643,24 +643,24 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "dallas") {
|
||||
shell.printfln("Testing adding Dallas sensor");
|
||||
emsesp::EMSESP::dallassensor_.test();
|
||||
if (command == "temperature") {
|
||||
shell.printfln("Testing adding Temperature sensor");
|
||||
emsesp::EMSESP::temperaturesensor_.test();
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (command == "dallas_full") {
|
||||
shell.printfln("Testing adding and changing Dallas sensor");
|
||||
if (command == "temperature_full") {
|
||||
shell.printfln("Testing adding and changing Temperature sensor");
|
||||
Mqtt::ha_enabled(true);
|
||||
Mqtt::nested_format(1);
|
||||
// Mqtt::nested_format(0);
|
||||
|
||||
emsesp::EMSESP::dallassensor_.test();
|
||||
emsesp::EMSESP::temperaturesensor_.test();
|
||||
shell.invoke_command("show");
|
||||
shell.invoke_command("call system publish");
|
||||
|
||||
// rename
|
||||
EMSESP::dallassensor_.update("01-0203-0405-0607", "testdallas", 2);
|
||||
EMSESP::temperaturesensor_.update("01-0203-0405-0607", "testtemperature", 2);
|
||||
shell.invoke_command("show");
|
||||
shell.invoke_command("call system publish");
|
||||
ok = true;
|
||||
@@ -923,10 +923,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
*/
|
||||
|
||||
/*
|
||||
requestX.url("/api/dallassensor/xxxx");
|
||||
requestX.url("/api/temperaturesensor/xxxx");
|
||||
EMSESP::webAPIService.webAPIService_get(&requestX);
|
||||
emsesp::EMSESP::logger().notice("****");
|
||||
requestX.url("/api/dallassensor/info");
|
||||
requestX.url("/api/temperaturesensor/info");
|
||||
EMSESP::webAPIService.webAPIService_get(&requestX);
|
||||
return;
|
||||
*/
|
||||
@@ -1091,15 +1091,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
||||
char data6[] = "{\"id\":2,\"devicevalue\":{\"v\":\"44\",\"u\":1,\"n\":\"hc2 selected room temperature\",\"c\":\"hc2/seltemp\"}";
|
||||
deserializeJson(doc, data6);
|
||||
json = doc.as<JsonVariant>();
|
||||
request.url("/rest/writeValue");
|
||||
EMSESP::webDataService.write_value(&request, json);
|
||||
request.url("/rest/writeDeviceValue");
|
||||
EMSESP::webDataService.write_device_value(&request, json);
|
||||
|
||||
// write value from web - testing hc9/seltemp - should fail!
|
||||
char data7[] = "{\"id\":2,\"devicevalue\":{\"v\":\"55\",\"u\":1,\"n\":\"hc2 selected room temperature\",\"c\":\"hc9/seltemp\"}";
|
||||
deserializeJson(doc, data7);
|
||||
json = doc.as<JsonVariant>();
|
||||
request.url("/rest/writeValue");
|
||||
EMSESP::webDataService.write_value(&request, json);
|
||||
request.url("/rest/writeDeviceValue");
|
||||
EMSESP::webDataService.write_device_value(&request, json);
|
||||
|
||||
// emsesp::EMSESP::logger().notice("*");
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace emsesp {
|
||||
// #define EMSESP_DEBUG_DEFAULT "dv"
|
||||
// #define EMSESP_DEBUG_DEFAULT "lastcode"
|
||||
// #define EMSESP_DEBUG_DEFAULT "2thermostats"
|
||||
// #define EMSESP_DEBUG_DEFAULT "dallas"
|
||||
// #define EMSESP_DEBUG_DEFAULT "temperature"
|
||||
// #define EMSESP_DEBUG_DEFAULT "analog"
|
||||
// #define EMSESP_DEBUG_DEFAULT "api_values"
|
||||
// #define EMSESP_DEBUG_DEFAULT "mqtt_post"
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.6.0-dev.9"
|
||||
#define EMSESP_APP_VERSION "3.6.0-dev.11"
|
||||
|
||||
@@ -57,17 +57,17 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
|
||||
|
||||
// this creates the customization file, saving it to the FS
|
||||
void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
||||
// Dallas Sensor customization
|
||||
JsonArray sensorsJson = root.createNestedArray("sensors");
|
||||
// Temperature Sensor customization
|
||||
JsonArray sensorsJson = root.createNestedArray("ts");
|
||||
for (const SensorCustomization & sensor : settings.sensorCustomizations) {
|
||||
JsonObject sensorJson = sensorsJson.createNestedObject();
|
||||
sensorJson["id"] = sensor.id; // is
|
||||
sensorJson["id"] = sensor.id; // ID of chip
|
||||
sensorJson["name"] = sensor.name; // n
|
||||
sensorJson["offset"] = sensor.offset; // o
|
||||
}
|
||||
|
||||
// Analog Sensor customization
|
||||
JsonArray analogJson = root.createNestedArray("analogs");
|
||||
JsonArray analogJson = root.createNestedArray("as");
|
||||
for (const AnalogCustomization & sensor : settings.analogCustomizations) {
|
||||
JsonObject sensorJson = analogJson.createNestedObject();
|
||||
sensorJson["gpio"] = sensor.gpio; // g
|
||||
@@ -98,7 +98,7 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
||||
StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & settings) {
|
||||
#ifdef EMSESP_STANDALONE
|
||||
// invoke some fake data for testing
|
||||
const char * json = "{\"sensors\":[],\"analogs\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom "
|
||||
const char * json = "{\"ts\":[],\"as\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom "
|
||||
"name for heating active\",\"08tapwateractive\"]}]}";
|
||||
|
||||
StaticJsonDocument<500> doc;
|
||||
@@ -111,10 +111,10 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
||||
Serial.println(COLOR_RESET);
|
||||
#endif
|
||||
|
||||
// Dallas Sensor customization
|
||||
// Temperature Sensor customization
|
||||
settings.sensorCustomizations.clear();
|
||||
if (root["sensors"].is<JsonArray>()) {
|
||||
for (const JsonObject sensorJson : root["sensors"].as<JsonArray>()) {
|
||||
if (root["ts"].is<JsonArray>()) {
|
||||
for (const JsonObject sensorJson : root["ts"].as<JsonArray>()) {
|
||||
// create each of the sensor, overwriting any previous settings
|
||||
auto sensor = SensorCustomization();
|
||||
sensor.id = sensorJson["id"].as<std::string>();
|
||||
@@ -126,8 +126,8 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
||||
|
||||
// Analog Sensor customization
|
||||
settings.analogCustomizations.clear();
|
||||
if (root["analogs"].is<JsonArray>()) {
|
||||
for (const JsonObject analogJson : root["analogs"].as<JsonArray>()) {
|
||||
if (root["as"].is<JsonArray>()) {
|
||||
for (const JsonObject analogJson : root["as"].as<JsonArray>()) {
|
||||
// create each of the sensor, overwriting any previous settings
|
||||
auto sensor = AnalogCustomization();
|
||||
sensor.gpio = analogJson["gpio"];
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
// Customization for dallas sensor
|
||||
// Customization for temperature sensor
|
||||
class SensorCustomization {
|
||||
public:
|
||||
std::string id;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2023 Paul Derbyshire
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -25,12 +25,13 @@ using namespace std::placeholders; // for `_1` etc
|
||||
WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securityManager)
|
||||
: _device_data_handler(DEVICE_DATA_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED))
|
||||
, _write_value_handler(WRITE_VALUE_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_value, this, _1, _2), AuthenticationPredicates::IS_ADMIN))
|
||||
, _write_sensor_handler(WRITE_SENSOR_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_sensor, this, _1, _2), AuthenticationPredicates::IS_ADMIN))
|
||||
, _write_analog_handler(WRITE_ANALOG_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_analog, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) {
|
||||
, _write_value_handler(WRITE_DEVICE_VALUE_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_device_value, this, _1, _2), AuthenticationPredicates::IS_ADMIN))
|
||||
, _write_temperature_handler(WRITE_TEMPERATURE_SENSOR_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_temperature_sensor, this, _1, _2),
|
||||
AuthenticationPredicates::IS_ADMIN))
|
||||
, _write_analog_handler(WRITE_ANALOG_SENSOR_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_analog_sensor, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) {
|
||||
server->on(CORE_DATA_SERVICE_PATH,
|
||||
HTTP_GET,
|
||||
securityManager->wrapRequest(std::bind(&WebDataService::core_data, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||
@@ -51,9 +52,9 @@ WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securi
|
||||
_write_value_handler.setMaxContentLength(256);
|
||||
server->addHandler(&_write_value_handler);
|
||||
|
||||
_write_sensor_handler.setMethod(HTTP_POST);
|
||||
_write_sensor_handler.setMaxContentLength(256);
|
||||
server->addHandler(&_write_sensor_handler);
|
||||
_write_temperature_handler.setMethod(HTTP_POST);
|
||||
_write_temperature_handler.setMaxContentLength(256);
|
||||
server->addHandler(&_write_temperature_handler);
|
||||
|
||||
_write_analog_handler.setMethod(HTTP_POST);
|
||||
_write_analog_handler.setMaxContentLength(256);
|
||||
@@ -75,40 +76,37 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
|
||||
|
||||
// list is already sorted by device type
|
||||
JsonArray devices = root.createNestedArray("devices");
|
||||
char buffer[3];
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
// ignore controller
|
||||
if (emsdevice && (emsdevice->device_type() != EMSdevice::DeviceType::CONTROLLER || emsdevice->count_entities() > 0)) {
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["id"] = Helpers::smallitoa(buffer, emsdevice->unique_id()); // a unique id as a string
|
||||
obj["tn"] = emsdevice->device_type_2_device_name_translated(); // translated device type name
|
||||
obj["t"] = emsdevice->device_type(); // device type number
|
||||
obj["b"] = emsdevice->brand_to_char(); // brand
|
||||
obj["n"] = emsdevice->name(); // name
|
||||
obj["d"] = emsdevice->device_id(); // deviceid
|
||||
obj["p"] = emsdevice->product_id(); // productid
|
||||
obj["v"] = emsdevice->version(); // version
|
||||
obj["e"] = emsdevice->count_entities(); // number of entities (device values)
|
||||
obj["id"] = emsdevice->unique_id(); // a unique id
|
||||
obj["tn"] = emsdevice->device_type_2_device_name_translated(); // translated device type name
|
||||
obj["t"] = emsdevice->device_type(); // device type number
|
||||
obj["b"] = emsdevice->brand_to_char(); // brand
|
||||
obj["n"] = emsdevice->name(); // name
|
||||
obj["d"] = emsdevice->device_id(); // deviceid
|
||||
obj["p"] = emsdevice->product_id(); // productid
|
||||
obj["v"] = emsdevice->version(); // version
|
||||
obj["e"] = emsdevice->count_entities(); // number of entities (device values)
|
||||
}
|
||||
}
|
||||
|
||||
// add any custom entities
|
||||
if (EMSESP::webEntityService.count_entities()) {
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["id"] = "99"; // the last unique id as a string
|
||||
obj["tn"] = "Custom"; // translated device type name
|
||||
obj["t"] = EMSdevice::DeviceType::CUSTOM; // device type number
|
||||
obj["b"] = 0; // brand
|
||||
obj["n"] = Helpers::translated_word(FL_(custom_device)); // name
|
||||
obj["d"] = 0; // deviceid
|
||||
obj["p"] = 0; // productid
|
||||
obj["v"] = 0; // version
|
||||
obj["e"] = EMSESP::webEntityService.count_entities(); // number of entities (device values)
|
||||
obj["id"] = 99; // the last unique id
|
||||
obj["tn"] = Helpers::translated_word(FL_(custom_device)); // translated device type name
|
||||
obj["t"] = EMSdevice::DeviceType::CUSTOM; // device type number
|
||||
obj["b"] = Helpers::translated_word(FL_(na)); // brand
|
||||
obj["n"] = Helpers::translated_word(FL_(custom_device_name)); // name
|
||||
obj["d"] = 0; // deviceid
|
||||
obj["p"] = 0; // productid
|
||||
obj["v"] = 0; // version
|
||||
obj["e"] = EMSESP::webEntityService.count_entities(); // number of entities (device values)
|
||||
}
|
||||
|
||||
// sensors stuff
|
||||
root["s_n"] = Helpers::translated_word(FL_(sensors_device));
|
||||
root["active_sensors"] = EMSESP::dallassensor_.no_sensors() + (EMSESP::analogsensor_.analog_enabled() ? EMSESP::analogsensor_.no_sensors() : 0);
|
||||
root["analog_enabled"] = EMSESP::analogsensor_.analog_enabled();
|
||||
root["connected"] = EMSESP::bus_status() != 2;
|
||||
root["connected"] = EMSESP::bus_status() != 2;
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@@ -116,15 +114,14 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
|
||||
|
||||
// sensor data - sends back to web
|
||||
// /sensorData endpoint
|
||||
// the "sensors" and "analogs" are arrays and must exist
|
||||
void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
||||
auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_XXLARGE);
|
||||
JsonObject root = response->getRoot();
|
||||
|
||||
// dallas sensors
|
||||
JsonArray sensors = root.createNestedArray("sensors");
|
||||
if (EMSESP::dallassensor_.have_sensors()) {
|
||||
for (const auto & sensor : EMSESP::dallassensor_.sensors()) {
|
||||
// temperature sensors
|
||||
JsonArray sensors = root.createNestedArray("ts");
|
||||
if (EMSESP::temperaturesensor_.have_sensors()) {
|
||||
for (const auto & sensor : EMSESP::temperaturesensor_.sensors()) {
|
||||
JsonObject obj = sensors.createNestedObject();
|
||||
obj["id"] = sensor.id(); // id as string
|
||||
obj["n"] = sensor.name(); // name
|
||||
@@ -145,32 +142,29 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
||||
}
|
||||
|
||||
// analog sensors
|
||||
JsonArray analogs = root.createNestedArray("analogs");
|
||||
JsonArray analogs = root.createNestedArray("as");
|
||||
if (EMSESP::analog_enabled() && EMSESP::analogsensor_.have_sensors()) {
|
||||
uint8_t count = 0;
|
||||
char buffer[3];
|
||||
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
||||
// don't send if it's marked for removal
|
||||
if (sensor.type() != AnalogSensor::AnalogType::MARK_DELETED) {
|
||||
count++;
|
||||
JsonObject obj = analogs.createNestedObject();
|
||||
obj["id"] = Helpers::smallitoa(buffer, count); // needed for sorting table
|
||||
obj["g"] = sensor.gpio();
|
||||
obj["n"] = sensor.name();
|
||||
obj["u"] = sensor.uom();
|
||||
obj["o"] = sensor.offset();
|
||||
obj["f"] = sensor.factor();
|
||||
obj["t"] = sensor.type();
|
||||
JsonObject obj = analogs.createNestedObject();
|
||||
obj["id"] = ++count; // needed for sorting table
|
||||
obj["g"] = sensor.gpio();
|
||||
obj["n"] = sensor.name();
|
||||
obj["u"] = sensor.uom();
|
||||
obj["o"] = sensor.offset();
|
||||
obj["f"] = sensor.factor();
|
||||
obj["t"] = sensor.type();
|
||||
|
||||
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) {
|
||||
obj["v"] = Helpers::transformNumFloat(sensor.value(), 0); // is optional and is a float
|
||||
} else {
|
||||
obj["v"] = 0; // must have a value for web sorting to work
|
||||
}
|
||||
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) {
|
||||
obj["v"] = Helpers::transformNumFloat(sensor.value(), 0); // is optional and is a float
|
||||
} else {
|
||||
obj["v"] = 0; // must have a value for web sorting to work
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root["analog_enabled"] = EMSESP::analogsensor_.analog_enabled();
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
}
|
||||
@@ -227,7 +221,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request, JsonVariant &
|
||||
|
||||
// takes a command and its data value from a specific EMS Device, from the Web
|
||||
// assumes the service has been checked for admin authentication
|
||||
void WebDataService::write_value(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject dv = json["devicevalue"];
|
||||
uint8_t unique_id = json["id"];
|
||||
@@ -314,9 +308,9 @@ void WebDataService::write_value(AsyncWebServerRequest * request, JsonVariant &
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
// takes a dallas sensor name and optional offset from the WebUI and update the customization settings
|
||||
// via the Dallas service
|
||||
void WebDataService::write_sensor(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
// takes a temperaturesensor name and optional offset from the WebUI and update the customization settings
|
||||
// via the temperaturesensor service
|
||||
void WebDataService::write_temperature_sensor(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
bool ok = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject sensor = json;
|
||||
@@ -330,7 +324,7 @@ void WebDataService::write_sensor(AsyncWebServerRequest * request, JsonVariant &
|
||||
if (EMSESP::system_.fahrenheit()) {
|
||||
offset10 = offset / 0.18;
|
||||
}
|
||||
ok = EMSESP::dallassensor_.update(id, name, offset10);
|
||||
ok = EMSESP::temperaturesensor_.update(id, name, offset10);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 204);
|
||||
@@ -338,18 +332,19 @@ void WebDataService::write_sensor(AsyncWebServerRequest * request, JsonVariant &
|
||||
}
|
||||
|
||||
// update the analog record, or create a new one
|
||||
void WebDataService::write_analog(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
void WebDataService::write_analog_sensor(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
bool ok = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject analog = json;
|
||||
|
||||
uint8_t gpio = analog["gpio"]; // this is the unique key, the GPIO
|
||||
std::string name = analog["name"];
|
||||
double factor = analog["factor"];
|
||||
double offset = analog["offset"];
|
||||
uint8_t uom = analog["uom"];
|
||||
int8_t type = analog["type"];
|
||||
ok = EMSESP::analogsensor_.update(gpio, name, offset, factor, uom, type);
|
||||
uint8_t gpio = analog["gpio"];
|
||||
std::string name = analog["name"];
|
||||
double factor = analog["factor"];
|
||||
double offset = analog["offset"];
|
||||
uint8_t uom = analog["uom"];
|
||||
int8_t type = analog["type"];
|
||||
bool deleted = analog["deleted"];
|
||||
ok = EMSESP::analogsensor_.update(gpio, name, offset, factor, uom, type, deleted);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 204);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2023 Paul Derbyshire
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -26,9 +26,9 @@
|
||||
#define SENSOR_DATA_SERVICE_PATH "/rest/sensorData"
|
||||
|
||||
// POST
|
||||
#define WRITE_VALUE_SERVICE_PATH "/rest/writeValue"
|
||||
#define WRITE_SENSOR_SERVICE_PATH "/rest/writeSensor"
|
||||
#define WRITE_ANALOG_SERVICE_PATH "/rest/writeAnalog"
|
||||
#define WRITE_DEVICE_VALUE_SERVICE_PATH "/rest/writeDeviceValue"
|
||||
#define WRITE_TEMPERATURE_SENSOR_SERVICE_PATH "/rest/writeTemperatureSensor"
|
||||
#define WRITE_ANALOG_SENSOR_SERVICE_PATH "/rest/writeAnalogSensor"
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
@@ -47,12 +47,12 @@ class WebDataService {
|
||||
|
||||
// POST
|
||||
void device_data(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_value(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_sensor(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_analog(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_device_value(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_temperature_sensor(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_analog_sensor(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void scan_devices(AsyncWebServerRequest * request);
|
||||
|
||||
AsyncCallbackJsonWebHandler _device_data_handler, _write_value_handler, _write_sensor_handler, _write_analog_handler;
|
||||
AsyncCallbackJsonWebHandler _device_data_handler, _write_value_handler, _write_temperature_handler, _write_analog_handler;
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2023 Paul Derbyshire
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -33,20 +33,22 @@ void WebEntityService::begin() {
|
||||
EMSESP::logger().info("Starting custom entity service");
|
||||
}
|
||||
|
||||
// this creates the scheduler file, saving it to the FS
|
||||
// and also calls when the Scheduler web page is refreshed
|
||||
// this creates the entity file, saving it to the FS
|
||||
// and also calls when the Entity web page is refreshed
|
||||
void WebEntity::read(WebEntity & webEntity, JsonObject & root) {
|
||||
JsonArray entity = root.createNestedArray("entity");
|
||||
JsonArray entity = root.createNestedArray("entities");
|
||||
uint8_t counter = 0;
|
||||
for (const EntityItem & entityItem : webEntity.entityItems) {
|
||||
JsonObject ei = entity.createNestedObject();
|
||||
ei["device_id"] = Helpers::hextoa(entityItem.device_id, false);
|
||||
ei["type_id"] = Helpers::hextoa(entityItem.type_id, false);
|
||||
ei["offset"] = entityItem.offset;
|
||||
ei["factor"] = entityItem.factor;
|
||||
ei["name"] = entityItem.name;
|
||||
ei["uom"] = entityItem.uom;
|
||||
ei["val_type"] = entityItem.valuetype;
|
||||
ei["write"] = entityItem.writeable;
|
||||
JsonObject ei = entity.createNestedObject();
|
||||
ei["id"] = counter++; // id is only used to render the table and must be unique
|
||||
ei["device_id"] = entityItem.device_id;
|
||||
ei["type_id"] = entityItem.type_id;
|
||||
ei["offset"] = entityItem.offset;
|
||||
ei["factor"] = entityItem.factor;
|
||||
ei["name"] = entityItem.name;
|
||||
ei["uom"] = entityItem.uom;
|
||||
ei["value_type"] = entityItem.value_type;
|
||||
ei["writeable"] = entityItem.writeable;
|
||||
EMSESP::webEntityService.render_value(ei, entityItem, true, true);
|
||||
}
|
||||
}
|
||||
@@ -59,33 +61,34 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) {
|
||||
}
|
||||
webEntity.entityItems.clear();
|
||||
|
||||
if (root["entity"].is<JsonArray>()) {
|
||||
for (const JsonObject ei : root["entity"].as<JsonArray>()) {
|
||||
auto entityItem = EntityItem();
|
||||
entityItem.device_id = Helpers::hextoint(ei["device_id"]);
|
||||
entityItem.type_id = Helpers::hextoint(ei["type_id"]);
|
||||
entityItem.offset = ei["offset"];
|
||||
entityItem.factor = ei["factor"];
|
||||
entityItem.name = ei["name"].as<std::string>();
|
||||
entityItem.uom = ei["uom"];
|
||||
entityItem.valuetype = ei["val_type"];
|
||||
entityItem.writeable = ei["write"];
|
||||
if (root["entities"].is<JsonArray>()) {
|
||||
for (const JsonObject ei : root["entities"].as<JsonArray>()) {
|
||||
auto entityItem = EntityItem();
|
||||
entityItem.device_id = ei["device_id"]; // send as numeric, will be converted to string in web
|
||||
entityItem.type_id = ei["type_id"];
|
||||
entityItem.offset = ei["offset"];
|
||||
entityItem.factor = ei["factor"];
|
||||
entityItem.name = ei["name"].as<std::string>();
|
||||
entityItem.uom = ei["uom"];
|
||||
entityItem.value_type = ei["value_type"];
|
||||
entityItem.writeable = ei["writeable"];
|
||||
|
||||
if (entityItem.valuetype == DeviceValueType::BOOL) {
|
||||
entityItem.val = EMS_VALUE_DEFAULT_BOOL;
|
||||
} else if (entityItem.valuetype == DeviceValueType::INT) {
|
||||
entityItem.val = EMS_VALUE_DEFAULT_INT;
|
||||
} else if (entityItem.valuetype == DeviceValueType::UINT) {
|
||||
entityItem.val = EMS_VALUE_DEFAULT_UINT;
|
||||
} else if (entityItem.valuetype == DeviceValueType::SHORT) {
|
||||
entityItem.val = EMS_VALUE_DEFAULT_SHORT;
|
||||
} else if (entityItem.valuetype == DeviceValueType::USHORT) {
|
||||
entityItem.val = EMS_VALUE_DEFAULT_USHORT;
|
||||
} else { // if (entityItem.valuetype == DeviceValueType::ULONG || entityItem.valuetype == DeviceValueType::TIME) {
|
||||
entityItem.val = EMS_VALUE_DEFAULT_ULONG;
|
||||
if (entityItem.value_type == DeviceValueType::BOOL) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_BOOL;
|
||||
} else if (entityItem.value_type == DeviceValueType::INT) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_INT;
|
||||
} else if (entityItem.value_type == DeviceValueType::UINT) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_UINT;
|
||||
} else if (entityItem.value_type == DeviceValueType::SHORT) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_SHORT;
|
||||
} else if (entityItem.value_type == DeviceValueType::USHORT) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_USHORT;
|
||||
} else { // if (entityItem.value_type == DeviceValueType::ULONG || entityItem.valuetype == DeviceValueType::TIME) {
|
||||
entityItem.value = EMS_VALUE_DEFAULT_ULONG;
|
||||
}
|
||||
|
||||
webEntity.entityItems.push_back(entityItem); // add to list
|
||||
|
||||
if (entityItem.writeable) {
|
||||
Command::add(
|
||||
EMSdevice::DeviceType::CUSTOM,
|
||||
@@ -106,7 +109,7 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
for (EntityItem & entityItem : *entityItems) {
|
||||
if (entityItem.name == name) {
|
||||
if (entityItem.valuetype == DeviceValueType::BOOL) {
|
||||
if (entityItem.value_type == DeviceValueType::BOOL) {
|
||||
bool v;
|
||||
if (!Helpers::value2bool(value, v)) {
|
||||
return false;
|
||||
@@ -118,9 +121,9 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na
|
||||
return false;
|
||||
}
|
||||
int v = f / entityItem.factor;
|
||||
if (entityItem.valuetype == DeviceValueType::UINT || entityItem.valuetype == DeviceValueType::INT) {
|
||||
if (entityItem.value_type == DeviceValueType::UINT || entityItem.value_type == DeviceValueType::INT) {
|
||||
EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v, 0);
|
||||
} else if (entityItem.valuetype == DeviceValueType::USHORT || entityItem.valuetype == DeviceValueType::SHORT) {
|
||||
} else if (entityItem.value_type == DeviceValueType::USHORT || entityItem.value_type == DeviceValueType::SHORT) {
|
||||
uint8_t v1[2] = {(uint8_t)(v >> 8), (uint8_t)(v & 0xFF)};
|
||||
EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v1, 2, 0);
|
||||
} else {
|
||||
@@ -128,6 +131,7 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na
|
||||
EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v1, 3, 0);
|
||||
}
|
||||
}
|
||||
|
||||
publish_single(entityItem);
|
||||
if (EMSESP::mqtt_.get_publish_onchange(0)) {
|
||||
publish();
|
||||
@@ -142,44 +146,44 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na
|
||||
void WebEntityService::render_value(JsonObject & output, EntityItem entity, const bool useVal, const bool web) {
|
||||
char payload[12];
|
||||
std::string name = useVal ? "value" : entity.name;
|
||||
switch (entity.valuetype) {
|
||||
switch (entity.value_type) {
|
||||
case DeviceValueType::BOOL:
|
||||
if ((uint8_t)entity.val != EMS_VALUE_BOOL_NOTSET) {
|
||||
if ((uint8_t)entity.value != EMS_VALUE_BOOL_NOTSET) {
|
||||
if (web) {
|
||||
output[name] = Helpers::render_boolean(payload, (uint8_t)entity.val, true);
|
||||
output[name] = Helpers::render_boolean(payload, (uint8_t)entity.value, true);
|
||||
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||
output[name] = (uint8_t)entity.val ? true : false;
|
||||
output[name] = (uint8_t)entity.value ? true : false;
|
||||
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
|
||||
output[name] = (uint8_t)entity.val ? 1 : 0;
|
||||
output[name] = (uint8_t)entity.value ? 1 : 0;
|
||||
} else {
|
||||
output[name] = Helpers::render_boolean(payload, (uint8_t)entity.val);
|
||||
output[name] = Helpers::render_boolean(payload, (uint8_t)entity.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::INT:
|
||||
if ((int8_t)entity.val != EMS_VALUE_INT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (int8_t)entity.val, 2));
|
||||
if ((int8_t)entity.value != EMS_VALUE_INT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (int8_t)entity.value, 2));
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::UINT:
|
||||
if ((uint8_t)entity.val != EMS_VALUE_UINT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (uint8_t)entity.val, 2));
|
||||
if ((uint8_t)entity.value != EMS_VALUE_UINT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (uint8_t)entity.value, 2));
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::SHORT:
|
||||
if ((int16_t)entity.val != EMS_VALUE_SHORT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (int16_t)entity.val, 2));
|
||||
if ((int16_t)entity.value != EMS_VALUE_SHORT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (int16_t)entity.value, 2));
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::USHORT:
|
||||
if ((uint16_t)entity.val != EMS_VALUE_USHORT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (uint16_t)entity.val, 2));
|
||||
if ((uint16_t)entity.value != EMS_VALUE_USHORT_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * (uint16_t)entity.value, 2));
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::ULONG:
|
||||
case DeviceValueType::TIME:
|
||||
if (entity.val != EMS_VALUE_ULONG_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * entity.val, 2));
|
||||
if (entity.value != EMS_VALUE_ULONG_NOTSET) {
|
||||
output[name] = serialized(Helpers::render_value(payload, entity.factor * entity.value, 2));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -334,6 +338,7 @@ uint8_t WebEntityService::count_entities() {
|
||||
if (entityItems->size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE);
|
||||
JsonObject output = doc.to<JsonObject>();
|
||||
uint8_t count = 0;
|
||||
@@ -347,6 +352,7 @@ uint8_t WebEntityService::count_entities() {
|
||||
// send to dashboard, msgpack don't like serialized, use number
|
||||
void WebEntityService::generate_value_web(JsonObject & output) {
|
||||
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
|
||||
|
||||
output["label"] = (std::string) "Custom Entities";
|
||||
JsonArray data = output.createNestedArray("data");
|
||||
uint8_t index = 0;
|
||||
@@ -357,39 +363,40 @@ void WebEntityService::generate_value_web(JsonObject & output) {
|
||||
if (entity.writeable) {
|
||||
obj["c"] = entity.name;
|
||||
}
|
||||
switch (entity.valuetype) {
|
||||
|
||||
switch (entity.value_type) {
|
||||
case DeviceValueType::BOOL: {
|
||||
char s[12];
|
||||
obj["v"] = Helpers::render_boolean(s, (uint8_t)entity.val, true);
|
||||
obj["v"] = Helpers::render_boolean(s, (uint8_t)entity.value, true);
|
||||
JsonArray l = obj.createNestedArray("l");
|
||||
l.add(Helpers::render_boolean(s, false, true));
|
||||
l.add(Helpers::render_boolean(s, true, true));
|
||||
break;
|
||||
}
|
||||
case DeviceValueType::INT:
|
||||
if ((int8_t)entity.val != EMS_VALUE_INT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (int8_t)entity.val, 0);
|
||||
if ((int8_t)entity.value != EMS_VALUE_INT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (int8_t)entity.value, 0);
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::UINT:
|
||||
if ((uint8_t)entity.val != EMS_VALUE_UINT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (uint8_t)entity.val, 0);
|
||||
if ((uint8_t)entity.value != EMS_VALUE_UINT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (uint8_t)entity.value, 0);
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::SHORT:
|
||||
if ((int16_t)entity.val != EMS_VALUE_SHORT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (int16_t)entity.val, 0);
|
||||
if ((int16_t)entity.value != EMS_VALUE_SHORT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (int16_t)entity.value, 0);
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::USHORT:
|
||||
if ((uint16_t)entity.val != EMS_VALUE_USHORT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (uint16_t)entity.val, 0);
|
||||
if ((uint16_t)entity.value != EMS_VALUE_USHORT_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * (uint16_t)entity.value, 0);
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::ULONG:
|
||||
case DeviceValueType::TIME:
|
||||
if (entity.val != EMS_VALUE_ULONG_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * entity.val, 0);
|
||||
if (entity.value != EMS_VALUE_ULONG_NOTSET) {
|
||||
obj["v"] = Helpers::transformNumFloat(entity.factor * entity.value, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -420,13 +427,13 @@ bool WebEntityService::get_value(std::shared_ptr<const Telegram> telegram) {
|
||||
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
|
||||
for (auto & entity : *entityItems) {
|
||||
if (telegram->type_id == entity.type_id && telegram->src == entity.device_id && telegram->offset <= entity.offset
|
||||
&& (telegram->offset + telegram->message_length) >= (entity.offset + len[entity.valuetype])) {
|
||||
uint32_t val = 0;
|
||||
for (uint8_t i = 0; i < len[entity.valuetype]; i++) {
|
||||
val = (val << 8) + telegram->message_data[i + entity.offset - telegram->offset];
|
||||
&& (telegram->offset + telegram->message_length) >= (entity.offset + len[entity.value_type])) {
|
||||
uint32_t value = 0;
|
||||
for (uint8_t i = 0; i < len[entity.value_type]; i++) {
|
||||
value = (value << 8) + telegram->message_data[i + entity.offset - telegram->offset];
|
||||
}
|
||||
if (val != entity.val) {
|
||||
entity.val = val;
|
||||
if (value != entity.value) {
|
||||
entity.value = value;
|
||||
if (Mqtt::publish_single()) {
|
||||
publish_single(entity);
|
||||
} else if (EMSESP::mqtt_.get_publish_onchange(0)) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2023 Paul Derbyshire
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -21,21 +21,22 @@
|
||||
#define WebEntityService_h
|
||||
|
||||
#define EMSESP_ENTITY_FILE "/config/emsespEntity.json"
|
||||
#define EMSESP_ENTITY_SERVICE_PATH "/rest/entity" // GET and POST
|
||||
#define EMSESP_ENTITY_SERVICE_PATH "/rest/entities" // GET and POST
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
class EntityItem {
|
||||
public:
|
||||
uint8_t id;
|
||||
uint8_t device_id;
|
||||
uint16_t type_id;
|
||||
uint8_t offset;
|
||||
int8_t valuetype;
|
||||
int8_t value_type;
|
||||
uint8_t uom;
|
||||
std::string name;
|
||||
double factor;
|
||||
bool writeable;
|
||||
uint32_t val;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
class WebEntity {
|
||||
@@ -66,7 +67,7 @@ class WebEntityService : public StatefulService<WebEntity> {
|
||||
HttpEndpoint<WebEntity> _httpEndpoint;
|
||||
FSPersistence<WebEntity> _fsPersistence;
|
||||
|
||||
std::list<EntityItem> * entityItems; // pointer to the list of schedule events
|
||||
std::list<EntityItem> * entityItems; // pointer to the list of entity items
|
||||
bool ha_registered_ = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* EMS-ESP - https://github.com/emsesp/EMS-ESP
|
||||
* Copyright 2020-2023 Paul Derbyshire
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -56,7 +56,7 @@ StateUpdateResult WebScheduler::update(JsonObject & root, WebScheduler & webSche
|
||||
#ifdef EMSESP_STANDALONE
|
||||
// invoke some fake data for testing
|
||||
const char * json =
|
||||
"{[{\"id\":\"01\",\"active\":true,\"flags\":31,\"time\": \"07:30\",\"cmd\": \"hc1/mode\",\"value\": \"day\",\"name\": \"turn on central heating\"}]}";
|
||||
"{[{\"id\":1,\"active\":true,\"flags\":31,\"time\": \"07:30\",\"cmd\": \"hc1/mode\",\"value\": \"day\",\"name\": \"turn on central heating\"}]}";
|
||||
StaticJsonDocument<500> doc;
|
||||
deserializeJson(doc, json);
|
||||
root = doc.as<JsonObject>();
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace emsesp {
|
||||
|
||||
class ScheduleItem {
|
||||
public:
|
||||
std::string id; // unqiue id
|
||||
boolean active;
|
||||
uint8_t flags;
|
||||
uint16_t elapsed_min; // total mins from 00:00
|
||||
|
||||
@@ -176,13 +176,13 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
||||
settings.pbutton_gpio = root["pbutton_gpio"] | default_pbutton_gpio;
|
||||
check_flag(prev, settings.pbutton_gpio, ChangeFlags::BUTTON);
|
||||
|
||||
// dallas
|
||||
// temperaturesensor
|
||||
prev = settings.dallas_gpio;
|
||||
settings.dallas_gpio = root["dallas_gpio"] | default_dallas_gpio;
|
||||
check_flag(prev, settings.dallas_gpio, ChangeFlags::DALLAS);
|
||||
check_flag(prev, settings.dallas_gpio, ChangeFlags::SENSOR);
|
||||
prev = settings.dallas_parasite;
|
||||
settings.dallas_parasite = root["dallas_parasite"] | EMSESP_DEFAULT_DALLAS_PARASITE;
|
||||
check_flag(prev, settings.dallas_parasite, ChangeFlags::DALLAS);
|
||||
check_flag(prev, settings.dallas_parasite, ChangeFlags::SENSOR);
|
||||
|
||||
// shower
|
||||
prev = settings.shower_timer;
|
||||
@@ -301,8 +301,8 @@ void WebSettingsService::onUpdate() {
|
||||
EMSESP::shower_.start();
|
||||
}
|
||||
|
||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::DALLAS)) {
|
||||
EMSESP::dallassensor_.start();
|
||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::SENSOR)) {
|
||||
EMSESP::temperaturesensor_.start();
|
||||
}
|
||||
|
||||
if (WebSettings::has_flags(WebSettings::ChangeFlags::UART)) {
|
||||
|
||||
@@ -79,7 +79,7 @@ class WebSettings {
|
||||
UART = (1 << 0), // 1
|
||||
SYSLOG = (1 << 1), // 2
|
||||
ADC = (1 << 2), // 4 - analog
|
||||
DALLAS = (1 << 3), // 8
|
||||
SENSOR = (1 << 3), // 8
|
||||
SHOWER = (1 << 4), // 16
|
||||
LED = (1 << 5), // 32
|
||||
BUTTON = (1 << 6), // 64
|
||||
|
||||
@@ -124,7 +124,7 @@ void WebStatusService::webStatusService(AsyncWebServerRequest * request) {
|
||||
root["tx_mode"] = EMSESP::txservice_.tx_mode();
|
||||
root["uptime"] = EMSbus::bus_uptime();
|
||||
root["num_devices"] = EMSESP::count_devices(); // excluding Controller
|
||||
root["num_sensors"] = EMSESP::dallassensor_.no_sensors();
|
||||
root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors();
|
||||
root["num_analogs"] = EMSESP::analogsensor_.no_sensors();
|
||||
|
||||
JsonArray statsJson = root.createNestedArray("stats");
|
||||
@@ -148,12 +148,13 @@ void WebStatusService::webStatusService(AsyncWebServerRequest * request) {
|
||||
statJson["f"] = EMSESP::txservice_.telegram_write_fail_count();
|
||||
statJson["q"] = EMSESP::txservice_.write_quality();
|
||||
|
||||
if (EMSESP::dallassensor_.dallas_enabled()) {
|
||||
if (EMSESP::temperaturesensor_.sensor_enabled()) {
|
||||
statJson = statsJson.createNestedObject();
|
||||
statJson["id"] = 3;
|
||||
statJson["s"] = EMSESP::dallassensor_.reads();
|
||||
statJson["f"] = EMSESP::dallassensor_.fails();
|
||||
statJson["q"] = EMSESP::dallassensor_.reads() == 0 ? 100 : 100 - (uint8_t)((100 * EMSESP::dallassensor_.fails()) / EMSESP::dallassensor_.reads());
|
||||
statJson["s"] = EMSESP::temperaturesensor_.reads();
|
||||
statJson["f"] = EMSESP::temperaturesensor_.fails();
|
||||
statJson["q"] =
|
||||
EMSESP::temperaturesensor_.reads() == 0 ? 100 : 100 - (uint8_t)((100 * EMSESP::temperaturesensor_.fails()) / EMSESP::temperaturesensor_.reads());
|
||||
}
|
||||
if (EMSESP::analog_enabled()) {
|
||||
statJson = statsJson.createNestedObject();
|
||||
|
||||
Reference in New Issue
Block a user