DS18S20 fix, sensors right align with 1 decimal, telegram counter 32 bit

This commit is contained in:
MichaelDvP
2020-08-30 14:27:11 +02:00
parent 76a394cc42
commit 8a98f7cac8
14 changed files with 74 additions and 70 deletions

View File

@@ -152,7 +152,7 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
<TableHead> <TableHead>
<TableRow> <TableRow>
<StyledTableCell>ID</StyledTableCell> <StyledTableCell>ID</StyledTableCell>
<StyledTableCell align="left">Temperature</StyledTableCell> <StyledTableCell align="right">Temperature</StyledTableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@@ -161,8 +161,8 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
<TableCell component="th" scope="row"> <TableCell component="th" scope="row">
{sensorData.id} {sensorData.id}
</TableCell> </TableCell>
<TableCell align="left"> <TableCell align="right">
{sensorData.temp}&deg;C {sensorData.temp.toFixed(1)}&deg;C
</TableCell> </TableCell>
</TableRow> </TableRow>
))} ))}
@@ -285,7 +285,7 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
<TableCell component="th" scope="row"> <TableCell component="th" scope="row">
{deviceData.name} {deviceData.name}
</TableCell> </TableCell>
<TableCell align="left"> <TableCell align="right">
{deviceData.value} {deviceData.value}
</TableCell> </TableCell>
</TableRow> </TableRow>

View File

