mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-09 01:09:51 +03:00
digital_out, settings #1375, dev.5b
This commit is contained in:
@@ -57,7 +57,9 @@ void AnalogSensor::start() {
|
||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
||||
FL_(commands_cmd));
|
||||
|
||||
Mqtt::subscribe(EMSdevice::DeviceType::ANALOGSENSOR, "analogsensor/#", nullptr); // use empty function callback
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "%s/#", F_(analogsensor));
|
||||
Mqtt::subscribe(EMSdevice::DeviceType::ANALOGSENSOR, topic, nullptr); // use empty function callback
|
||||
}
|
||||
|
||||
// load settings from the customization file, sorts them and initializes the GPIOs
|
||||
@@ -206,10 +208,9 @@ void AnalogSensor::reload() {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
digitalWrite(sensor.gpio(), sensor.offset() > 0 ? 1 : 0);
|
||||
digitalWrite(sensor.gpio(), sensor.offset() * sensor.factor() > 0 ? 1 : 0);
|
||||
sensor.set_value(digitalRead(sensor.gpio()));
|
||||
}
|
||||
sensor.set_uom(0); // no uom, just for safe measures
|
||||
publish_sensor(sensor);
|
||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
||||
LOG_DEBUG("Adding PWM output sensor on GPIO %02d", sensor.gpio());
|
||||
@@ -434,15 +435,15 @@ void AnalogSensor::remove_ha_topic(const int8_t type, const uint8_t gpio) const
|
||||
#else
|
||||
if (type == AnalogType::DIGITAL_OUT) {
|
||||
#endif
|
||||
snprintf(topic, sizeof(topic), "switch/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
||||
snprintf(topic, sizeof(topic), "switch/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||
} else if (type == AnalogType::DIGITAL_OUT) { // DAC
|
||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
||||
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||
} else if (type >= AnalogType::PWM_0) {
|
||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
||||
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||
} else if (type == AnalogType::DIGITAL_IN) {
|
||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), gpio);
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
|
||||
}
|
||||
Mqtt::queue_remove_topic(topic);
|
||||
}
|
||||
@@ -514,7 +515,7 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_MEDIUM> config;
|
||||
|
||||
char stat_t[50];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/analogsensor_data", Mqtt::basename().c_str()); // use basename
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s_data", Mqtt::basename().c_str(), F_(analogsensor)); // use base path
|
||||
config["stat_t"] = stat_t;
|
||||
|
||||
char val_obj[50];
|
||||
@@ -534,9 +535,9 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
|
||||
char uniq_s[70];
|
||||
if (Mqtt::entity_format() == Mqtt::entityFormat::MULTI_SHORT) {
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_analogsensor_%02d", Mqtt::basename().c_str(), sensor.gpio());
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_%s_%02d", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||
} else {
|
||||
snprintf(uniq_s, sizeof(uniq_s), "analogsensor_%02d", sensor.gpio());
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_%02d", F_(analogsensor), sensor.gpio());
|
||||
}
|
||||
|
||||
config["obj_id"] = uniq_s;
|
||||
@@ -559,8 +560,8 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
#else
|
||||
if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
||||
#endif
|
||||
snprintf(topic, sizeof(topic), "switch/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "switch/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||
config["cmd_t"] = command_topic;
|
||||
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||
config["pl_on"] = true;
|
||||
@@ -574,30 +575,30 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
config["pl_off"] = Helpers::render_boolean(result, false);
|
||||
}
|
||||
} else if (sensor.type() == AnalogType::DIGITAL_OUT) { // DAC
|
||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||
config["cmd_t"] = command_topic;
|
||||
config["min"] = 0;
|
||||
config["max"] = 255;
|
||||
config["mode"] = "box"; // auto, slider or box
|
||||
config["step"] = 1;
|
||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
||||
snprintf(topic, sizeof(topic), "number/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||
config["cmd_t"] = command_topic;
|
||||
config["min"] = 0;
|
||||
config["max"] = 100;
|
||||
config["mode"] = "box"; // auto, slider or box
|
||||
config["step"] = 0.1;
|
||||
} else if (sensor.type() == AnalogType::COUNTER) {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/analogsensor/%s", Mqtt::basename().c_str(), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::basename().c_str(), F_(analogsensor), sensor.name().c_str());
|
||||
config["cmd_t"] = command_topic;
|
||||
config["stat_cla"] = "total_increasing";
|
||||
// config["mode"] = "box"; // auto, slider or box
|
||||
// config["step"] = sensor.factor();
|
||||
} else if (sensor.type() == AnalogType::DIGITAL_IN) {
|
||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
|
||||
config["pl_on"] = true;
|
||||
config["pl_off"] = false;
|
||||
@@ -610,7 +611,7 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
config["pl_off"] = Helpers::render_boolean(result, false);
|
||||
}
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
|
||||
config["stat_cla"] = "measurement";
|
||||
}
|
||||
|
||||
@@ -626,7 +627,9 @@ void AnalogSensor::publish_values(const bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
Mqtt::queue_publish("analogsensor_data", doc.as<JsonObject>());
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "%s_data", F_(analogsensor));
|
||||
Mqtt::queue_publish(topic, doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
// called from emsesp.cpp, similar to the emsdevice->get_value_info
|
||||
@@ -702,6 +705,7 @@ bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject
|
||||
JsonObject dataSensor = output.createNestedObject(sensor.name());
|
||||
dataSensor["gpio"] = sensor.gpio();
|
||||
dataSensor["type"] = F_(number);
|
||||
dataSensor["value"] = sensor.value();
|
||||
dataSensor["analog"] = FL_(list_sensortype)[sensor.type()];
|
||||
if (sensor.type() == AnalogType::ADC) {
|
||||
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
|
||||
@@ -717,7 +721,6 @@ bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject
|
||||
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
|
||||
dataSensor["frequency"] = sensor.factor();
|
||||
}
|
||||
dataSensor["value"] = sensor.value();
|
||||
} else if (id == 0) { // output values command
|
||||
output[sensor.name()] = sensor.value();
|
||||
} else { // if someone wants gpio numbers
|
||||
@@ -763,6 +766,7 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
||||
}
|
||||
for (auto & sensor : sensors_) {
|
||||
if (sensor.gpio() == gpio) {
|
||||
double oldoffset = sensor.offset();
|
||||
if (sensor.type() == AnalogType::COUNTER) {
|
||||
if (val < 0 || value[0] == '+') { // sign corrects values
|
||||
sensor.set_offset(sensor.value() + val);
|
||||
@@ -771,11 +775,8 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
||||
sensor.set_offset(val);
|
||||
sensor.set_value(val);
|
||||
}
|
||||
publish_sensor(sensor);
|
||||
return true;
|
||||
} else if (sensor.type() == AnalogType::ADC) {
|
||||
sensor.set_offset(val);
|
||||
return true;
|
||||
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
|
||||
uint8_t v = val;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@@ -784,8 +785,6 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
||||
sensor.set_value(v);
|
||||
pinMode(sensor.gpio(), OUTPUT);
|
||||
dacWrite(sensor.gpio(), sensor.offset());
|
||||
publish_sensor(sensor);
|
||||
return true;
|
||||
} else
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
if ((sensor.gpio() == 23 || sensor.gpio() == 24) && v <= 255) {
|
||||
@@ -801,9 +800,7 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
||||
sensor.set_offset(v);
|
||||
sensor.set_value(v);
|
||||
pinMode(sensor.gpio(), OUTPUT);
|
||||
digitalWrite(sensor.gpio(), sensor.offset() > 0 ? 1 : 0);
|
||||
publish_sensor(sensor);
|
||||
return true;
|
||||
digitalWrite(sensor.gpio(), sensor.offset() * sensor.factor() > 0 ? 1 : 0);
|
||||
}
|
||||
} else if (sensor.type() >= AnalogType::PWM_0) {
|
||||
if (val > 100) {
|
||||
@@ -819,9 +816,18 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
|
||||
uint8_t channel = sensor.type() - AnalogType::PWM_0;
|
||||
ledcWrite(channel, (uint32_t)(val * 8191 / 100));
|
||||
#endif
|
||||
publish_sensor(sensor);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (oldoffset != sensor.offset()) {
|
||||
// don't save state of digital out if fixed value on reboot is selected
|
||||
if (sensor.type() != AnalogType::DIGITAL_OUT || sensor.uom() == 0) {
|
||||
update(sensor.gpio(), sensor.name(), sensor.offset(), sensor.factor(), sensor.uom(), sensor.type(), false);
|
||||
}
|
||||
publish_sensor(sensor);
|
||||
changed_ = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1597,6 +1597,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
||||
}
|
||||
// do not overwrite
|
||||
if (json.containsKey(name)) {
|
||||
EMSESP::logger().debug("double json key: %s", name);
|
||||
continue;
|
||||
}
|
||||
// handle Booleans
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.6.3-dev.5a"
|
||||
#define EMSESP_APP_VERSION "3.6.3-dev.5b"
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace emsesp {
|
||||
|
||||
using namespace std::placeholders; // for `_1` etc
|
||||
|
||||
bool WebCustomization::_start = true;
|
||||
|
||||
WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||
: _httpEndpoint(WebCustomization::read,
|
||||
WebCustomization::update,
|
||||
@@ -132,10 +134,13 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
||||
sensor.factor = analogJson["factor"];
|
||||
sensor.uom = analogJson["uom"];
|
||||
sensor.type = analogJson["type"];
|
||||
if (_start && sensor.type == EMSESP::analogsensor_.AnalogType::DIGITAL_OUT && sensor.uom > DeviceValue::DeviceValueUOM::NONE) {
|
||||
sensor.offset = sensor.uom - 1;
|
||||
}
|
||||
customizations.analogCustomizations.push_back(sensor); // add to list
|
||||
}
|
||||
}
|
||||
|
||||
_start = false;
|
||||
// load array of entities id's with masks, building up the object class
|
||||
customizations.entityCustomizations.clear();
|
||||
if (root["masked_entities"].is<JsonArray>()) {
|
||||
@@ -203,7 +208,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request) {
|
||||
size_t buffer = EMSESP_JSON_SIZE_XXXXLARGE;
|
||||
auto * response = new MsgpackAsyncJsonResponse(true, buffer);
|
||||
|
||||
while (!response->getSize()) {
|
||||
while (!response) {
|
||||
delete response;
|
||||
buffer -= 1024;
|
||||
response = new MsgpackAsyncJsonResponse(true, buffer);
|
||||
@@ -259,7 +264,7 @@ void WebCustomizationService::customization_entities(AsyncWebServerRequest * req
|
||||
// emsesp::EMSESP::logger().info(id.as<const char *>());
|
||||
}
|
||||
// add deleted entities from file
|
||||
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
|
||||
read([&](WebCustomization & settings) {
|
||||
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
|
||||
if (entityCustomization.device_id == device_id) {
|
||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||
@@ -288,7 +293,7 @@ void WebCustomizationService::customization_entities(AsyncWebServerRequest * req
|
||||
emsdevice->getCustomizationEntities(entity_ids);
|
||||
|
||||
// Save the list to the customization file
|
||||
EMSESP::webCustomizationService.update(
|
||||
update(
|
||||
[&](WebCustomization & settings) {
|
||||
// see if we already have a mask list for this device, if so remove it
|
||||
for (auto it = settings.entityCustomizations.begin(); it != settings.entityCustomizations.end();) {
|
||||
|
||||
@@ -73,6 +73,9 @@ class WebCustomization {
|
||||
std::list<EntityCustomization> entityCustomizations; // for a list of entities that have a special mask set
|
||||
static void read(WebCustomization & customizations, JsonObject & root);
|
||||
static StateUpdateResult update(JsonObject & root, WebCustomization & customizations);
|
||||
|
||||
private:
|
||||
static bool _start;
|
||||
};
|
||||
|
||||
class WebCustomizationService : public StatefulService<WebCustomization> {
|
||||
|
||||
@@ -93,7 +93,8 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
|
||||
}
|
||||
|
||||
// add any custom entities
|
||||
if (EMSESP::webCustomEntityService.count_entities()) {
|
||||
uint8_t customEntities = EMSESP::webCustomEntityService.count_entities();
|
||||
if (customEntities) {
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["id"] = 99; // the last unique id
|
||||
obj["tn"] = Helpers::translated_word(FL_(custom_device)); // translated device type name
|
||||
@@ -103,7 +104,7 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
|
||||
obj["d"] = 0; // deviceid
|
||||
obj["p"] = 0; // productid
|
||||
obj["v"] = 0; // version
|
||||
obj["e"] = EMSESP::webCustomEntityService.count_entities(); // number of custom entities
|
||||
obj["e"] = customEntities; // number of custom entities
|
||||
}
|
||||
|
||||
root["connected"] = EMSESP::bus_status() != 2;
|
||||
@@ -163,7 +164,8 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
||||
}
|
||||
}
|
||||
|
||||
root["analog_enabled"] = EMSESP::analogsensor_.analog_enabled();
|
||||
root["analog_enabled"] = EMSESP::analog_enabled();
|
||||
root["platform"] = EMSESP_PLATFORM;
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@@ -180,7 +182,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request) {
|
||||
auto * response = new MsgpackAsyncJsonResponse(false, buffer);
|
||||
|
||||
// check size
|
||||
while (!response->getSize()) {
|
||||
while (!response) {
|
||||
delete response;
|
||||
buffer -= 1024;
|
||||
response = new MsgpackAsyncJsonResponse(false, buffer);
|
||||
|
||||
Reference in New Issue
Block a user