tidied up commands

This commit is contained in:
Proddy
2024-01-28 18:28:26 +01:00
parent d11508282f
commit 5735ffd222
6 changed files with 114 additions and 127 deletions

View File

@@ -33,29 +33,13 @@ void AnalogSensor::start() {
LOG_INFO("Starting Analog sensor service"); LOG_INFO("Starting Analog sensor service");
// Add API call for /info // Add API calls
Command::add(
EMSdevice::DeviceType::ANALOGSENSOR,
F_(info),
[&](const char * value, const int8_t id, JsonObject output) { return command_info(value, id, output); },
FL_(info_cmd));
Command::add(
EMSdevice::DeviceType::ANALOGSENSOR,
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( Command::add(
EMSdevice::DeviceType::ANALOGSENSOR, EMSdevice::DeviceType::ANALOGSENSOR,
F_(setvalue), F_(setvalue),
[&](const char * value, const int8_t id) { return command_setvalue(value, id); }, [&](const char * value, const int8_t id) { return command_setvalue(value, id); },
FL_(setiovalue_cmd), FL_(setiovalue_cmd),
CommandFlag::ADMIN_ONLY); CommandFlag::ADMIN_ONLY);
Command::add(
EMSdevice::DeviceType::ANALOGSENSOR,
F_(commands),
[&](const char * value, const int8_t id, JsonObject output) { return command_commands(value, id, output); },
FL_(commands_cmd));
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
snprintf(topic, sizeof(topic), "%s/#", F_(analogsensor)); snprintf(topic, sizeof(topic), "%s/#", F_(analogsensor));
@@ -636,48 +620,64 @@ void AnalogSensor::publish_values(const bool force) {
Mqtt::queue_publish(topic, doc.as<JsonObject>()); Mqtt::queue_publish(topic, doc.as<JsonObject>());
} }
// called from emsesp.cpp, similar to the emsdevice->get_value_info // called from emsesp.cpp for commands
// searches by name // searches sensor by name
// TODO see if this can replace the command_info bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int8_t id) {
bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int8_t id) const {
if (sensors_.empty()) { if (sensors_.empty()) {
return true; // no sensors, return true
}
uint8_t show_all = 0;
if (Helpers::hasValue(cmd)) {
show_all = (strncmp(cmd, F_(info), 4) == 0) ? 1 : (strncmp(cmd, F_(values), 6) == 0) ? 2 : 0;
}
// see if we're showing all sensors
if (show_all) {
for (const auto & sensor : sensors_) {
if (show_all == 1) {
// info
JsonObject dataSensor = output[sensor.name()].to<JsonObject>();
addSensorJson(dataSensor, sensor);
} else {
// values, shortname version. Also used in 'system allvalues'
output[sensor.name()] = sensor.value();
}
}
return true; return true;
} }
// make a copy of the string command for parsing // check of it a 'commmands' command
char command_s[30]; if (Helpers::toLower(cmd) == F_(commands)) {
strlcpy(command_s, cmd, sizeof(command_s)); return Command::list(EMSdevice::DeviceType::TEMPERATURESENSOR, output);
}
// this is for a specific sensor
// make a copy of the string command for parsing, and lowercase it
char sensor_name[30] = {'\0'};
char * attribute_s = nullptr; char * attribute_s = nullptr;
strlcpy(sensor_name, cmd, sizeof(sensor_name));
auto sensor_lowercase = Helpers::toLower(sensor_name);
// check specific attribute to fetch instead of the complete record // check specific attribute to fetch instead of the complete record
char * breakp = strchr(command_s, '/'); char * breakp = strchr(sensor_name, '/');
if (breakp) { if (breakp) {
*breakp = '\0'; *breakp = '\0';
attribute_s = breakp + 1; attribute_s = breakp + 1;
} }
for (const auto & sensor : sensors_) { for (const auto & sensor : sensors_) {
if (Helpers::toLower(command_s) == Helpers::toLower(sensor.name().c_str()) || Helpers::atoint(command_s) == sensor.gpio()) { if (sensor_lowercase == Helpers::toLower(sensor.name().c_str()) || Helpers::atoint(sensor_name) == sensor.gpio()) {
output["gpio"] = sensor.gpio(); // add the details
output["name"] = sensor.name(); addSensorJson(output, sensor);
output["type"] = F_(number);
output["analog"] = FL_(list_sensortype)[sensor.type()]; /*
output["uom"] = EMSdevice::uom_to_string(sensor.uom()); // if someone wants gpio numbers
output["offset"] = sensor.offset(); char gpio_str[9];
output["factor"] = sensor.factor(); snprintf(gpio_str, sizeof(gpio_str), "gpio_%02d", sensor.gpio());
output["value"] = sensor.value(); output[gpio_str] = sensor.value();
output["writeable"] = sensor.type() == AnalogType::COUNTER || (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2); */
// min/max for writeable analogs
if (sensor.type() == AnalogType::COUNTER) {
output["min"] = 0;
output["max"] = 4000000;
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
output["min"] = 0;
output["max"] = sensor.gpio() == 25 || sensor.gpio() == 26 ? 255 : 1;
} else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) {
output["min"] = 0;
output["max"] = 100;
}
// if we're filtering on an attribute, go find it // if we're filtering on an attribute, go find it
if (attribute_s) { if (attribute_s) {
if (output.containsKey(attribute_s)) { if (output.containsKey(attribute_s)) {
@@ -687,57 +687,45 @@ bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int
return true; return true;
} else { } else {
char error[100]; char error[100];
snprintf(error, sizeof(error), "cannot find attribute %s in entity %s", attribute_s, command_s); snprintf(error, sizeof(error), "cannot find attribute %s in entity %s", attribute_s, sensor_name);
output.clear(); output.clear();
output["message"] = error; output["message"] = error;
return false; return false;
} }
} }
return true; return true; // found a match, exit
} }
} }
return false; return false; // not found
} }
// creates JSON doc from values void AnalogSensor::addSensorJson(JsonObject output, const Sensor & sensor) {
// returns true if there are no sensors output["gpio"] = sensor.gpio();
// TODO see if this can be merged with get_value_info so we can remove the commands (info, commands, etc...) output["type"] = F_(number);
bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject output) const { output["analog"] = FL_(list_sensortype)[sensor.type()];
if (sensors_.empty()) { output["value"] = sensor.value();
return true; output["writeable"] = sensor.type() == AnalogType::COUNTER || (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2);
} if (sensor.type() == AnalogType::COUNTER) {
output["min"] = 0;
for (const auto & sensor : sensors_) { output["max"] = 4000000;
if (id == -1) { // show number and id for info command output["start_value"] = sensor.offset();
JsonObject dataSensor = output[sensor.name()].to<JsonObject>(); output["factor"] = sensor.factor();
dataSensor["gpio"] = sensor.gpio(); output["uom"] = EMSdevice::uom_to_string(sensor.uom());
dataSensor["type"] = F_(number); } else if (sensor.type() == AnalogType::ADC) {
dataSensor["value"] = sensor.value(); output["offset"] = sensor.offset();
dataSensor["analog"] = FL_(list_sensortype)[sensor.type()]; output["factor"] = sensor.factor();
if (sensor.type() == AnalogType::ADC) { output["uom"] = EMSdevice::uom_to_string(sensor.uom());
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
dataSensor["offset"] = sensor.offset();
dataSensor["factor"] = sensor.factor();
} else if (sensor.type() == AnalogType::COUNTER) {
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
dataSensor["start_value"] = sensor.offset();
dataSensor["factor"] = sensor.factor();
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) { } else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
dataSensor["factor"] = sensor.factor(); output["factor"] = sensor.factor();
} else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) { } else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) {
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom()); output["frequency"] = sensor.factor();
dataSensor["frequency"] = sensor.factor(); output["min"] = 0;
output["max"] = 100;
output["uom"] = EMSdevice::uom_to_string(sensor.uom());
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
output["min"] = 0;
output["max"] = sensor.gpio() == 25 || sensor.gpio() == 26 ? 255 : 1;
} }
} else if (id == 0) { // output values command
output[sensor.name()] = sensor.value();
} else { // if someone wants gpio numbers
char gpio_str[9];
snprintf(gpio_str, sizeof(gpio_str), "gpio_%02d", sensor.gpio());
output[gpio_str] = sensor.value();
}
}
return (output.size() > 0);
} }
// this creates the sensor, initializing everything // this creates the sensor, initializing everything
@@ -853,9 +841,4 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
return false; return false;
} }
// list commands
bool AnalogSensor::command_commands(const char * value, const int8_t id, JsonObject output) {
return Command::list(EMSdevice::DeviceType::ANALOGSENSOR, output);
}
} // namespace emsesp } // namespace emsesp

