mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-14 15:54:47 +00:00
Support multiple temperature sensors
This commit is contained in:
parent
6479fd6a63
commit
e121ec75d8
@ -675,8 +675,7 @@ bool AmsConfiguration::load() {
|
||||
bool success = false;
|
||||
|
||||
EEPROM.begin(EEPROM_SIZE);
|
||||
int cs = EEPROM.read(address);
|
||||
address++;
|
||||
int cs = EEPROM.read(address++);
|
||||
switch(cs) {
|
||||
case 81: // v1.2
|
||||
success = loadConfig81(address);
|
||||
@ -686,11 +685,13 @@ bool AmsConfiguration::load() {
|
||||
break;
|
||||
case 83: // v1.4
|
||||
EEPROM.get(address, config);
|
||||
loadTempSensors();
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
EEPROM.end();
|
||||
|
||||
|
||||
if(config.apPin >= 0)
|
||||
pinMode(config.apPin, INPUT_PULLUP);
|
||||
meterChanged = true;
|
||||
@ -698,6 +699,35 @@ bool AmsConfiguration::load() {
|
||||
return success;
|
||||
}
|
||||
|
||||
void AmsConfiguration::loadTempSensors() {
|
||||
int address = EEPROM_TEMP_CONFIG_ADDRESS;
|
||||
int c = 0;
|
||||
int storedCount = EEPROM.read(address++);
|
||||
if(storedCount > 0 && storedCount <= 32) {
|
||||
for(int i = 0; i < storedCount; i++) {
|
||||
TempSensorConfig* tsc = new TempSensorConfig();
|
||||
EEPROM.get(address, *tsc);
|
||||
if(tsc->address[0] != 0xFF) {
|
||||
tempSensors[c++] = tsc;
|
||||
}
|
||||
address += sizeof(*tsc);
|
||||
}
|
||||
}
|
||||
tempSensorCount = c;
|
||||
}
|
||||
|
||||
void AmsConfiguration::saveTempSensors() {
|
||||
int address = EEPROM_TEMP_CONFIG_ADDRESS;
|
||||
EEPROM.put(address++, tempSensorCount);
|
||||
for(int i = 0; i < tempSensorCount; i++) {
|
||||
TempSensorConfig* tsc = tempSensors[i];
|
||||
if(tsc->address[0] != 0xFF) {
|
||||
EEPROM.put(address, *tsc);
|
||||
address += sizeof(*tsc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AmsConfiguration::loadConfig82(int address) {
|
||||
ConfigObject82 config82;
|
||||
EEPROM.get(address, config82);
|
||||
@ -855,6 +885,7 @@ bool AmsConfiguration::save() {
|
||||
EEPROM.put(address, EEPROM_CHECK_SUM);
|
||||
address++;
|
||||
EEPROM.put(address, config);
|
||||
saveTempSensors();
|
||||
bool success = EEPROM.commit();
|
||||
EEPROM.end();
|
||||
|
||||
@ -862,6 +893,42 @@ bool AmsConfiguration::save() {
|
||||
return success;
|
||||
}
|
||||
|
||||
uint8_t AmsConfiguration::getTempSensorCount() {
|
||||
return tempSensorCount;
|
||||
}
|
||||
|
||||
TempSensorConfig* AmsConfiguration::getTempSensorConfig(uint8_t i) {
|
||||
return tempSensors[i];
|
||||
}
|
||||
|
||||
void AmsConfiguration::updateTempSensorConfig(uint8_t address[8], const char name[32], bool common) {
|
||||
bool found = false;
|
||||
for(int x = 0; x < tempSensorCount; x++) {
|
||||
TempSensorConfig *data = tempSensors[x];
|
||||
if(isSensorAddressEqual(data->address, address)) {
|
||||
found = true;
|
||||
strcpy(data->name, name);
|
||||
data->common = common;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
TempSensorConfig *data = new TempSensorConfig();
|
||||
memcpy(data->address, address, 8);
|
||||
strcpy(data->name, name);
|
||||
data->common = common;
|
||||
tempSensors[tempSensorCount] = data;
|
||||
tempSensorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
bool AmsConfiguration::isSensorAddressEqual(uint8_t a[8], uint8_t b[8]) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(a[i] != b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int AmsConfiguration::readString(int pAddress, char* pString[]) {
|
||||
int address = 0;
|
||||
byte length = EEPROM.read(pAddress + address);
|
||||
@ -969,6 +1036,8 @@ void AmsConfiguration::print(Print* debugger)
|
||||
debugger->printf("NTP server: %s\r\n", this->getNtpServer());
|
||||
debugger->printf("NTP DHCP: %s\r\n", this->isNtpDhcp() ? "Yes" : "No");
|
||||
}
|
||||
|
||||
debugger->printf("Temp sensor count: %i\r\n", this->getTempSensorCount());
|
||||
|
||||
debugger->println("-----------------------------------------------");
|
||||
}
|
||||
|
||||
@ -67,8 +67,6 @@ struct ConfigObject {
|
||||
char ntpServer[64];
|
||||
|
||||
uint8_t tempAnalogSensorPin;
|
||||
int8_t tempSensorInternal; // -128 = disabled, -1 = analog, 0-127 = digital sensor index
|
||||
uint8_t tempSensorCount;
|
||||
};
|
||||
|
||||
struct ConfigObject82 {
|
||||
@ -124,6 +122,12 @@ struct ConfigObject82 {
|
||||
uint16_t domoCL1IDX;
|
||||
};
|
||||
|
||||
struct TempSensorConfig {
|
||||
uint8_t address[8];
|
||||
char name[16];
|
||||
bool common;
|
||||
};
|
||||
|
||||
class AmsConfiguration {
|
||||
public:
|
||||
bool hasConfig();
|
||||
@ -285,6 +289,12 @@ public:
|
||||
bool isNtpChanged();
|
||||
void ackNtpChange();
|
||||
|
||||
uint8_t getTempSensorCount();
|
||||
TempSensorConfig* getTempSensorConfig(uint8_t i);
|
||||
void updateTempSensorConfig(uint8_t address[8], const char name[32], bool common);
|
||||
|
||||
bool isSensorAddressEqual(uint8_t a[8], uint8_t b[8]);
|
||||
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
@ -350,15 +360,20 @@ private:
|
||||
360, // Summertime offset (*10)
|
||||
"pool.ntp.org", // NTP server
|
||||
0xFF, // Analog temp sensor
|
||||
0xFF, // Internal temp sensor
|
||||
0, // Temp sensor count
|
||||
// 900 bytes
|
||||
// 894 bytes
|
||||
};
|
||||
bool wifiChanged, mqttChanged, meterChanged = true, domoChanged, ntpChanged;
|
||||
|
||||
const int EEPROM_SIZE = 904; // Config size + 4 bytes for config version
|
||||
uint8_t tempSensorCount = 0;
|
||||
TempSensorConfig* tempSensors[32];
|
||||
|
||||
const int EEPROM_SIZE = 1024 * 3;
|
||||
const int EEPROM_CHECK_SUM = 83; // Used to check if config is stored. Change if structure changes
|
||||
const int EEPROM_CONFIG_ADDRESS = 0;
|
||||
const int EEPROM_TEMP_CONFIG_ADDRESS = 2048;
|
||||
|
||||
void loadTempSensors();
|
||||
void saveTempSensors();
|
||||
|
||||
bool loadConfig81(int address);
|
||||
bool loadConfig82(int address);
|
||||
|
||||
@ -156,6 +156,14 @@ void setup() {
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t c = config.getTempSensorCount();
|
||||
for(int i = 0; i < c; i++) {
|
||||
TempSensorConfig* tsc = config.getTempSensorConfig(i);
|
||||
hw.confTempSensor(tsc->address, tsc->name, tsc->common);
|
||||
Debug.print("Sensor name: ");
|
||||
Debug.println(tsc->name);
|
||||
}
|
||||
|
||||
double vcc = hw.getVcc();
|
||||
|
||||
if (Debug.isActive(RemoteDebug::INFO)) {
|
||||
@ -269,7 +277,6 @@ bool longPressActive = false;
|
||||
bool wifiConnected = false;
|
||||
|
||||
unsigned long lastTemperatureRead = 0;
|
||||
double temperature = -127;
|
||||
|
||||
unsigned long lastRead = 0;
|
||||
unsigned long lastSuccessfulRead = 0;
|
||||
@ -306,8 +313,8 @@ void loop() {
|
||||
}
|
||||
}
|
||||
|
||||
if(now - lastTemperatureRead > 5000) {
|
||||
temperature = hw.getTemperature();
|
||||
if(now - lastTemperatureRead > 10000) {
|
||||
hw.updateTemperatures();
|
||||
lastTemperatureRead = now;
|
||||
}
|
||||
|
||||
@ -554,7 +561,7 @@ void readHanPort() {
|
||||
if(strlen(config.getMqttHost()) > 0 && strlen(config.getMqttPublishTopic()) > 0) {
|
||||
if(config.getMqttPayloadFormat() == 0) {
|
||||
StaticJsonDocument<512> json;
|
||||
hanToJson(json, data, hw, temperature, config.getMqttClientId());
|
||||
hanToJson(json, data, hw, hw.getTemperature(), config.getMqttClientId());
|
||||
if (Debug.isActive(RemoteDebug::INFO)) {
|
||||
debugI("Sending data to MQTT");
|
||||
if (Debug.isActive(RemoteDebug::DEBUG)) {
|
||||
@ -1012,7 +1019,7 @@ void sendSystemStatusToMqtt() {
|
||||
mqtt.publish(String(config.getMqttPublishTopic()) + "/vcc", String(vcc, 2));
|
||||
}
|
||||
mqtt.publish(String(config.getMqttPublishTopic()) + "/rssi", String(hw.getWifiRssi()));
|
||||
if(temperature != DEVICE_DISCONNECTED_C) {
|
||||
mqtt.publish(String(config.getMqttPublishTopic()) + "/temperature", String(temperature, 2));
|
||||
if(hw.getTemperature() != DEVICE_DISCONNECTED_C) {
|
||||
mqtt.publish(String(config.getMqttPublishTopic()) + "/temperature", String(hw.getTemperature(), 2));
|
||||
}
|
||||
}
|
||||
|
||||
100
src/HwTools.cpp
100
src/HwTools.cpp
@ -3,8 +3,8 @@
|
||||
void HwTools::setTempSensorPin(int tempSensorPin) {
|
||||
if(tempSensorPin != this->tempSensorPin) {
|
||||
this->tempSensorInit = false;
|
||||
if(tempSensor)
|
||||
delete tempSensor;
|
||||
if(sensorApi)
|
||||
delete sensorApi;
|
||||
if(oneWire)
|
||||
delete oneWire;
|
||||
if(tempSensorPin > 0 && tempSensorPin < 40) {
|
||||
@ -50,27 +50,99 @@ double HwTools::getVcc() {
|
||||
return vccOffset + (volts > 0.0 ? volts * vccMultiplier : 0.0);
|
||||
}
|
||||
|
||||
double HwTools::getTemperature() {
|
||||
void HwTools::confTempSensor(uint8_t address[8], const char name[32], bool common) {
|
||||
bool found = false;
|
||||
for(int x = 0; x < sensorCount; x++) {
|
||||
TempSensorData *data = tempSensors[x];
|
||||
if(isSensorAddressEqual(data->address, address)) {
|
||||
found = true;
|
||||
strcpy(data->name, name);
|
||||
data->common = common;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
TempSensorData *data = new TempSensorData();
|
||||
memcpy(data->address, address, 8);
|
||||
strcpy(data->name, name);
|
||||
data->common = common;
|
||||
data->lastRead = DEVICE_DISCONNECTED_C;
|
||||
data->lastValidRead = DEVICE_DISCONNECTED_C;
|
||||
tempSensors[sensorCount] = data;
|
||||
sensorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t HwTools::getTempSensorCount() {
|
||||
return sensorCount;
|
||||
}
|
||||
|
||||
TempSensorData* HwTools::getTempSensorData(uint8_t i) {
|
||||
return tempSensors[i];
|
||||
}
|
||||
|
||||
bool HwTools::updateTemperatures() {
|
||||
if(tempSensorPin != 0xFF) {
|
||||
if(!tempSensorInit) {
|
||||
oneWire = new OneWire(tempSensorPin);
|
||||
tempSensor = new DallasTemperature(this->oneWire);
|
||||
tempSensor->begin();
|
||||
sensorApi = new DallasTemperature(this->oneWire);
|
||||
sensorApi->begin();
|
||||
delay(50);
|
||||
tempSensor->requestTemperatures();
|
||||
hasTempSensor = tempSensor->getTempCByIndex(0) != DEVICE_DISCONNECTED_C;
|
||||
tempSensorInit = true;
|
||||
}
|
||||
|
||||
if(hasTempSensor) {
|
||||
tempSensor->requestTemperatures();
|
||||
return tempSensor->getTempCByIndex(0);
|
||||
} else {
|
||||
return DEVICE_DISCONNECTED_C;
|
||||
DeviceAddress addr;
|
||||
sensorApi->requestTemperatures();
|
||||
int c = sensorApi->getDeviceCount();
|
||||
for(int i = 0; i < c; i++) {
|
||||
bool found = false;
|
||||
sensorApi->getAddress(addr, i);
|
||||
float t = sensorApi->getTempC(addr);
|
||||
for(int x = 0; x < sensorCount; x++) {
|
||||
TempSensorData *data = tempSensors[x];
|
||||
if(isSensorAddressEqual(data->address, addr)) {
|
||||
found = true;
|
||||
data->lastRead = t;
|
||||
if(t > -85) {
|
||||
data->lastValidRead = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
TempSensorData *data = new TempSensorData();
|
||||
memcpy(data->address, addr, 8);
|
||||
data->common = true;
|
||||
data->lastRead = t;
|
||||
if(t > -85) {
|
||||
data->lastValidRead = t;
|
||||
}
|
||||
|
||||
tempSensors[sensorCount] = data;
|
||||
sensorCount++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HwTools::isSensorAddressEqual(uint8_t a[8], uint8_t b[8]) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(a[i] != b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
double HwTools::getTemperature() {
|
||||
uint8_t c = 0;
|
||||
double ret = 0;
|
||||
for(int x = 0; x < sensorCount; x++) {
|
||||
TempSensorData data = *tempSensors[x];
|
||||
if(data.common && data.lastValidRead > -85) {
|
||||
ret += data.lastValidRead;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
return DEVICE_DISCONNECTED_C;
|
||||
return c == 0 ? DEVICE_DISCONNECTED_C : ret/c;
|
||||
}
|
||||
|
||||
int HwTools::getWifiRssi() {
|
||||
|
||||
@ -18,6 +18,14 @@
|
||||
#define LED_BLUE 3
|
||||
#define LED_YELLOW 4
|
||||
|
||||
struct TempSensorData {
|
||||
uint8_t address[8];
|
||||
char name[32];
|
||||
bool common;
|
||||
float lastRead;
|
||||
float lastValidRead;
|
||||
};
|
||||
|
||||
class HwTools {
|
||||
public:
|
||||
void setTempSensorPin(int tempSensorPin);
|
||||
@ -25,7 +33,12 @@ public:
|
||||
void setVccOffset(double vccOffset);
|
||||
void setVccMultiplier(double vccMultiplier);
|
||||
double getVcc();
|
||||
void confTempSensor(uint8_t address[8], const char name[32], bool common);
|
||||
uint8_t getTempSensorCount();
|
||||
TempSensorData* getTempSensorData(uint8_t i);
|
||||
bool updateTemperatures();
|
||||
double getTemperature();
|
||||
double getTemperature(uint8_t address[8]);
|
||||
int getWifiRssi();
|
||||
void setLed(uint8_t ledPin, bool ledInverted);
|
||||
void setLedRgb(uint8_t ledPinRed, uint8_t ledPinGreen, uint8_t ledPinBlue, bool ledRgbInverted);
|
||||
@ -41,11 +54,15 @@ private:
|
||||
bool ledInverted, ledRgbInverted;
|
||||
double vccOffset = 0.0;
|
||||
double vccMultiplier = 1.0;
|
||||
bool tempSensorInit, hasTempSensor;
|
||||
|
||||
bool tempSensorInit;
|
||||
OneWire *oneWire;
|
||||
DallasTemperature *tempSensor;
|
||||
DallasTemperature *sensorApi;
|
||||
uint8_t sensorCount = 0;
|
||||
TempSensorData *tempSensors[32];
|
||||
|
||||
bool writeLedPin(uint8_t color, uint8_t state);
|
||||
bool isSensorAddressEqual(uint8_t a[8], uint8_t b[8]);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -22,6 +22,9 @@
|
||||
#include "root/upload_html.h"
|
||||
#include "root/delete_html.h"
|
||||
#include "root/reset_html.h"
|
||||
#include "root/temperature_head_html.h"
|
||||
#include "root/temperature_row_html.h"
|
||||
#include "root/temperature_foot_html.h"
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
@ -37,6 +40,7 @@ void AmsWebServer::setup(AmsConfiguration* config, MQTTClient* mqtt) {
|
||||
server.on("/", HTTP_GET, std::bind(&AmsWebServer::indexHtml, this));
|
||||
server.on("/", HTTP_POST, std::bind(&AmsWebServer::handleSetup, this));
|
||||
server.on("/application.js", HTTP_GET, std::bind(&AmsWebServer::applicationJs, this));
|
||||
server.on("/temperature", HTTP_GET, std::bind(&AmsWebServer::temperature, this));
|
||||
server.on("/config-meter", HTTP_GET, std::bind(&AmsWebServer::configMeterHtml, this));
|
||||
server.on("/config-wifi", HTTP_GET, std::bind(&AmsWebServer::configWifiHtml, this));
|
||||
server.on("/config-mqtt", HTTP_GET, std::bind(&AmsWebServer::configMqttHtml, this));
|
||||
@ -120,6 +124,36 @@ bool AmsWebServer::checkSecurity(byte level) {
|
||||
return access;
|
||||
}
|
||||
|
||||
void AmsWebServer::temperature() {
|
||||
printD("Serving /temperature.html over http...");
|
||||
|
||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
||||
server.sendHeader("Pragma", "no-cache");
|
||||
server.sendHeader("Expires", "-1");
|
||||
|
||||
String html;
|
||||
uint8_t c = hw->getTempSensorCount();
|
||||
for(int i = 0; i < c; i++) {
|
||||
TempSensorData* data = hw->getTempSensorData(i);
|
||||
|
||||
String row = String((const __FlashStringHelper*) TEMPERATURE_ROW_HTML);
|
||||
row.replace("${index}", String(i, DEC));
|
||||
row.replace("${address}", toHex(data->address));
|
||||
row.replace("${name}", data->name);
|
||||
row.replace("${common}", data->common ? "checked" : "");
|
||||
row.replace("${value}", String(data->lastRead, 1));
|
||||
|
||||
html += row;
|
||||
}
|
||||
|
||||
server.setContentLength(html.length() + HEAD_HTML_LEN + TEMPERATURE_HEAD_HTML_LEN + FOOT_HTML_LEN + TEMPERATURE_FOOT_HTML_LEN);
|
||||
server.send_P(200, "text/html", HEAD_HTML);
|
||||
server.sendContent_P(TEMPERATURE_HEAD_HTML);
|
||||
server.sendContent(html);
|
||||
server.sendContent_P(TEMPERATURE_FOOT_HTML);
|
||||
server.sendContent_P(FOOT_HTML);
|
||||
}
|
||||
|
||||
void AmsWebServer::indexHtml() {
|
||||
printD("Serving /index.html over http...");
|
||||
|
||||
@ -269,6 +303,26 @@ void AmsWebServer::configMeterHtml() {
|
||||
server.sendContent_P(FOOT_HTML);
|
||||
}
|
||||
|
||||
String AmsWebServer::toHex(uint8_t* in) {
|
||||
String hex;
|
||||
for(int i = 0; i < sizeof(in)*2; i++) {
|
||||
if(in[i] < 0x10) {
|
||||
hex += '0';
|
||||
}
|
||||
hex += String(in[i], HEX);
|
||||
}
|
||||
hex.toUpperCase();
|
||||
return hex;
|
||||
}
|
||||
|
||||
uint8_t* AmsWebServer::fromHex(String in, uint8_t size) {
|
||||
uint8_t ret[size];
|
||||
for(int i = 0; i < size*2; i += 2) {
|
||||
ret[i/2] = strtol(in.substring(i, i+2).c_str(), 0, 16);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AmsWebServer::configWifiHtml() {
|
||||
printD("Serving /config-wifi.html over http...");
|
||||
|
||||
@ -835,6 +889,16 @@ void AmsWebServer::handleSave() {
|
||||
config->setNtpServer(server.arg("ntpServer").c_str());
|
||||
}
|
||||
|
||||
if(server.hasArg("tempConfig") && server.arg("tempConfig") == "true") {
|
||||
for(int i = 0; i < 32; i++) {
|
||||
if(!server.hasArg("sensor" + String(i, DEC))) break;
|
||||
String address = server.arg("sensor" + String(i, DEC));
|
||||
String name = server.arg("sensor" + String(i, DEC) + "name");
|
||||
bool common = server.hasArg("sensor" + String(i, DEC) + "common") && server.arg("sensor" + String(i, DEC) + "common") == "true";
|
||||
config->updateTempSensorConfig(fromHex(address, 8), name.c_str(), common);
|
||||
}
|
||||
}
|
||||
|
||||
printI("Saving configuration now...");
|
||||
|
||||
if (debugger->isActive(RemoteDebug::DEBUG)) config->print(debugger);
|
||||
@ -854,6 +918,11 @@ void AmsWebServer::handleSave() {
|
||||
hw->setVccPin(config->getVccPin());
|
||||
hw->setVccOffset(config->getVccOffset());
|
||||
hw->setVccMultiplier(config->getVccMultiplier());
|
||||
uint8_t c = config->getTempSensorCount();
|
||||
for(int i = 0; i < c; i++) {
|
||||
TempSensorConfig* tsc = config->getTempSensorConfig(i);
|
||||
hw->confTempSensor(tsc->address, tsc->name, tsc->common);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printE("Error saving configuration");
|
||||
|
||||
@ -60,6 +60,7 @@ private:
|
||||
|
||||
void indexHtml();
|
||||
void applicationJs();
|
||||
void temperature();
|
||||
void configMeterHtml();
|
||||
void configWifiHtml();
|
||||
void configMqttHtml();
|
||||
@ -103,6 +104,9 @@ private:
|
||||
|
||||
void notFound();
|
||||
|
||||
String toHex(uint8_t* in);
|
||||
uint8_t* fromHex(String in, uint8_t size);
|
||||
|
||||
void printD(String fmt, ...);
|
||||
void printI(String fmt, ...);
|
||||
void printW(String fmt, ...);
|
||||
|
||||
11
web/temperature_foot.html
Normal file
11
web/temperature_foot.html
Normal file
@ -0,0 +1,11 @@
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="row form-group">
|
||||
<div class="col-6">
|
||||
<a href="/" class="btn btn-outline-secondary">Back</a>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
3
web/temperature_head.html
Normal file
3
web/temperature_head.html
Normal file
@ -0,0 +1,3 @@
|
||||
<form method="post" action="/save">
|
||||
<input type="hidden" name="tempConfig" value="true"/>
|
||||
<div class="my-3 p-3 bg-white rounded shadow">
|
||||
28
web/temperature_row.html
Normal file
28
web/temperature_row.html
Normal file
@ -0,0 +1,28 @@
|
||||
<input type="hidden" name="sensor${index}" value="${address}"/>
|
||||
<div class="row mb-3">
|
||||
<div class="col-xl-3 col-lg-4 col-sm-6">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Address</span>
|
||||
</div>
|
||||
<input name="sensor${index}address" type="text" class="form-control" value="${address}" maxlength="16" disabled/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-3 col-sm-6">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Name</span>
|
||||
</div>
|
||||
<input name="sensor${index}name" type="text" class="form-control" value="${name}" maxlength="32"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-3 col-sm-6">
|
||||
<div class="form-check">
|
||||
<input name="sensor${index}common" class="form-check-input" type="checkbox" value="true" id="sensor${index}common" ${common}>
|
||||
<label class="form-check-label" for="sensor${index}common">Include in average</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-2 col-lg-2 col-sm-6">
|
||||
${value} °C
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user