@@ -100,18 +100,6 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
onChange={handleValueChange('tx_gpio')} onChange={handleValueChange('tx_gpio')}
margin="normal" margin="normal"
/> />
<TextValidator
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:40']}
errorMessages={['LED GPIO is required', "Must be a number", "Must be 0 or higher", "Max value is 255"]}
name="led_gpio"
label="LED GPIO pin (0=none)"
fullWidth
variant="outlined"
value={data.led_gpio}
type="number"
onChange={handleValueChange('led_gpio')}
margin="normal"
/>
<TextValidator <TextValidator
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:40']} validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:40']}
errorMessages={['Dallas GPIO is required', "Must be a number", "Must be 0 or higher", "Max value is 255"]} errorMessages={['Dallas GPIO is required', "Must be a number", "Must be 0 or higher", "Max value is 255"]}
@@ -124,6 +112,18 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
onChange={handleValueChange('dallas_gpio')} onChange={handleValueChange('dallas_gpio')}
margin="normal" margin="normal"
/> />
<TextValidator
validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:40']}
errorMessages={['LED GPIO is required', "Must be a number", "Must be 0 or higher", "Max value is 255"]}
name="led_gpio"
label="LED GPIO pin (0=none)"
fullWidth
variant="outlined"
value={data.led_gpio}
type="number"
onChange={handleValueChange('led_gpio')}
margin="normal"
/>
<BlockFormControlLabel <BlockFormControlLabel
control={ control={
<Checkbox <Checkbox
@@ -132,7 +132,7 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps)
value="hide_led" value="hide_led"
/> />
} }
label="Hide LED" label="Invert/Hide LED"
/> />
<BlockFormControlLabel <BlockFormControlLabel
control={ control={

View File

@@ -37,6 +37,10 @@ import {
import { EMSESPStatus } from "./EMSESPtypes"; import { EMSESPStatus } from "./EMSESPtypes";
function formatNumber(num: number) {
return new Intl.NumberFormat().format(num);
}
type EMSESPStatusFormProps = RestFormProps<EMSESPStatus> & WithTheme & WithWidthProps; type EMSESPStatusFormProps = RestFormProps<EMSESPStatus> & WithTheme & WithWidthProps;
const StyledTableCell = withStyles((theme: Theme) => const StyledTableCell = withStyles((theme: Theme) =>
@@ -75,7 +79,7 @@ class EMSESPStatusForm extends Component<EMSESPStatusFormProps> {
<TableHead> <TableHead>
<TableRow> <TableRow>
<StyledTableCell>Statistic</StyledTableCell> <StyledTableCell>Statistic</StyledTableCell>
<StyledTableCell align="center"># Telegrams</StyledTableCell> <StyledTableCell align="right"># Telegrams</StyledTableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@@ -83,25 +87,25 @@ class EMSESPStatusForm extends Component<EMSESPStatusFormProps> {
<TableCell> <TableCell>
(Rx) Received telegrams (Rx) Received telegrams
</TableCell> </TableCell>
<TableCell align="center">{data.rx_received}</TableCell> <TableCell align="right">{formatNumber(data.rx_received)}</TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell > <TableCell >
(Rx) Incomplete telegrams (Rx) Incomplete telegrams
</TableCell> </TableCell>
<TableCell align="center">{data.crc_errors}</TableCell> <TableCell align="right">{formatNumber(data.crc_errors)}</TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell > <TableCell >
(Tx) Successfully sent telegrams (Tx) Successfully sent telegrams
</TableCell> </TableCell>
<TableCell align="center">{data.tx_sent}</TableCell> <TableCell align="right">{formatNumber(data.tx_sent)}</TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell > <TableCell >
(Tx) Send Errors (Tx) Send Errors
</TableCell> </TableCell>
<TableCell align="center">{data.tx_errors}</TableCell> <TableCell align="right">{formatNumber(data.tx_errors)}</TableCell>
</TableRow> </TableRow>
</TableBody> </TableBody>
</Table> </Table>

View File

@@ -15,12 +15,12 @@ void APSettingsService::begin() {
} }
void APSettingsService::reconfigureAP() { void APSettingsService::reconfigureAP() {
_lastManaged = millis() - MANAGE_NETWORK_DELAY; _lastManaged = uuid::get_uptime() - MANAGE_NETWORK_DELAY;
_reconfigureAp = true; _reconfigureAp = true;
} }
void APSettingsService::loop() { void APSettingsService::loop() {
unsigned long currentMillis = millis(); unsigned long currentMillis = uuid::get_uptime();
unsigned long manageElapsed = (unsigned long)(currentMillis - _lastManaged); unsigned long manageElapsed = (unsigned long)(currentMillis - _lastManaged);
if (manageElapsed >= MANAGE_NETWORK_DELAY) { if (manageElapsed >= MANAGE_NETWORK_DELAY) {
_lastManaged = currentMillis; _lastManaged = currentMillis;

View File

@@ -7,6 +7,8 @@
#include <DNSServer.h> #include <DNSServer.h>
#include <IPAddress.h> #include <IPAddress.h>
#include <uuid/common.h>
#define MANAGE_NETWORK_DELAY 10000 #define MANAGE_NETWORK_DELAY 10000

View File

@@ -62,7 +62,7 @@ void MqttSettingsService::begin() {
} }
void MqttSettingsService::loop() { void MqttSettingsService::loop() {
if (_reconfigureMqtt || (_disconnectedAt && (unsigned long)(millis() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) { if (_reconfigureMqtt || (_disconnectedAt && (unsigned long)(uuid::get_uptime() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) {
// reconfigure MQTT client // reconfigure MQTT client
configureMqtt(); configureMqtt();
@@ -107,7 +107,7 @@ void MqttSettingsService::onMqttDisconnect(AsyncMqttClientDisconnectReason reaso
// Serial.print(F("Disconnected from MQTT reason: ")); // Serial.print(F("Disconnected from MQTT reason: "));
// Serial.println((uint8_t)reason); // Serial.println((uint8_t)reason);
_disconnectReason = reason; _disconnectReason = reason;
_disconnectedAt = millis(); _disconnectedAt = uuid::get_uptime();
} }
void MqttSettingsService::onConfigUpdated() { void MqttSettingsService::onConfigUpdated() {

View File

@@ -6,12 +6,13 @@
#include <FSPersistence.h> #include <FSPersistence.h>
#include <AsyncMqttClient.h> #include <AsyncMqttClient.h>
#include <ESPUtils.h> #include <ESPUtils.h>
#include <uuid/common.h>
#include "../../src/system.h" #include "../../src/system.h"
#include "../../src/mqtt.h" #include "../../src/mqtt.h"
#include "../../src/sensors.h" #include "../../src/sensors.h"
#define MQTT_RECONNECTION_DELAY 5000 #define MQTT_RECONNECTION_DELAY 1000
#define MQTT_SETTINGS_FILE "/config/mqttSettings.json" #define MQTT_SETTINGS_FILE "/config/mqttSettings.json"
#define MQTT_SETTINGS_SERVICE_PATH "/rest/mqttSettings" #define MQTT_SETTINGS_SERVICE_PATH "/rest/mqttSettings"

View File

@@ -33,7 +33,7 @@ void NTPStatus::ntpStatus(AsyncWebServerRequest* request) {
root["server"] = sntp_getservername(0); root["server"] = sntp_getservername(0);
// device uptime in seconds // device uptime in seconds
root["uptime"] = millis() / 1000; root["uptime"] = uuid::get_uptime() / 1000;
response->setLength(); response->setLength();
request->send(response); request->send(response);

View File

@@ -16,6 +16,8 @@
#include <AsyncJson.h> #include <AsyncJson.h>
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <SecurityManager.h> #include <SecurityManager.h>
#include <uuid/common.h>
#define MAX_NTP_STATUS_SIZE 1024 #define MAX_NTP_STATUS_SIZE 1024
#define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus" #define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus"

View File

@@ -286,7 +286,7 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) {
char valuestr[8] = {0}; // for formatting temp char valuestr[8] = {0}; // for formatting temp
shell.printfln(F("Dallas temperature sensors:")); shell.printfln(F("Dallas temperature sensors:"));
for (const auto & device : sensor_devices()) { for (const auto & device : sensor_devices()) {
shell.printfln(F(" ID: %s, Temperature: %s°C"), device.to_string().c_str(), Helpers::render_value(valuestr, device.temperature_c, 2)); shell.printfln(F(" ID: %s, Temperature: %s°C"), device.to_string().c_str(), Helpers::render_value(valuestr, device.temperature_c, 1));
} }
shell.println(); shell.println();
} }

View File

@@ -183,27 +183,27 @@ float Sensors::get_temperature_c(const uint8_t addr[]) {
int16_t raw_value = ((int16_t)scratchpad[SCRATCHPAD_TEMP_MSB] << 8) | scratchpad[SCRATCHPAD_TEMP_LSB]; int16_t raw_value = ((int16_t)scratchpad[SCRATCHPAD_TEMP_MSB] << 8) | scratchpad[SCRATCHPAD_TEMP_LSB];
// Adjust based on device resolution if (addr[0] == TYPE_DS18S20) {
int resolution = 9 + ((scratchpad[SCRATCHPAD_CONFIG] >> 5) & 0x3); raw_value = (raw_value << 3) + 12 - scratchpad[SCRATCHPAD_CNT_REM];
switch (resolution) { } else {
case 9: // Adjust based on device resolution
raw_value &= ~0x1; int resolution = 9 + ((scratchpad[SCRATCHPAD_CONFIG] >> 5) & 0x3);
break; switch (resolution) {
case 9:
case 10: raw_value &= ~0x7;
raw_value &= ~0x3; break;
break; case 10:
raw_value &= ~0x3;
case 11: break;
raw_value &= ~0x7; case 11:
break; raw_value &= ~0x1;
break;
case 12: case 12:
break; break;
}
} }
uint32_t raw = (raw_value * 625 + 500) / 1000; // round to 0.1
uint32_t raw = (raw_value * 625) / 100; // round to 0.01 return (float)raw / 10;
return (float)raw / 100;
#else #else
return NAN; return NAN;
#endif #endif
@@ -254,7 +254,7 @@ void Sensors::publish_values() {
StaticJsonDocument<100> doc; StaticJsonDocument<100> doc;
for (const auto & device : devices_) { for (const auto & device : devices_) {
char s[7]; // sensorrange -55.00 to 125.00 char s[7]; // sensorrange -55.00 to 125.00
doc["temp"] = Helpers::render_value(s, device.temperature_c, 2); doc["temp"] = Helpers::render_value(s, device.temperature_c, 1);
char topic[60]; // sensors{1-n} char topic[60]; // sensors{1-n}
strlcpy(topic, "sensor_", 50); // create topic, e.g. home/ems-esp/sensor_28-EA41-9497-0E03-5F strlcpy(topic, "sensor_", 50); // create topic, e.g. home/ems-esp/sensor_28-EA41-9497-0E03-5F
strlcat(topic, device.to_string().c_str(), 60); strlcat(topic, device.to_string().c_str(), 60);
@@ -264,20 +264,13 @@ void Sensors::publish_values() {
return; return;
} }
// const size_t capacity = num_devices * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(num_devices);
DynamicJsonDocument doc(100 * num_devices); DynamicJsonDocument doc(100 * num_devices);
uint8_t i = 1; // sensor count uint8_t i = 1; // sensor count
for (const auto & device : devices_) { for (const auto & device : devices_) {
char s[7]; char s[7];
if (mqtt_format_ == MQTT_format::CUSTOM) { if (mqtt_format_ == MQTT_format::CUSTOM) {
doc[device.to_string()] = Helpers::render_value(s, device.temperature_c, 2); doc[device.to_string()] = Helpers::render_value(s, device.temperature_c, 1);
} else if (mqtt_format_ == MQTT_format::SINGLE) {
doc["id"] = device.to_string();
doc["temp"] = Helpers::render_value(s, device.temperature_c, 2);
std::string topic(100, '\0');
snprintf_P(&topic[0], 50, PSTR("sensor%d"), i);
Mqtt::publish(topic, doc);
} else if ((mqtt_format_ == MQTT_format::NESTED) || (mqtt_format_ == MQTT_format::HA)) { } else if ((mqtt_format_ == MQTT_format::NESTED) || (mqtt_format_ == MQTT_format::HA)) {
// e.g. {"sensor1":{"id":"28-EA41-9497-0E03-5F","temp":"23.30"},"sensor2":{"id":"28-233D-9497-0C03-8B","temp":"24.0"}} // e.g. {"sensor1":{"id":"28-EA41-9497-0E03-5F","temp":"23.30"},"sensor2":{"id":"28-233D-9497-0C03-8B","temp":"24.0"}}
char sensorID[10]; // sensor{1-n} char sensorID[10]; // sensor{1-n}
@@ -285,7 +278,7 @@ void Sensors::publish_values() {
strlcat(sensorID, Helpers::itoa(s, i), 10); strlcat(sensorID, Helpers::itoa(s, i), 10);
JsonObject dataSensor = doc.createNestedObject(sensorID); JsonObject dataSensor = doc.createNestedObject(sensorID);
dataSensor["id"] = device.to_string(); dataSensor["id"] = device.to_string();
dataSensor["temp"] = Helpers::render_value(s, device.temperature_c, 2); dataSensor["temp"] = Helpers::render_value(s, device.temperature_c, 1);
} }
// special for HA // special for HA

View File

@@ -74,12 +74,13 @@ class Sensors {
static constexpr size_t SCRATCHPAD_TEMP_MSB = 1; static constexpr size_t SCRATCHPAD_TEMP_MSB = 1;
static constexpr size_t SCRATCHPAD_TEMP_LSB = 0; static constexpr size_t SCRATCHPAD_TEMP_LSB = 0;
static constexpr size_t SCRATCHPAD_CONFIG = 4; static constexpr size_t SCRATCHPAD_CONFIG = 4;
static constexpr size_t SCRATCHPAD_CNT_REM = 6;
// dallas chips // dallas chips
static constexpr uint8_t TYPE_DS18B20 = 0x28; static constexpr uint8_t TYPE_DS18B20 = 0x28;
static constexpr uint8_t TYPE_DS18S20 = 0x10; static constexpr uint8_t TYPE_DS18S20 = 0x10;
static constexpr uint8_t TYPE_DS1822 = 0x22; static constexpr uint8_t TYPE_DS1822 = 0x22;
static constexpr uint8_t TYPE_DS1825 = 0x3B; static constexpr uint8_t TYPE_DS1825 = 0x3B; // also DS1826
static constexpr uint32_t READ_INTERVAL_MS = 5000; // 5 seconds static constexpr uint32_t READ_INTERVAL_MS = 5000; // 5 seconds
static constexpr uint32_t CONVERSION_MS = 1000; // 1 seconds static constexpr uint32_t CONVERSION_MS = 1000; // 1 seconds

View File

@@ -219,6 +219,7 @@ void RxService::add(uint8_t * data, uint8_t length) {
// check if queue is full, if so remove top item to make space // check if queue is full, if so remove top item to make space
if (rx_telegrams_.size() >= MAX_RX_TELEGRAMS) { if (rx_telegrams_.size() >= MAX_RX_TELEGRAMS) {
rx_telegrams_.pop_front(); rx_telegrams_.pop_front();
increment_telegram_error_count();
} }
rx_telegrams_.emplace_back(rx_telegram_id_++, std::move(telegram)); // add to queue rx_telegrams_.emplace_back(rx_telegram_id_++, std::move(telegram)); // add to queue

View File

@@ -201,7 +201,7 @@ class RxService : public EMSbus {
void loop(); void loop();
void add(uint8_t * data, uint8_t length); void add(uint8_t * data, uint8_t length);
uint16_t telegram_count() const { uint32_t telegram_count() const {
return telegram_count_; return telegram_count_;
} }
@@ -209,7 +209,7 @@ class RxService : public EMSbus {
telegram_count_++; telegram_count_++;
} }
uint16_t telegram_error_count() const { uint32_t telegram_error_count() const {
return telegram_error_count_; return telegram_error_count_;
} }
@@ -235,8 +235,8 @@ class RxService : public EMSbus {
private: private:
uint8_t rx_telegram_id_ = 0; // queue counter uint8_t rx_telegram_id_ = 0; // queue counter
uint16_t telegram_count_ = 0; // # Rx received uint32_t telegram_count_ = 0; // # Rx received
uint16_t telegram_error_count_ = 0; // # Rx CRC errors uint32_t telegram_error_count_ = 0; // # Rx CRC errors
std::shared_ptr<const Telegram> rx_telegram; // the incoming Rx telegram std::shared_ptr<const Telegram> rx_telegram; // the incoming Rx telegram
std::list<QueuedRxTelegram> rx_telegrams_; // the Rx Queue std::list<QueuedRxTelegram> rx_telegrams_; // the Rx Queue
@@ -288,7 +288,7 @@ class TxService : public EMSbus {
telegram_last_post_send_query_ = type_id; telegram_last_post_send_query_ = type_id;
} }
uint16_t telegram_read_count() const { uint32_t telegram_read_count() const {
return telegram_read_count_; return telegram_read_count_;
} }
@@ -300,7 +300,7 @@ class TxService : public EMSbus {
telegram_read_count_++; telegram_read_count_++;
} }
uint16_t telegram_fail_count() const { uint32_t telegram_fail_count() const {
return telegram_fail_count_; return telegram_fail_count_;
} }
@@ -312,7 +312,7 @@ class TxService : public EMSbus {
telegram_fail_count_++; telegram_fail_count_++;
} }
uint16_t telegram_write_count() const { uint32_t telegram_write_count() const {
return telegram_write_count_; return telegram_write_count_;
} }
@@ -355,9 +355,9 @@ class TxService : public EMSbus {
private: private:
std::list<QueuedTxTelegram> tx_telegrams_; // the Tx queue std::list<QueuedTxTelegram> tx_telegrams_; // the Tx queue
uint16_t telegram_read_count_ = 0; // # Tx successful reads uint32_t telegram_read_count_ = 0; // # Tx successful reads
uint16_t telegram_write_count_ = 0; // # Tx successful writes uint32_t telegram_write_count_ = 0; // # Tx successful writes
uint16_t telegram_fail_count_ = 0; // # Tx unsuccessful transmits uint32_t telegram_fail_count_ = 0; // # Tx unsuccessful transmits
std::shared_ptr<Telegram> telegram_last_; std::shared_ptr<Telegram> telegram_last_;
uint16_t telegram_last_post_send_query_; // which type ID to query after a successful send, to read back the values just written uint16_t telegram_last_post_send_query_; // which type ID to query after a successful send, to read back the values just written