Датчик почвенной влажности soil-1 + второй релейный модуль под fan-1

По фото: у нас два одинаковых 2-канальных релейных модуля (не один) —
второй закрывает fan-1 по-настоящему (GPIO18), больше не "пока не куплено".

Добавлен soil-1: компараторный модуль почвенной влажности, читаем A0 через
ADC (GPIO34, input-only), публикуем sensor_type=soil_moisture в процентах.
Raw->% калибруется через SOIL_RAW_DRY/SOIL_RAW_WET в config.h — заводские
значения приблизительные, точную калибровку раньше сделать было нельзя (не
было физического доступа к датчику), нужно измерить на месте.

soil-1 в Postgres/Laravel платформы ещё не заведён (не трогаем
home_automatization) — телеметрия будет идти в ClickHouse, но в Laravel UI
устройство не появится до отдельной регистрации device_type/devices-записи.

Веб-интерфейс и /api/state дополнены полем "soil".
This commit is contained in:
2026-08-18 12:57:49 +05:00
parent 0456d4e447
commit 6a7d512b22
5 changed files with 127 additions and 44 deletions
+13 -1
View File
@@ -31,9 +31,12 @@ static const char PAGE_HTML[] PROGMEM = R"HTML(<!DOCTYPE html>
<h1>Гроубокс</h1>
<div class="card">
<div class="row"><span>Температура</span><span id="temp" class="sensor-value">—</span></div>
<div class="row"><span>Влажность</span><span id="hum" class="sensor-value">—</span></div>
<div class="row"><span>Влажность воздуха</span><span id="hum" class="sensor-value">—</span></div>
<div class="muted" id="updated">нет данных</div>
</div>
<div class="card">
<div class="row"><span>Влажность почвы</span><span id="soil" class="sensor-value">—</span></div>
</div>
<div class="card" id="actuators"></div>
<script>
const DEVICES = [
@@ -46,6 +49,7 @@ function render(state) {
document.getElementById('temp').textContent = state.sensor.has_reading ? state.sensor.temperature.toFixed(1) + ' °C' : '';
document.getElementById('hum').textContent = state.sensor.has_reading ? state.sensor.humidity.toFixed(0) + ' %' : '';
document.getElementById('updated').textContent = state.sensor.has_reading ? 'данные с DHT22 получены' : 'нет данных с DHT22';
document.getElementById('soil').textContent = state.soil.has_reading ? state.soil.percent.toFixed(0) + ' %' : '';
const box = document.getElementById('actuators');
box.innerHTML = '';
@@ -100,6 +104,14 @@ static void handleState() {
sensor["humidity"] = humidity;
}
float soilPercent;
bool hasSoilReading = telemetryGetLastSoil(soilPercent);
JsonObject soil = doc["soil"].to<JsonObject>();
soil["has_reading"] = hasSoilReading;
if (hasSoilReading) {
soil["percent"] = soilPercent;
}
JsonObject devicesObj = doc["devices"].to<JsonObject>();
devicesGetState(devicesObj);