#include "configuration.h" #if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include() #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "SHTXXSensor.h" #include "TelemetrySensor.h" #include SHTXXSensor::SHTXXSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHTXX, "SHTXX") {} void SHTXXSensor::getSensorVariant(SHTSensor::SHTSensorType sensorType) { switch (sensorType) { case SHTSensor::SHTSensorType::SHT2X: sensorVariant = "SHT2x"; break; case SHTSensor::SHTSensorType::SHT3X: case SHTSensor::SHTSensorType::SHT85: sensorVariant = "SHT3x/SHT85"; break; case SHTSensor::SHTSensorType::SHT3X_ALT: sensorVariant = "SHT3x"; break; case SHTSensor::SHTSensorType::SHTW1: case SHTSensor::SHTSensorType::SHTW2: case SHTSensor::SHTSensorType::SHTC1: case SHTSensor::SHTSensorType::SHTC3: sensorVariant = "SHTC1/SHTC3/SHTW1/SHTW2"; break; case SHTSensor::SHTSensorType::SHT4X: sensorVariant = "SHT4x"; break; default: sensorVariant = "Unknown"; break; } } bool SHTXXSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) { LOG_INFO("Init sensor: %s", sensorName); _bus = bus; _address = dev->address.address; if (sht.init(*_bus)) { LOG_INFO("%s: init(): success", sensorName); getSensorVariant(sht.mSensorType); LOG_INFO("%s Sensor detected: %s on 0x%x", sensorName, sensorVariant, _address); status = 1; } else { LOG_ERROR("%s: init(): failed", sensorName); } initI2CSensor(); return status; } /** * Accuracy setting of measurement. * Not all sensors support changing the sampling accuracy (only SHT3X and SHT4X) * SHTAccuracy: * - SHT_ACCURACY_HIGH: Highest repeatability at the cost of slower measurement * - SHT_ACCURACY_MEDIUM: Balanced repeatability and speed of measurement * - SHT_ACCURACY_LOW: Fastest measurement but lowest repeatability */ bool SHTXXSensor::setAccuracy(SHTSensor::SHTAccuracy newAccuracy) { // Only SHT3X-family (including alternates) and SHT4X support changing accuracy if (sht.mSensorType != SHTSensor::SHTSensorType::SHT3X && sht.mSensorType != SHTSensor::SHTSensorType::SHT3X_ALT && sht.mSensorType != SHTSensor::SHTSensorType::SHT85 && sht.mSensorType != SHTSensor::SHTSensorType::SHT4X) { LOG_WARN("%s doesn't support accuracy setting", sensorVariant); return false; } LOG_INFO("%s: setting new accuracy setting", sensorVariant); accuracy = newAccuracy; return sht.setAccuracy(accuracy); } bool SHTXXSensor::getMetrics(meshtastic_Telemetry *measurement) { if (sht.readSample()) { measurement->variant.environment_metrics.has_temperature = true; measurement->variant.environment_metrics.has_relative_humidity = true; measurement->variant.environment_metrics.temperature = sht.getTemperature(); measurement->variant.environment_metrics.relative_humidity = sht.getHumidity(); LOG_INFO("%s (%s): Got: temp:%fdegC, hum:%f%%rh", sensorName, sensorVariant, measurement->variant.environment_metrics.temperature, measurement->variant.environment_metrics.relative_humidity); return true; } else { LOG_ERROR("%s (%s): read sample failed", sensorName, sensorVariant); return false; } } AdminMessageHandleResult SHTXXSensor::handleAdminMessage(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request, meshtastic_AdminMessage *response) { AdminMessageHandleResult result; result = AdminMessageHandleResult::NOT_HANDLED; switch (request->which_payload_variant) { case meshtastic_AdminMessage_sensor_config_tag: if (!request->sensor_config.has_shtxx_config) { result = AdminMessageHandleResult::NOT_HANDLED; break; } // Check for sensor accuracy setting if (request->sensor_config.shtxx_config.has_set_accuracy) { SHTSensor::SHTAccuracy newAccuracy; if (request->sensor_config.shtxx_config.set_accuracy == 0) { newAccuracy = SHTSensor::SHT_ACCURACY_LOW; } else if (request->sensor_config.shtxx_config.set_accuracy == 1) { newAccuracy = SHTSensor::SHT_ACCURACY_MEDIUM; } else if (request->sensor_config.shtxx_config.set_accuracy == 2) { newAccuracy = SHTSensor::SHT_ACCURACY_HIGH; } else { LOG_ERROR("%s: incorrect accuracy setting", sensorName); result = AdminMessageHandleResult::HANDLED; break; } this->setAccuracy(newAccuracy); } result = AdminMessageHandleResult::HANDLED; break; default: result = AdminMessageHandleResult::NOT_HANDLED; } return result; } #endif