mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-16 12:49:56 +03:00
more to psram, names for sensors, schedule, custom as char[20]
This commit is contained in:
@@ -108,7 +108,7 @@ void TemperatureSensor::loop() {
|
||||
last_activity_ = time_now;
|
||||
}
|
||||
} else if (state_ == State::READING) {
|
||||
if (temperature_convert_complete() && (time_now - last_activity_ > CONVERSION_MS)) {
|
||||
if (temperature_convert_complete(time_now - last_activity_)) {
|
||||
#ifdef EMSESP_DEBUG_SENSOR
|
||||
LOG_DEBUG("Scanning for temperature sensors");
|
||||
#endif
|
||||
@@ -181,12 +181,12 @@ void TemperatureSensor::loop() {
|
||||
|
||||
default:
|
||||
sensorfails_++;
|
||||
LOG_ERROR("Unknown sensor %s", Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Unknown sensor %s", Sensor(addr).id());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
sensorfails_++;
|
||||
LOG_ERROR("Invalid sensor %s", Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Invalid sensor %s", Sensor(addr).id());
|
||||
}
|
||||
} else {
|
||||
if (!parasite_) {
|
||||
@@ -219,13 +219,13 @@ void TemperatureSensor::loop() {
|
||||
s->set_name("gateway_temperature");
|
||||
s->set_is_system(true); // mark as internal system temperature sensor
|
||||
if (!EMSESP::nvs_.isKey("intTemp")) {
|
||||
EMSESP::nvs_.putString("intTemp", s->id().c_str());
|
||||
EMSESP::nvs_.putString("intTemp", s->id());
|
||||
}
|
||||
// LOG_NOTICE("Adding system sensor for gateway temperature %s", s->id().c_str());
|
||||
EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
|
||||
auto newSensor = SensorCustomization();
|
||||
newSensor.id = s->id();
|
||||
newSensor.name = s->name();
|
||||
auto newSensor = SensorCustomization();
|
||||
strlcpy(newSensor.id, s->id(), sizeof(newSensor.id));
|
||||
strlcpy(newSensor.name, s->name(), sizeof(newSensor.name));
|
||||
newSensor.offset = 0;
|
||||
newSensor.is_system = s->is_system(); // always true
|
||||
settings.sensorCustomizations.push_back(newSensor);
|
||||
@@ -244,21 +244,21 @@ void TemperatureSensor::loop() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool TemperatureSensor::temperature_convert_complete() {
|
||||
bool TemperatureSensor::temperature_convert_complete(const uint32_t time) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (parasite_) {
|
||||
return true; // don't care, use the minimum time in loop
|
||||
return time > CONVERSION_MS; // don't care, use the datasheet time
|
||||
}
|
||||
return bus_.read_bit() == 1;
|
||||
#else
|
||||
return true;
|
||||
return time > CONVERSION_MS;
|
||||
#endif
|
||||
}
|
||||
|
||||
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());
|
||||
LOG_ERROR("Bus reset failed before reading scratchpad from %s", Sensor(addr).id());
|
||||
return EMS_VALUE_INT16_NOTSET;
|
||||
}
|
||||
YIELD;
|
||||
@@ -270,7 +270,7 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
YIELD;
|
||||
|
||||
if (!bus_.reset()) {
|
||||
LOG_ERROR("Bus reset failed after reading scratchpad from %s", Sensor(addr).id().c_str());
|
||||
LOG_ERROR("Bus reset failed after reading scratchpad from %s", Sensor(addr).id());
|
||||
return EMS_VALUE_INT16_NOTSET;
|
||||
}
|
||||
YIELD;
|
||||
@@ -286,7 +286,7 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
scratchpad[6],
|
||||
scratchpad[7],
|
||||
scratchpad[8],
|
||||
Sensor(addr).id().c_str());
|
||||
Sensor(addr).id());
|
||||
return EMS_VALUE_INT16_NOTSET;
|
||||
}
|
||||
|
||||
@@ -319,10 +319,10 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) {
|
||||
}
|
||||
|
||||
// update temperature sensor information name and offset
|
||||
bool TemperatureSensor::update(const std::string & id, const std::string & name, int16_t offset, bool is_system) {
|
||||
bool TemperatureSensor::update(const char * id, const char * name, int16_t offset, bool hide, bool is_system) {
|
||||
// find the sensor
|
||||
for (auto & sensor : sensors_) {
|
||||
if (sensor.id() == id) {
|
||||
if (!strcmp(id, sensor.id())) {
|
||||
// found a match, update the sensor object
|
||||
|
||||
// if HA is enabled then delete the old record
|
||||
@@ -336,27 +336,27 @@ bool TemperatureSensor::update(const std::string & id, const std::string & name,
|
||||
sensor.set_is_system(is_system);
|
||||
|
||||
// store the new name and offset in our configuration
|
||||
EMSESP::webCustomizationService.update([&id, &name, &offset, &is_system, &sensor](WebCustomization & settings) {
|
||||
EMSESP::webCustomizationService.update([&id, &name, &offset, &sensor, &hide, &is_system](WebCustomization & settings) {
|
||||
// look it up to see if it exists
|
||||
bool found = false;
|
||||
for (auto & SensorCustomization : settings.sensorCustomizations) {
|
||||
if (SensorCustomization.id == id) {
|
||||
SensorCustomization.name = name;
|
||||
if (!strcmp(id, SensorCustomization.id)) {
|
||||
strlcpy(SensorCustomization.name, name, sizeof(SensorCustomization.name));
|
||||
SensorCustomization.offset = offset;
|
||||
SensorCustomization.is_system = is_system;
|
||||
found = true;
|
||||
LOG_DEBUG("Customizing existing sensor ID %s", id.c_str());
|
||||
LOG_DEBUG("Customizing existing sensor ID %s", id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
auto newSensor = SensorCustomization();
|
||||
newSensor.id = id;
|
||||
newSensor.name = name;
|
||||
auto newSensor = SensorCustomization();
|
||||
strlcpy(newSensor.id, id, sizeof(newSensor.id));
|
||||
strlcpy(newSensor.name, name, sizeof(newSensor.name));
|
||||
newSensor.offset = offset;
|
||||
newSensor.is_system = is_system; // is user defined, not system
|
||||
settings.sensorCustomizations.push_back(newSensor);
|
||||
LOG_DEBUG("Adding new customization for sensor ID %s", id.c_str());
|
||||
LOG_DEBUG("Adding new customization for sensor ID %s", id);
|
||||
}
|
||||
sensor.ha_registered = false; // it's changed so we may need to recreate the HA config
|
||||
return StateUpdateResult::CHANGED;
|
||||
@@ -438,30 +438,27 @@ 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_(temperaturesensor), sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s/%s", F_(temperaturesensor), sensor.name());
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", F_(temperaturesensor), "_data", sensor.name().c_str());
|
||||
snprintf(topic, sizeof(topic), "%s%s/%s", F_(temperaturesensor), "_data", sensor.name());
|
||||
}
|
||||
char payload[10];
|
||||
Mqtt::queue_publish(topic, Helpers::render_value(payload, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
|
||||
}
|
||||
char cmd[COMMAND_MAX_LENGTH];
|
||||
snprintf(cmd, sizeof(cmd), "%s/%s", F_(temperaturesensor), sensor.name().c_str());
|
||||
snprintf(cmd, sizeof(cmd), "%s/%s", F_(temperaturesensor), sensor.name());
|
||||
EMSESP::webSchedulerService.onChange(cmd);
|
||||
}
|
||||
|
||||
// send empty config topic to remove the entry from HA
|
||||
void TemperatureSensor::remove_ha_topic(const std::string & id) {
|
||||
void TemperatureSensor::remove_ha_topic(const char * id) {
|
||||
if (!Mqtt::ha_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Removing HA config for temperature sensor ID %s", id.c_str());
|
||||
// use '_' as HA doesn't like '-' in the topic name
|
||||
std::string sensorid = id;
|
||||
std::replace(sensorid.begin(), sensorid.end(), '-', '_');
|
||||
LOG_DEBUG("Removing HA config for temperature sensor ID %s", id);
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/temperaturesensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str());
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/temperaturesensor_%s/config", Mqtt::basename().c_str(), id);
|
||||
Mqtt::queue_remove_topic(topic);
|
||||
}
|
||||
|
||||
@@ -504,7 +501,7 @@ void TemperatureSensor::publish_values(const bool force) {
|
||||
remove_ha_topic(sensor.id());
|
||||
sensor.ha_registered = false;
|
||||
} else if (!sensor.ha_registered || force) {
|
||||
LOG_DEBUG("Recreating HA config for sensor ID %s", sensor.id().c_str());
|
||||
LOG_DEBUG("Recreating HA config for sensor ID %s", sensor.id());
|
||||
|
||||
JsonDocument config;
|
||||
config["~"] = Mqtt::base();
|
||||
@@ -520,10 +517,10 @@ void TemperatureSensor::publish_values(const bool force) {
|
||||
char val_obj[70];
|
||||
char val_cond[170];
|
||||
if (Mqtt::is_nested()) {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']['temp']", sensor.id().c_str());
|
||||
snprintf(val_cond, sizeof(val_cond), "value_json['%s'] is defined and %s is defined", sensor.id().c_str(), val_obj);
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']['temp']", sensor.id());
|
||||
snprintf(val_cond, sizeof(val_cond), "value_json['%s'] is defined and %s is defined", sensor.id(), val_obj);
|
||||
} else {
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name().c_str());
|
||||
snprintf(val_obj, sizeof(val_obj), "value_json['%s']", sensor.name());
|
||||
snprintf(val_cond, sizeof(val_cond), "%s is defined", val_obj);
|
||||
}
|
||||
|
||||
@@ -537,17 +534,14 @@ void TemperatureSensor::publish_values(const bool force) {
|
||||
|
||||
char uniq_s[70];
|
||||
if (Mqtt::entity_format() == Mqtt::entityFormat::MULTI_SHORT) {
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_%s_%s", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id().c_str());
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_%s_%s", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id());
|
||||
} else {
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_%s", F_(temperaturesensor), sensor.id().c_str());
|
||||
snprintf(uniq_s, sizeof(uniq_s), "%s_%s", F_(temperaturesensor), sensor.id());
|
||||
}
|
||||
|
||||
config["uniq_id"] = uniq_s;
|
||||
config["def_ent_id"] = (std::string) "sensor." + uniq_s;
|
||||
|
||||
char name[50];
|
||||
snprintf(name, sizeof(name), "%s", sensor.name().c_str());
|
||||
config["name"] = name;
|
||||
config["name"] = sensor.name();
|
||||
|
||||
// see if we need to create the [devs] discovery section, as this needs only to be done once for all sensors
|
||||
bool is_ha_device_created = false;
|
||||
@@ -562,7 +556,7 @@ void TemperatureSensor::publish_values(const bool force) {
|
||||
Mqtt::add_ha_avail_section(config.as<JsonObject>(), stat_t, !is_ha_device_created, val_cond);
|
||||
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id().c_str());
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id());
|
||||
|
||||
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
|
||||
}
|
||||
@@ -579,17 +573,15 @@ 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
|
||||
char id_s[20];
|
||||
snprintf(id_s,
|
||||
sizeof(id_s),
|
||||
snprintf(id_,
|
||||
sizeof(id_),
|
||||
"%02X_%04X_%04X_%04X",
|
||||
(unsigned int)(internal_id_ >> 48) & 0xFF,
|
||||
(unsigned int)(internal_id_ >> 32) & 0xFFFF,
|
||||
(unsigned int)(internal_id_ >> 16) & 0xFFFF,
|
||||
(unsigned int)(internal_id_) & 0xFFFF);
|
||||
id_ = std::string(id_s);
|
||||
name_ = std::string{}; // name (alias) is empty
|
||||
offset_ = 0; // 0 degrees offset
|
||||
name_[0] = '\0';
|
||||
offset_ = 0; // 0 degrees offset
|
||||
}
|
||||
|
||||
uint64_t TemperatureSensor::get_id(const uint8_t addr[]) {
|
||||
@@ -599,8 +591,8 @@ uint64_t TemperatureSensor::get_id(const uint8_t addr[]) {
|
||||
|
||||
// find the name from the customization service
|
||||
// if empty, return the ID as a string
|
||||
std::string TemperatureSensor::Sensor::name() const {
|
||||
if (name_.empty()) {
|
||||
const char * TemperatureSensor::Sensor::name() const {
|
||||
if (name_[0] == '\0') {
|
||||
return id_;
|
||||
}
|
||||
return name_;
|
||||
@@ -613,8 +605,8 @@ bool TemperatureSensor::Sensor::apply_customization() {
|
||||
auto const & sensors = settings.sensorCustomizations;
|
||||
if (!sensors.empty()) {
|
||||
for (const auto & sensor : sensors) {
|
||||
if (id_ == sensor.id) {
|
||||
LOG_DEBUG("Loading customization for temperature sensor %s", sensor.id.c_str());
|
||||
if (!strcmp(sensor.id, id_)) {
|
||||
LOG_DEBUG("Loading customization for temperature sensor %s", id_);
|
||||
set_name(sensor.name);
|
||||
set_offset(sensor.offset);
|
||||
set_is_system(sensor.is_system);
|
||||
|
||||
Reference in New Issue
Block a user