View File

@@ -153,11 +153,9 @@ class AnalogSensor {
} }
bool update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted = false); 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; bool get_value_info(JsonObject output, const char * cmd, const int8_t id = -1);
void store_counters(); void store_counters();
bool command_info(const char * value, const int8_t id, JsonObject output) const;
private: private:
static constexpr uint8_t MAX_SENSORS = 20; static constexpr uint8_t MAX_SENSORS = 20;
static constexpr uint32_t MEASURE_ANALOG_INTERVAL = 500; static constexpr uint32_t MEASURE_ANALOG_INTERVAL = 500;
@@ -167,7 +165,7 @@ class AnalogSensor {
void remove_ha_topic(const int8_t type, const uint8_t id) const; void remove_ha_topic(const int8_t type, const uint8_t id) const;
bool command_setvalue(const char * value, const int8_t gpio); bool command_setvalue(const char * value, const int8_t gpio);
void measure(); void measure();
bool command_commands(const char * value, const int8_t id, JsonObject output); void addSensorJson(JsonObject output, const Sensor & sensor);
std::vector<Sensor> sensors_; // our list of sensors std::vector<Sensor> sensors_; // our list of sensors

View File

@@ -932,7 +932,7 @@ void EMSdevice::generate_values_web(JsonObject output) {
// add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique // add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique
obj["id"] = dv.has_tag() ? mask + tag_to_string(dv.tag) + " " + fullname : mask + fullname; // suffix tag obj["id"] = dv.has_tag() ? mask + tag_to_string(dv.tag) + " " + fullname : mask + fullname; // suffix tag
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338 // TAG https://github.com/emsesp/EMS-ESP32/issues/1338
// obj["id"] = dv.has_tag() ? mask + fullname + " " + tag_to_string(dv.tag) : mask + fullname; // suffix tag // obj["id"] = dv.has_tag() ? mask + fullname + " " + tag_to_string(dv.tag) : mask + fullname; // suffix tag
// add commands and options // add commands and options
@@ -1046,7 +1046,7 @@ void EMSdevice::generate_values_web_customization(JsonArray output) {
if (fullname) { if (fullname) {
obj["n"] = dv.has_tag() ? std::string(tag_to_string(dv.tag)) + " " + fullname : fullname; // prefix tag obj["n"] = dv.has_tag() ? std::string(tag_to_string(dv.tag)) + " " + fullname : fullname; // prefix tag
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338 // TAG https://github.com/emsesp/EMS-ESP32/issues/1338
// obj["n"] = (dv.has_tag()) ? fullname + " " + tag_to_string(dv.tag) : fullname; // suffix tag // obj["n"] = (dv.has_tag()) ? fullname + " " + tag_to_string(dv.tag) : fullname; // suffix tag
} }
@@ -1394,7 +1394,7 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t
if (!fullname.empty()) { if (!fullname.empty()) {
json["fullname"] = dv.has_tag() ? fullname + " " + tag_to_string(dv.tag) : fullname; // suffix tag json["fullname"] = dv.has_tag() ? fullname + " " + tag_to_string(dv.tag) : fullname; // suffix tag
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338 // TAG https://github.com/emsesp/EMS-ESP32/issues/1338
json["fullname"] = dv.has_tag() ? std::string(tag_to_string(dv.tag)) + " " + fullname.c_str() : fullname; // prefix tag json["fullname"] = dv.has_tag() ? std::string(tag_to_string(dv.tag)) + " " + fullname.c_str() : fullname; // prefix tag
} }
@@ -1600,7 +1600,7 @@ bool EMSdevice::generate_values(JsonObject output, const uint8_t tag_filter, con
// add tag // add tag
if (have_tag) { if (have_tag) {
snprintf(name, sizeof(name), "%s %s (%s)", tag_to_string(dv.tag), fullname.c_str(), dv.short_name); // prefix tag snprintf(name, sizeof(name), "%s %s (%s)", tag_to_string(dv.tag), fullname.c_str(), dv.short_name); // prefix tag
// TODO check TAG https://github.com/emsesp/EMS-ESP32/issues/1338 // TAG https://github.com/emsesp/EMS-ESP32/issues/1338
// snprintf(name, sizeof(name), "%s %s (%s)", fullname.c_str(), tag_to_string(dv.tag), dv.short_name); // sufix tag // snprintf(name, sizeof(name), "%s %s (%s)", fullname.c_str(), tag_to_string(dv.tag), dv.short_name); // sufix tag
} else { } else {
snprintf(name, sizeof(name), "%s (%s)", fullname.c_str(), dv.short_name); snprintf(name, sizeof(name), "%s (%s)", fullname.c_str(), dv.short_name);

View File

@@ -119,16 +119,15 @@ bool System::command_allvalues(const char * value, const int8_t id, JsonObject o
emsdevice->generate_values(device_output, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::API_VERBOSE); // use nested for id -1 and 0 emsdevice->generate_values(device_output, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::API_VERBOSE); // use nested for id -1 and 0
} }
// Custom entities // Custom Entities
device_output = output["Custom Entities"].to<JsonObject>(); device_output = output["Custom Entities"].to<JsonObject>();
EMSESP::webCustomEntityService.get_value_info(device_output, ""); EMSESP::webCustomEntityService.get_value_info(device_output, "");
// Sensors // Sensors
device_output = output["Analog Sensors"].to<JsonObject>(); device_output = output["Analog Sensors"].to<JsonObject>();
// TODO fix this also for analogsensor EMSESP::analogsensor_.get_value_info(device_output, "values");
EMSESP::analogsensor_.command_info(nullptr, 0, device_output);
device_output = output["Temperature Sensors"].to<JsonObject>(); device_output = output["Temperature Sensors"].to<JsonObject>();
EMSESP::temperaturesensor_.get_value_info(device_output, nullptr); EMSESP::temperaturesensor_.get_value_info(device_output, "values");
return true; return true;
} }

View File

@@ -349,24 +349,25 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons
return true; // no sensors, return true return true; // no sensors, return true
} }
bool show_all = true; uint8_t show_all = 0;
if (Helpers::hasValue(cmd)) { if (Helpers::hasValue(cmd)) {
show_all = (strncmp(cmd, F_(info), 4) == 0); show_all = (strncmp(cmd, F_(info), 4) == 0) ? 1 : (strncmp(cmd, F_(values), 6) == 0) ? 2 : 0;
} }
// see if we're showing all sensors // see if we're showing all sensors
if (show_all) { if (show_all) {
for (const auto & sensor : sensors_) { for (const auto & sensor : sensors_) {
if (show_all == 1) {
// info
JsonObject dataSensor = output[sensor.name()].to<JsonObject>(); JsonObject dataSensor = output[sensor.name()].to<JsonObject>();
dataSensor["id"] = sensor.id(); addSensorJson(dataSensor, sensor);
dataSensor["offset"] = sensor.offset(); } else {
// values, shortname version. Also used in 'system allvalues'
if (Helpers::hasValue(sensor.temperature_c)) { if (Helpers::hasValue(sensor.temperature_c)) {
char val[10]; char val[10];
dataSensor["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0)); output[sensor.name()] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
}
} }
dataSensor["type"] = F_(number);
dataSensor["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
dataSensor["writeable"] = false;
} }
return true; return true;
} }
@@ -393,17 +394,8 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons
for (const auto & sensor : sensors_) { for (const auto & sensor : sensors_) {
// match custom name or sensor ID // match custom name or sensor ID
if (sensor_lowercase == Helpers::toLower(sensor.name().c_str()) || sensor_lowercase == Helpers::toLower(sensor.id().c_str())) { if (sensor_lowercase == Helpers::toLower(sensor.name().c_str()) || sensor_lowercase == Helpers::toLower(sensor.id().c_str())) {
output["id"] = sensor.id(); // add values
output["name"] = sensor.name(); addSensorJson(output, sensor);
if (Helpers::hasValue(sensor.temperature_c)) {
char val[10];
output["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
}
output["type"] = F_(number);
output["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
output["writeable"] = false;
// if we're filtering on an attribute, go find it // if we're filtering on an attribute, go find it
if (attribute_s) { if (attribute_s) {
if (output.containsKey(attribute_s)) { if (output.containsKey(attribute_s)) {
@@ -426,6 +418,20 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons
return false; // not found return false; // not found
} }
void TemperatureSensor::addSensorJson(JsonObject output, const Sensor & sensor) {
output["id"] = sensor.id();
output["name"] = sensor.name();
if (Helpers::hasValue(sensor.temperature_c)) {
char val[10];
output["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
}
output["type"] = F_(number);
output["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
output["writeable"] = false;
}
// publish a single sensor to MQTT // publish a single sensor to MQTT
void TemperatureSensor::publish_sensor(const Sensor & sensor) { void TemperatureSensor::publish_sensor(const Sensor & sensor) {
if (Mqtt::enabled() && Mqtt::publish_single()) { if (Mqtt::enabled() && Mqtt::publish_single()) {

View File

@@ -152,6 +152,7 @@ class TemperatureSensor {
int16_t get_temperature_c(const uint8_t addr[]); int16_t get_temperature_c(const uint8_t addr[]);
uint64_t get_id(const uint8_t addr[]); uint64_t get_id(const uint8_t addr[]);
void remove_ha_topic(const std::string & id); void remove_ha_topic(const std::string & id);
void addSensorJson(JsonObject output, const Sensor & sensor);
std::vector<Sensor> sensors_; // our list of active sensors std::vector<Sensor> sensors_; // our list of active sensors