mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
@@ -1,9 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
# [3.7.0]
|
||||
# [3.6.1]
|
||||
|
||||
## **IMPORTANT! BREAKING CHANGES**
|
||||
|
||||
- shower_data MQTT topic shows duration is seconds (was previously an English string)
|
||||
|
||||
## Added
|
||||
|
||||
- rssi in Network Status Page
|
||||
@@ -15,3 +17,4 @@
|
||||
## Changed
|
||||
|
||||
- mqtt free mem check 60k
|
||||
- small cosmetic changes to Searching in Customization web page
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"@prefresh/vite": "^2.4.1",
|
||||
"@table-library/react-table-library": "4.1.7",
|
||||
"@types/lodash-es": "^4.17.9",
|
||||
"@types/node": "^20.5.7",
|
||||
"@types/node": "^20.5.8",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
|
||||
@@ -86,7 +86,7 @@ const SettingsCustomization: FC = () => {
|
||||
|
||||
const entities_theme = useTheme({
|
||||
Table: `
|
||||
--data-table-library_grid-template-columns: 150px repeat(1, minmax(80px, 1fr)) 45px minmax(45px, auto) minmax(120px, auto);
|
||||
--data-table-library_grid-template-columns: 156px repeat(1, minmax(80px, 1fr)) 45px minmax(45px, auto) minmax(120px, auto);
|
||||
`,
|
||||
BaseRow: `
|
||||
font-size: 14px;
|
||||
@@ -192,17 +192,9 @@ const SettingsCustomization: FC = () => {
|
||||
return value;
|
||||
}
|
||||
|
||||
function formatName(de: DeviceEntity) {
|
||||
return (
|
||||
<>
|
||||
{de.n && (de.n[0] === '!' ? LL.COMMAND(1) + ': ' + de.n.slice(1) : de.cn && de.cn !== '' ? de.cn : de.n) + ' '}(
|
||||
<Link target="_blank" href={APIURL + devices?.devices[selectedDevice].tn + '/' + de.id}>
|
||||
{de.id}
|
||||
</Link>
|
||||
)
|
||||
</>
|
||||
);
|
||||
}
|
||||
const formatName = (de: DeviceEntity, withShortname: boolean) =>
|
||||
(de.n && de.n[0] === '!' ? LL.COMMAND(1) + ': ' + de.n.slice(1) : de.cn && de.cn !== '' ? de.cn : de.n) +
|
||||
(withShortname ? ' ' + de.id : '');
|
||||
|
||||
const getMaskNumber = (newMask: string[]) => {
|
||||
let new_mask = 0;
|
||||
@@ -232,10 +224,13 @@ const SettingsCustomization: FC = () => {
|
||||
return new_masks;
|
||||
};
|
||||
|
||||
const filter_entity = (de: DeviceEntity) =>
|
||||
(de.m & selectedFilters || !selectedFilters) && formatName(de, true).includes(search.toLocaleLowerCase());
|
||||
|
||||
const maskDisabled = (set: boolean) => {
|
||||
setDeviceEntities(
|
||||
deviceEntities.map(function (de) {
|
||||
if ((de.m & selectedFilters || !selectedFilters) && de.id.toLowerCase().includes(search.toLowerCase())) {
|
||||
if (filter_entity(de)) {
|
||||
return {
|
||||
...de,
|
||||
m: set
|
||||
@@ -353,7 +348,7 @@ const SettingsCustomization: FC = () => {
|
||||
margin="normal"
|
||||
select
|
||||
>
|
||||
<MenuItem disabled key={0} value={-1}>
|
||||
<MenuItem disabled key={-1} value={-1}>
|
||||
{LL.SELECT_DEVICE()}...
|
||||
</MenuItem>
|
||||
{devices.devices.map((device: DeviceShort, index) => (
|
||||
@@ -370,9 +365,7 @@ const SettingsCustomization: FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const shown_data = deviceEntities.filter(
|
||||
(de) => (de.m & selectedFilters || !selectedFilters) && de.id.toLowerCase().includes(search.toLowerCase())
|
||||
);
|
||||
const shown_data = deviceEntities.filter((de) => filter_entity(de));
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -470,7 +463,13 @@ const SettingsCustomization: FC = () => {
|
||||
<Cell stiff>
|
||||
<EntityMaskToggle onUpdate={updateDeviceEntity} de={de} />
|
||||
</Cell>
|
||||
<Cell>{formatName(de)}</Cell>
|
||||
<Cell>
|
||||
{formatName(de, false)} (
|
||||
<Link target="_blank" href={APIURL + devices?.devices[selectedDevice].tn + '/' + de.id}>
|
||||
{de.id}
|
||||
</Link>
|
||||
)
|
||||
</Cell>
|
||||
<Cell>{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.mi)}</Cell>
|
||||
<Cell>{!(de.m & DeviceEntityMask.DV_READONLY) && formatValue(de.ma)}</Cell>
|
||||
<Cell>{formatValue(de.v)}</Cell>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import DoneIcon from '@mui/icons-material/Done';
|
||||
|
||||
import {
|
||||
@@ -67,15 +68,34 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
|
||||
<Dialog sx={dialogStyle} open={open} onClose={close}>
|
||||
<DialogTitle>{LL.EDIT() + ' ' + LL.ENTITY()}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<Box color="warning.main">
|
||||
<Typography variant="body2">{editItem.id}</Typography>
|
||||
</Box>
|
||||
<Box color="warning.main" mt={1} mb={2}>
|
||||
<Typography variant="body2">
|
||||
{LL.DEFAULT(1) + ' ' + LL.ENTITY_NAME(1)}: {editItem.n}
|
||||
<Grid container direction="row">
|
||||
<Typography variant="body2" color="warning.main">
|
||||
{LL.ENTITY() + ' ID'}:
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box mb={3}>
|
||||
<Typography variant="body2">{editItem.id}</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid container direction="row">
|
||||
<Typography variant="body2" color="warning.main">
|
||||
{LL.DEFAULT(1) + ' ' + LL.ENTITY_NAME(1)}:
|
||||
</Typography>
|
||||
<Typography variant="body2">{editItem.n}</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid container direction="row">
|
||||
<Typography variant="body2" color="warning.main">
|
||||
{LL.WRITEABLE()}:
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
{editItem.w ? (
|
||||
<DoneIcon color="success" sx={{ fontSize: 16 }} />
|
||||
) : (
|
||||
<CloseIcon color="error" sx={{ fontSize: 16 }} />
|
||||
)}
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Box mt={1} mb={2}>
|
||||
<EntityMaskToggle onUpdate={updateDeviceEntity} de={editItem} />
|
||||
</Box>
|
||||
<Grid container spacing={1}>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||
import CircleIcon from '@mui/icons-material/Circle';
|
||||
import WarningIcon from '@mui/icons-material/Warning';
|
||||
|
||||
import { Box, Typography, Divider, Stack, Button } from '@mui/material';
|
||||
@@ -216,7 +216,11 @@ const SettingsScheduler: FC = () => {
|
||||
{tableList.map((si: ScheduleItem) => (
|
||||
<Row key={si.id} item={si} onClick={() => editScheduleItem(si)}>
|
||||
<Cell stiff>
|
||||
{si.active && <CheckCircleIcon sx={{ color: '#79D200', fontSize: 16, verticalAlign: 'middle' }} />}
|
||||
{si.active ? (
|
||||
<CircleIcon color="success" sx={{ fontSize: 16, verticalAlign: 'middle' }} />
|
||||
) : (
|
||||
<CircleIcon color="error" sx={{ fontSize: 16, verticalAlign: 'middle' }} />
|
||||
)}
|
||||
</Cell>
|
||||
<Cell stiff>
|
||||
<Stack spacing={1} direction="row">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
||||
import DoneIcon from '@mui/icons-material/Done';
|
||||
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
|
||||
|
||||
@@ -184,11 +183,6 @@ const SettingsSchedulerDialog = ({
|
||||
control={<Checkbox checked={editItem.active} onChange={updateFormValue} name="active" />}
|
||||
label={LL.ACTIVE()}
|
||||
/>
|
||||
{editItem.active && (
|
||||
<Grid item sx={{ mt: 1 }}>
|
||||
<CheckCircleIcon sx={{ color: '#79D200', fontSize: 16, verticalAlign: 'middle' }} />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid container>
|
||||
<TextField
|
||||
|
||||
@@ -1355,10 +1355,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^20.5.7":
|
||||
version: 20.5.7
|
||||
resolution: "@types/node@npm:20.5.7"
|
||||
checksum: e5bce3d38478f2a135e254e910f40f844d379dbc8d5576ec6532122297c435f9c05e01f585c38fb9a83e21bde2652cc266b6aa98e45c8b5e51cc5b11a4f64cf0
|
||||
"@types/node@npm:^20.5.8":
|
||||
version: 20.5.8
|
||||
resolution: "@types/node@npm:20.5.8"
|
||||
checksum: 5d4af299b4499c4658d5fed3475ad1039828c5a8a44cd15494d45d8d1097965b59246f140af43a9e94277007082e8d04bc4f7771a4b97a8292ffd7442240cffd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1587,7 +1587,7 @@ __metadata:
|
||||
"@table-library/react-table-library": 4.1.7
|
||||
"@types/babel__core": ^7
|
||||
"@types/lodash-es": ^4.17.9
|
||||
"@types/node": ^20.5.7
|
||||
"@types/node": ^20.5.8
|
||||
"@types/react": ^18.2.21
|
||||
"@types/react-dom": ^18.2.7
|
||||
"@types/react-router-dom": ^5.3.3
|
||||
|
||||
@@ -260,7 +260,7 @@ void AnalogSensor::measure() {
|
||||
for (auto & sensor : sensors_) {
|
||||
if (sensor.type() == AnalogType::DIGITAL_IN || sensor.type() == AnalogType::COUNTER || sensor.type() == AnalogType::TIMER
|
||||
|| sensor.type() == AnalogType::RATE) {
|
||||
auto old_value = sensor.value(); // remember current value before reading
|
||||
auto old_value = sensor.value(); // remember current value before reading
|
||||
auto current_reading = digitalRead(sensor.gpio());
|
||||
if (sensor.poll_ != current_reading) { // check for pinchange
|
||||
sensor.polltime_ = uuid::get_uptime(); // remember time of pinchange
|
||||
@@ -274,7 +274,7 @@ void AnalogSensor::measure() {
|
||||
} else if (!sensor.poll_) { // falling edge
|
||||
if (sensor.type() == AnalogType::COUNTER) {
|
||||
sensor.set_value(old_value + sensor.factor());
|
||||
} else if (sensor.type() == AnalogType::RATE) { // dafault uom: Hz (1/sec) with factor 1
|
||||
} else if (sensor.type() == AnalogType::RATE) { // dafault uom: Hz (1/sec) with factor 1
|
||||
sensor.set_value(sensor.factor() * 1000 / (sensor.polltime_ - sensor.last_polltime_));
|
||||
} else if (sensor.type() == AnalogType::TIMER) { // default seconds with factor 1
|
||||
sensor.set_value(sensor.factor() * (sensor.polltime_ - sensor.last_polltime_) / 1000);
|
||||
@@ -685,7 +685,7 @@ bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject
|
||||
dataSensor["value"] = sensor.value();
|
||||
} else if (id == 0) { // output values command
|
||||
output[sensor.name()] = sensor.value();
|
||||
} else { // if someone wants gpio numbers
|
||||
} else { // if someone wants gpio numbers
|
||||
char gpio_str[9];
|
||||
snprintf(gpio_str, sizeof(gpio_str), "gpio_%02d", sensor.gpio());
|
||||
output[gpio_str] = sensor.value();
|
||||
|
||||
@@ -56,7 +56,7 @@ class Command {
|
||||
struct CmdFunction {
|
||||
uint8_t device_type_; // DeviceType::
|
||||
uint8_t device_id_;
|
||||
uint8_t flags_; // mqtt flags for command subscriptions
|
||||
uint8_t flags_; // mqtt flags for command subscriptions
|
||||
const char * cmd_;
|
||||
cmd_function_p cmdfunction_;
|
||||
cmd_json_function_p cmdfunction_json_;
|
||||
|
||||
@@ -87,9 +87,9 @@ class Boiler : public EMSdevice {
|
||||
uint32_t wwWorkM_; // DHW minutes
|
||||
int8_t wwHystOn_;
|
||||
int8_t wwHystOff_;
|
||||
uint8_t wwTapActivated_; // maintenance-mode to switch DHW off
|
||||
uint16_t wwMixerTemp_; // mixing temperature
|
||||
uint16_t wwCylMiddleTemp_; // Cyl middle temperature (TS3)
|
||||
uint8_t wwTapActivated_; // maintenance-mode to switch DHW off
|
||||
uint16_t wwMixerTemp_; // mixing temperature
|
||||
uint16_t wwCylMiddleTemp_; // Cyl middle temperature (TS3)
|
||||
uint16_t wwSolarTemp_;
|
||||
uint8_t wwAlternatingOper_; // alternating operation on/off
|
||||
uint8_t wwAltOpPrioHeat_; // alternating operation, prioritize heat time
|
||||
|
||||
@@ -170,7 +170,7 @@ void Mixer::process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> teleg
|
||||
void Mixer::process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, flowTempHc_, 0); // is * 10
|
||||
has_bitupdate(telegram, pumpStatus_, 2, 0);
|
||||
has_update(telegram, status_, 11); // temp status
|
||||
has_update(telegram, status_, 11); // temp status
|
||||
}
|
||||
|
||||
// Mixer IPM - 0x010C
|
||||
@@ -220,7 +220,7 @@ void Mixer::process_MMStatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, flowTempHc_, 1); // is * 10
|
||||
has_bitupdate(telegram, pumpStatus_, 3, 2); // is 0 or 0x64 (100%), check only bit 2
|
||||
has_update(telegram, flowSetTemp_, 0);
|
||||
has_update(telegram, status_, 4); // valve status -100 to 100
|
||||
has_update(telegram, status_, 4); // valve status -100 to 100
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -685,9 +685,9 @@ void Solar::process_SM100Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, cylBottomTemp2_, 16); // is *10 - TS5: Temperature sensor 2 cylinder, bottom, or swimming pool
|
||||
has_update(telegram, heatExchangerTemp_, 20); // is *10 - TS6: Heat exchanger temperature sensor
|
||||
|
||||
has_update(telegram, collector2Temp_, 6); // is *10 - TS7: Temperature sensor for collector array 2
|
||||
has_update(telegram, cylMiddleTemp_, 8); // is *10 - TS14: cylinder middle temperature
|
||||
has_update(telegram, retHeatAssist_, 10); // is *10 - TS15: return temperature heating assistance
|
||||
has_update(telegram, collector2Temp_, 6); // is *10 - TS7: Temperature sensor for collector array 2
|
||||
has_update(telegram, cylMiddleTemp_, 8); // is *10 - TS14: cylinder middle temperature
|
||||
has_update(telegram, retHeatAssist_, 10); // is *10 - TS15: return temperature heating assistance
|
||||
}
|
||||
|
||||
// SM100wwTemperature - 0x07D6
|
||||
@@ -749,8 +749,8 @@ void Solar::process_SM100Monitor2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(heatCntFlowTemp_, 0)); // is *10
|
||||
has_update(telegram->read_value(heatCntRetTemp_, 2)); // is *10
|
||||
has_update(telegram->read_value(heatCnt_, 12));
|
||||
has_update(telegram->read_value(swapRetTemp_, 6)); // is *10
|
||||
has_update(telegram->read_value(swapFlowTemp_, 8)); // is *10
|
||||
has_update(telegram->read_value(swapRetTemp_, 6)); // is *10
|
||||
has_update(telegram->read_value(swapFlowTemp_, 8)); // is *10
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
@@ -879,7 +879,7 @@ void Solar::process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram)
|
||||
has_update(telegram, collectorTemp_, 4); // Collector Temperature
|
||||
has_update(telegram, cylBottomTemp_, 6); // Temperature Bottom of Solar Boiler cyl
|
||||
uint16_t Wh = energyLastHour_ / 10;
|
||||
telegram->read_value(Wh, 2); // Solar Energy produced in last hour only ushort, is not * 10
|
||||
telegram->read_value(Wh, 2); // Solar Energy produced in last hour only ushort, is not * 10
|
||||
if (energyLastHour_ != Wh * 10) {
|
||||
energyLastHour_ = Wh * 10;
|
||||
has_update(&energyLastHour_);
|
||||
|
||||
@@ -58,9 +58,9 @@ class Solar : public EMSdevice {
|
||||
uint32_t energyLastHour_;
|
||||
uint32_t energyToday_;
|
||||
uint32_t energyTotal_;
|
||||
uint32_t pumpWorkTime_; // Total solar pump operating time
|
||||
uint32_t pump2WorkTime_; // Total solar pump 2 operating time
|
||||
uint32_t m1WorkTime_; // differential control work time
|
||||
uint32_t pumpWorkTime_; // Total solar pump operating time
|
||||
uint32_t pump2WorkTime_; // Total solar pump 2 operating time
|
||||
uint32_t m1WorkTime_; // differential control work time
|
||||
uint8_t cylHeated_;
|
||||
uint8_t collectorShutdown_; // Collector shutdown on/off
|
||||
|
||||
|
||||
@@ -661,8 +661,8 @@ void Thermostat::process_RC20Set_2(std::shared_ptr<const Telegram> telegram) {
|
||||
return;
|
||||
}
|
||||
has_update(telegram, hc->heatingtype, 0);
|
||||
has_update(telegram, hc->nighttemp, 1); // is * 2,
|
||||
has_update(telegram, hc->daytemp, 2); // is * 2,
|
||||
has_update(telegram, hc->nighttemp, 1); // is * 2,
|
||||
has_update(telegram, hc->daytemp, 2); // is * 2,
|
||||
has_update(telegram, hc->mode, 3);
|
||||
has_enumupdate(telegram, hc->program, 11, 1); // 1 .. 9 predefined programs
|
||||
has_update(telegram, hc->tempautotemp, 13);
|
||||
@@ -798,8 +798,8 @@ void Thermostat::process_RC35wwSettings(std::shared_ptr<const Telegram> telegram
|
||||
has_update(telegram, wwDisinfecting_, 4); // 0-off, 0xFF on
|
||||
has_update(telegram, wwDisinfectDay_, 5); // 0-6 Day of week, 7 every day
|
||||
has_update(telegram, wwDisinfectHour_, 6);
|
||||
has_update(telegram, wwMaxTemp_, 8); // Limiter 60 degrees
|
||||
has_update(telegram, wwOneTimeKey_, 9); // 0-off, 0xFF on
|
||||
has_update(telegram, wwMaxTemp_, 8); // Limiter 60 degrees
|
||||
has_update(telegram, wwOneTimeKey_, 9); // 0-off, 0xFF on
|
||||
}
|
||||
|
||||
// Settings WW 0x3A - RC30
|
||||
@@ -951,7 +951,7 @@ void Thermostat::process_RC300Monitor(std::shared_ptr<const Telegram> telegram)
|
||||
return;
|
||||
}
|
||||
|
||||
has_update(telegram, hc->roomTemp, 0); // is * 10
|
||||
has_update(telegram, hc->roomTemp, 0); // is * 10
|
||||
has_bitupdate(telegram, hc->modetype, 10, 1);
|
||||
has_bitupdate(telegram, hc->mode, 10, 0); // bit 1, mode (auto=1 or manual=0)
|
||||
|
||||
@@ -1013,8 +1013,8 @@ void Thermostat::process_RC300Set(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
has_update(hc->tempautotemp, tat);
|
||||
|
||||
has_update(telegram, hc->manualtemp, 10); // is * 2
|
||||
has_enumupdate(telegram, hc->program, 11, 1); // timer program 1 or 2
|
||||
has_update(telegram, hc->manualtemp, 10); // is * 2
|
||||
has_enumupdate(telegram, hc->program, 11, 1); // timer program 1 or 2
|
||||
|
||||
has_enumupdate(telegram, hc->reducemode, 5, 1); // 1-outdoor temp threshold, 2-room temp threshold, 3-reduced mode
|
||||
has_update(telegram, hc->reducetemp, 9);
|
||||
@@ -1097,7 +1097,7 @@ void Thermostat::process_RC300WWtemp(std::shared_ptr<const Telegram> telegram) {
|
||||
// RC300WWmode(0x2F5), data: 01 FF 04 00 00 00 08 05 00 08 04 00 00 00 00 00 00 00 00 00 01
|
||||
void Thermostat::process_RC300WWmode(std::shared_ptr<const Telegram> telegram) {
|
||||
// circulation pump see: https://github.com/Th3M3/buderus_ems-wiki/blob/master/Einstellungen%20der%20Bedieneinheit%20RC310.md
|
||||
has_update(telegram, wwCircPump_, 1); // FF=off, 0=on ?
|
||||
has_update(telegram, wwCircPump_, 1); // FF=off, 0=on ?
|
||||
|
||||
has_update(telegram, wwMode_, 2); // 0=off, 1=low, 2=high, 3=auto, 4=own prog
|
||||
has_update(telegram, wwCircMode_, 3); // 0=off, 1=on, 2=auto, 4=own?
|
||||
@@ -1207,11 +1207,11 @@ void Thermostat::process_RC30Set(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, mixingvalves_, 17); // Number of Mixing Valves: (0x00=0, 0x01=1, 0x02=2)
|
||||
has_update(telegram, brightness_, 18); // Screen brightness 0F=dark F1=light
|
||||
has_update(telegram, hc->mode, 23);
|
||||
has_update(telegram, hc->nofrosttemp, 24); // Set Temperature when mode is Off / 10 (e.g.: 0x0F = 7.5 degrees Celsius)
|
||||
has_update(telegram, heatingpid_, 25); // PID setting 00=1 01=2 02=3
|
||||
has_update(telegram, preheating_, 26); // Preheating in the clock program: (0x00 = off, 0xFF = on)
|
||||
has_update(telegram, hc->tempautotemp, 28); // is * 2
|
||||
has_update(telegram, hc->manualtemp, 29); // manualtemp is * 2
|
||||
has_update(telegram, hc->nofrosttemp, 24); // Set Temperature when mode is Off / 10 (e.g.: 0x0F = 7.5 degrees Celsius)
|
||||
has_update(telegram, heatingpid_, 25); // PID setting 00=1 01=2 02=3
|
||||
has_update(telegram, preheating_, 26); // Preheating in the clock program: (0x00 = off, 0xFF = on)
|
||||
has_update(telegram, hc->tempautotemp, 28); // is * 2
|
||||
has_update(telegram, hc->manualtemp, 29); // manualtemp is * 2
|
||||
}
|
||||
|
||||
// type 0x40 (HC1) - for reading the operating mode from the RC30 thermostat (0x10)
|
||||
@@ -1274,13 +1274,13 @@ void Thermostat::process_RC35Set(std::shared_ptr<const Telegram> telegram) {
|
||||
return;
|
||||
}
|
||||
|
||||
has_update(telegram, hc->heatingtype, 0); // 0- off, 1-radiator, 2-convector, 3-floor
|
||||
has_update(telegram, hc->nighttemp, 1); // is * 2
|
||||
has_update(telegram, hc->daytemp, 2); // is * 2
|
||||
has_update(telegram, hc->holidaytemp, 3); // is * 2
|
||||
has_update(telegram, hc->roominfluence, 4); // is * 1
|
||||
has_update(telegram, hc->offsettemp, 6); // is * 2
|
||||
has_update(telegram, hc->mode, 7); // night, day, auto
|
||||
has_update(telegram, hc->heatingtype, 0); // 0- off, 1-radiator, 2-convector, 3-floor
|
||||
has_update(telegram, hc->nighttemp, 1); // is * 2
|
||||
has_update(telegram, hc->daytemp, 2); // is * 2
|
||||
has_update(telegram, hc->holidaytemp, 3); // is * 2
|
||||
has_update(telegram, hc->roominfluence, 4); // is * 1
|
||||
has_update(telegram, hc->offsettemp, 6); // is * 2
|
||||
has_update(telegram, hc->mode, 7); // night, day, auto
|
||||
|
||||
has_update(telegram, hc->wwprio, 21); // 0xFF for on
|
||||
has_update(telegram, hc->summertemp, 22); // is * 1
|
||||
@@ -1291,10 +1291,10 @@ void Thermostat::process_RC35Set(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, hc->control, 26); // 0-off, 1-RC20 (remote), 2-RC35
|
||||
has_update(telegram, hc->controlmode, 33); // 0-outdoortemp, 1-roomtemp
|
||||
has_update(telegram, hc->tempautotemp, 37);
|
||||
has_update(telegram, hc->noreducetemp, 38); // outdoor temperature for no reduce
|
||||
has_update(telegram, hc->reducetemp, 39); // temperature for off/reduce
|
||||
has_update(telegram, hc->vacreducetemp, 40); // temperature for off/reduce in vacations
|
||||
has_update(telegram, hc->vacreducemode, 41); // vacations reduce mode
|
||||
has_update(telegram, hc->noreducetemp, 38); // outdoor temperature for no reduce
|
||||
has_update(telegram, hc->reducetemp, 39); // temperature for off/reduce
|
||||
has_update(telegram, hc->vacreducetemp, 40); // temperature for off/reduce in vacations
|
||||
has_update(telegram, hc->vacreducemode, 41); // vacations reduce mode
|
||||
has_update(telegram, hc->minflowtemp, 16);
|
||||
|
||||
// RC35 stores values for floorheating in different position
|
||||
@@ -1416,7 +1416,7 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
bool ivtclock = (telegram->message_data[0] & 0x80) == 0x80; // dont sync ivt-clock, #439
|
||||
bool junkersclock = model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS;
|
||||
time_t ttime = mktime(tm_); // thermostat time
|
||||
time_t ttime = mktime(tm_); // thermostat time
|
||||
// correct thermostat clock if we have valid ntp time, and could write the command
|
||||
if (!ivtclock && !junkersclock && tset_ && EMSESP::system_.ntp_connected() && !EMSESP::system_.readonly_mode() && has_command(&dateTime_)) {
|
||||
double difference = difftime(now, ttime);
|
||||
@@ -1426,7 +1426,7 @@ void Thermostat::process_RCTime(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
}
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (!tset_ && tm_->tm_year > 110) { // emsesp clock not set, but thermostat clock
|
||||
if (!tset_ && tm_->tm_year > 110) { // emsesp clock not set, but thermostat clock
|
||||
if (ivtclock) {
|
||||
tm_->tm_isdst = -1; // determine dst
|
||||
ttime = mktime(tm_); // thermostat time
|
||||
@@ -2302,7 +2302,7 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) {
|
||||
data[6] = (tm_->tm_wday + 6) % 7; // Bosch counts from Mo, time from Su
|
||||
data[7] = tm_->tm_isdst + 2; // set DST and flag for ext. clock
|
||||
if (model() == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||
data[6]++; // Junkers use 1-7;
|
||||
data[6]++; // Junkers use 1-7;
|
||||
data[7] = 0;
|
||||
}
|
||||
} else if (dt.length() == 23) {
|
||||
@@ -2500,7 +2500,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) {
|
||||
if (mode == HeatingCircuit::Mode::AUTO) {
|
||||
set_mode_value = 0xFF; // special value for auto
|
||||
} else {
|
||||
set_mode_value = 0; // everything else, like manual/day etc..
|
||||
set_mode_value = 0; // everything else, like manual/day etc..
|
||||
}
|
||||
break;
|
||||
case EMSdevice::EMS_DEVICE_FLAG_JUNKERS:
|
||||
@@ -3121,7 +3121,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
|
||||
offset = 0x0A; // manual offset
|
||||
break;
|
||||
case HeatingCircuit::Mode::TEMPAUTO:
|
||||
offset = 0x08; // auto offset
|
||||
offset = 0x08; // auto offset
|
||||
if (temperature == -1) {
|
||||
factor = 1; // to write 0xFF
|
||||
}
|
||||
|
||||
@@ -256,9 +256,9 @@ class Thermostat : public EMSdevice {
|
||||
static constexpr uint16_t EMS_TYPE_RCOutdoorTemp = 0xA3; // is an automatic thermostat broadcast, outdoor external temp
|
||||
|
||||
// Type offsets
|
||||
static constexpr uint8_t EMS_OFFSET_RC10StatusMessage_setpoint = 1; // setpoint temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC10StatusMessage_curr = 2; // current temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC10Set_temp = 4; // position of thermostat setpoint temperature
|
||||
static constexpr uint8_t EMS_OFFSET_RC10StatusMessage_setpoint = 1; // setpoint temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC10StatusMessage_curr = 2; // current temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC10Set_temp = 4; // position of thermostat setpoint temperature
|
||||
|
||||
static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_setpoint = 1; // setpoint temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_curr = 2; // current temp
|
||||
@@ -267,9 +267,9 @@ class Thermostat : public EMSdevice {
|
||||
static constexpr uint8_t EMS_OFFSET_RC20Set_temp_auto = 28; // position of thermostat setpoint temperature
|
||||
static constexpr uint8_t EMS_OFFSET_RC20Set_temp_manual = 29; // position of thermostat setpoint temperature
|
||||
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_mode = 3; // ES72 - see https://github.com/emsesp/EMS-ESP/issues/334
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_temp_night = 1; // ES72
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_temp_day = 2; // ES72
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_mode = 3; // ES72 - see https://github.com/emsesp/EMS-ESP/issues/334
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_temp_night = 1; // ES72
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_temp_day = 2; // ES72
|
||||
|
||||
static constexpr uint8_t EMS_OFFSET_RC30StatusMessage_setpoint = 1; // setpoint temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC30StatusMessage_curr = 2; // current temp
|
||||
@@ -308,8 +308,8 @@ class Thermostat : public EMSdevice {
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_temp_summer = 22;
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_temp_nofrost = 23;
|
||||
|
||||
static constexpr uint8_t EMS_OFFSET_EasyStatusMessage_setpoint = 10; // setpoint temp
|
||||
static constexpr uint8_t EMS_OFFSET_EasyStatusMessage_curr = 8; // current temp
|
||||
static constexpr uint8_t EMS_OFFSET_EasyStatusMessage_setpoint = 10; // setpoint temp
|
||||
static constexpr uint8_t EMS_OFFSET_EasyStatusMessage_curr = 8; // current temp
|
||||
|
||||
static constexpr uint8_t EMS_OFFSET_RCPLUSStatusMessage_mode = 10; // thermostat mode (auto, manual)
|
||||
static constexpr uint8_t EMS_OFFSET_RCPLUSStatusMessage_setpoint = 3; // setpoint temp
|
||||
|
||||
@@ -520,7 +520,7 @@ void EMSdevice::add_device_value(uint8_t tag, // to b
|
||||
// get fullname, getting translation if it exists
|
||||
const char * const * fullname;
|
||||
if (Helpers::count_items(name) == 1) {
|
||||
fullname = nullptr; // no translations available, use empty
|
||||
fullname = nullptr; // no translations available, use empty
|
||||
} else {
|
||||
fullname = &name[1]; // translations start at index 1
|
||||
}
|
||||
@@ -1311,7 +1311,7 @@ void EMSdevice::dump_value_info() {
|
||||
if (dv.type == DeviceValueType::BOOL) {
|
||||
snprintf(entityid, sizeof(entityid), "binary_sensor.%s", entity_with_tag); // binary sensor (for booleans)
|
||||
} else {
|
||||
snprintf(entityid, sizeof(entityid), "sensor.%s", entity_with_tag); // normal HA sensor
|
||||
snprintf(entityid, sizeof(entityid), "sensor.%s", entity_with_tag); // normal HA sensor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -459,7 +459,7 @@ class EMSdevice {
|
||||
|
||||
std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types
|
||||
|
||||
std::vector<DeviceValue> devicevalues_; // all the device values
|
||||
std::vector<DeviceValue> devicevalues_; // all the device values
|
||||
|
||||
std::vector<uint16_t> handlers_ignored_;
|
||||
};
|
||||
|
||||
@@ -145,12 +145,12 @@ class DeviceValue {
|
||||
DV_NUMOP_MUL15 = -15
|
||||
};
|
||||
|
||||
uint8_t device_type; // EMSdevice::DeviceType
|
||||
uint8_t tag; // DeviceValueTAG::*
|
||||
void * value_p; // pointer to variable of any type
|
||||
uint8_t type; // DeviceValueType::*
|
||||
const char * const ** options; // options as a flash char array
|
||||
const char * const * options_single; // options are not translated
|
||||
uint8_t device_type; // EMSdevice::DeviceType
|
||||
uint8_t tag; // DeviceValueTAG::*
|
||||
void * value_p; // pointer to variable of any type
|
||||
uint8_t type; // DeviceValueType::*
|
||||
const char * const ** options; // options as a flash char array
|
||||
const char * const * options_single; // options are not translated
|
||||
int8_t numeric_operator;
|
||||
uint8_t options_size; // number of options in the char array, calculated
|
||||
const char * const short_name; // used in MQTT and API
|
||||
|
||||
@@ -163,7 +163,7 @@ class EMSESP {
|
||||
}
|
||||
|
||||
static void watch(uint8_t watch) {
|
||||
watch_ = watch; // 0=off, 1=on, 2=raw
|
||||
watch_ = watch; // 0=off, 1=on, 2=raw
|
||||
if (watch == WATCH_OFF) {
|
||||
watch_id_ = 0; // reset watch id if watch is disabled
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ std::string Helpers::data_to_hex(const uint8_t * data, const uint8_t length) {
|
||||
*p++ = buffer[1];
|
||||
*p++ = ' '; // space
|
||||
}
|
||||
*--p = '\0'; // null terminate just in case, loosing the trailing space
|
||||
*--p = '\0'; // null terminate just in case, loosing the trailing space
|
||||
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
@@ -592,7 +592,8 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con
|
||||
if (!mqtt_enabled_ || topic.empty()) {
|
||||
return false; // quit, not using MQTT
|
||||
}
|
||||
// check free mem
|
||||
// check free mem
|
||||
#ifndef EMSESP_STANDALONE
|
||||
if (ESP.getFreeHeap() < 60 * 1204) {
|
||||
if (operation == Operation::PUBLISH) {
|
||||
mqtt_message_id_++;
|
||||
@@ -601,6 +602,7 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con
|
||||
LOG_DEBUG("%s failed: low memory", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe");
|
||||
return false; // quit
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t packet_id = 0;
|
||||
char fulltopic[MQTT_TOPIC_MAX_SIZE];
|
||||
|
||||
@@ -847,7 +847,7 @@ void System::led_monitor() {
|
||||
}
|
||||
|
||||
if (led_on_) {
|
||||
digitalWrite(led_gpio_, LED_ON); // LED off
|
||||
digitalWrite(led_gpio_, LED_ON); // LED off
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
@@ -1432,27 +1432,27 @@ bool System::command_test(const char * value, const int8_t id) {
|
||||
// 3 = RMII clock output from GPIO17, for 50hz inverted clock
|
||||
bool System::load_board_profile(std::vector<int8_t> & data, const std::string & board_profile) {
|
||||
if (board_profile == "S32") {
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // BBQKees Gateway S32
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // BBQKees Gateway S32
|
||||
} else if (board_profile == "E32") {
|
||||
data = {2, 4, 5, 17, 33, PHY_type::PHY_TYPE_LAN8720, 16, 1, 0}; // BBQKees Gateway E32
|
||||
} else if (board_profile == "MH-ET") {
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // MH-ET Live D1 Mini
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // MH-ET Live D1 Mini
|
||||
} else if (board_profile == "NODEMCU") {
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // NodeMCU 32S
|
||||
data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // NodeMCU 32S
|
||||
} else if (board_profile == "LOLIN") {
|
||||
data = {2, 18, 17, 16, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin D32
|
||||
data = {2, 18, 17, 16, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin D32
|
||||
} else if (board_profile == "OLIMEX") {
|
||||
data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, -1, 0, 0}; // Olimex ESP32-EVB (uses U1TXD/U1RXD/BUTTON, no LED or Temperature sensor)
|
||||
} else if (board_profile == "OLIMEXPOE") {
|
||||
data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, 12, 0, 3}; // Olimex ESP32-POE
|
||||
} else if (board_profile == "C3MINI") {
|
||||
data = {7, 1, 4, 5, 9, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin C3 Mini
|
||||
data = {7, 1, 4, 5, 9, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin C3 Mini
|
||||
} else if (board_profile == "S2MINI") {
|
||||
data = {15, 7, 11, 12, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin S2 Mini
|
||||
data = {15, 7, 11, 12, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin S2 Mini
|
||||
} else if (board_profile == "S3MINI") {
|
||||
data = {17, 18, 8, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Liligo S3
|
||||
data = {17, 18, 8, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Liligo S3
|
||||
} else if (board_profile == "S32S3") {
|
||||
data = {2, 18, 5, 17, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // BBQKees Gateway S3
|
||||
data = {2, 18, 5, 17, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // BBQKees Gateway S3
|
||||
} else if (board_profile == "CUSTOM") {
|
||||
// send back current values
|
||||
data = {(int8_t)EMSESP::system_.led_gpio_,
|
||||
|
||||
@@ -148,11 +148,11 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
||||
// validate the CRC. if it fails then increment the number of corrupt/incomplete telegrams and only report to console/syslog
|
||||
uint8_t crc = calculate_crc(data, length - 1);
|
||||
if (data[length - 1] != crc) {
|
||||
if ((data[0] & 0x7F) != ems_bus_id()) { // do not count echos as errors
|
||||
if ((data[0] & 0x7F) != ems_bus_id()) { // do not count echos as errors
|
||||
telegram_error_count_++;
|
||||
LOG_WARNING("Incomplete Rx: %s", Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC
|
||||
} else {
|
||||
LOG_TRACE("Incomplete Rx: %s", Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC
|
||||
LOG_TRACE("Incomplete Rx: %s", Helpers::data_to_hex(data, length - 1).c_str()); // exclude CRC
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
||||
telegram_raw[5] = (telegram->type_id >> 8) - 1; // type, 1st byte, high-byte, subtract 0x100
|
||||
telegram_raw[6] = telegram->type_id & 0xFF; // type, 2nd byte, low-byte
|
||||
message_p = 7;
|
||||
copy_data = false; // there are no more data values after the type_id when reading on EMS+
|
||||
copy_data = false; // there are no more data values after the type_id when reading on EMS+
|
||||
}
|
||||
} else {
|
||||
// EMS 1.0
|
||||
@@ -396,11 +396,11 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
||||
if (status == EMS_TX_STATUS_ERR) {
|
||||
LOG_ERROR("Failed to transmit Tx via UART.");
|
||||
if (telegram->operation == Telegram::Operation::TX_READ) {
|
||||
increment_telegram_read_fail_count(); // another Tx fail
|
||||
increment_telegram_read_fail_count(); // another Tx fail
|
||||
} else {
|
||||
increment_telegram_write_fail_count(); // another Tx fail
|
||||
}
|
||||
tx_state(Telegram::Operation::NONE); // nothing send, tx not in wait state
|
||||
tx_state(Telegram::Operation::NONE); // nothing send, tx not in wait state
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ void TxService::add(const uint8_t operation,
|
||||
if (front) {
|
||||
tx_telegrams_.emplace_front(tx_telegram_id_++, std::move(telegram), false, validateid); // add to front of queue
|
||||
} else {
|
||||
tx_telegrams_.emplace_back(tx_telegram_id_++, std::move(telegram), false, validateid); // add to back of queue
|
||||
tx_telegrams_.emplace_back(tx_telegram_id_++, std::move(telegram), false, validateid); // add to back of queue
|
||||
}
|
||||
if (validateid != 0) {
|
||||
EMSESP::wait_validate(validateid);
|
||||
@@ -595,14 +595,14 @@ bool TxService::send_raw(const char * telegram_data) {
|
||||
void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const uint8_t length) {
|
||||
// have we reached the limit? if so, reset count and give up
|
||||
if (++retry_count_ > MAXIMUM_TX_RETRIES) {
|
||||
reset_retry_count(); // give up
|
||||
EMSESP::wait_validate(0); // do not wait for validation
|
||||
reset_retry_count(); // give up
|
||||
EMSESP::wait_validate(0); // do not wait for validation
|
||||
if (operation == Telegram::Operation::TX_READ) {
|
||||
if (telegram_last_->offset > 0) { // ignore errors for higher offsets
|
||||
LOG_DEBUG("Last Tx Read operation failed after %d retries. Ignoring request: %s", MAXIMUM_TX_RETRIES, telegram_last_->to_string().c_str());
|
||||
return;
|
||||
}
|
||||
increment_telegram_read_fail_count(); // another Tx fail
|
||||
increment_telegram_read_fail_count(); // another Tx fail
|
||||
} else {
|
||||
increment_telegram_write_fail_count(); // another Tx fail
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ static constexpr int16_t EMS_VALUE_SHORT_NOTSET = 0x7D00; // 32000: for 2-
|
||||
static constexpr uint32_t EMS_VALUE_ULONG_NOTSET = 0x00FFFFFF; // for 3-byte longs
|
||||
static constexpr uint32_t EMS_VALUE_ULLONG_NOTSET = 0xFFFFFFFF; // for 4-byte longs
|
||||
|
||||
static constexpr uint8_t EMS_MAX_TELEGRAM_LENGTH = 32; // max length of a complete EMS telegram
|
||||
static constexpr uint8_t EMS_MAX_TELEGRAM_MESSAGE_LENGTH = 27; // max length of message block, assuming EMS1.0
|
||||
static constexpr uint8_t EMS_MAX_TELEGRAM_LENGTH = 32; // max length of a complete EMS telegram
|
||||
static constexpr uint8_t EMS_MAX_TELEGRAM_MESSAGE_LENGTH = 27; // max length of message block, assuming EMS1.0
|
||||
|
||||
#define EMS_VALUE_DEFAULT_INT EMS_VALUE_INT_NOTSET
|
||||
#define EMS_VALUE_DEFAULT_UINT EMS_VALUE_UINT_NOTSET
|
||||
@@ -232,13 +232,13 @@ class EMSbus {
|
||||
private:
|
||||
static constexpr uint32_t EMS_BUS_TIMEOUT = 30000; // timeout in ms before recognizing the ems bus is offline (30 seconds)
|
||||
|
||||
static uint32_t last_bus_activity_; // timestamp of last time a valid Rx came in
|
||||
static uint32_t bus_uptime_start_; // timestamp of first time we connected to the bus
|
||||
static bool bus_connected_; // start assuming the bus hasn't been connected
|
||||
static uint8_t ems_mask_; // unset=0xFF, buderus=0x00, junkers/ht3=0x80
|
||||
static uint8_t ems_bus_id_; // the bus id, which configurable and stored in settings
|
||||
static uint8_t tx_mode_; // local copy of the tx mode
|
||||
static uint8_t tx_state_; // state of the Tx line (NONE or waiting on a TX_READ or TX_WRITE)
|
||||
static uint32_t last_bus_activity_; // timestamp of last time a valid Rx came in
|
||||
static uint32_t bus_uptime_start_; // timestamp of first time we connected to the bus
|
||||
static bool bus_connected_; // start assuming the bus hasn't been connected
|
||||
static uint8_t ems_mask_; // unset=0xFF, buderus=0x00, junkers/ht3=0x80
|
||||
static uint8_t ems_bus_id_; // the bus id, which configurable and stored in settings
|
||||
static uint8_t tx_mode_; // local copy of the tx mode
|
||||
static uint8_t tx_state_; // state of the Tx line (NONE or waiting on a TX_READ or TX_WRITE)
|
||||
};
|
||||
|
||||
class RxService : public EMSbus {
|
||||
@@ -433,17 +433,17 @@ class TxService : public EMSbus {
|
||||
private:
|
||||
std::deque<QueuedTxTelegram> tx_telegrams_; // the Tx queue
|
||||
|
||||
uint32_t telegram_read_count_ = 0; // # Tx successful reads
|
||||
uint32_t telegram_write_count_ = 0; // # Tx successful writes
|
||||
uint32_t telegram_read_fail_count_ = 0; // # Tx unsuccessful transmits
|
||||
uint32_t telegram_write_fail_count_ = 0; // # Tx unsuccessful transmits
|
||||
uint32_t telegram_read_count_ = 0; // # Tx successful reads
|
||||
uint32_t telegram_write_count_ = 0; // # Tx successful writes
|
||||
uint32_t telegram_read_fail_count_ = 0; // # Tx unsuccessful transmits
|
||||
uint32_t telegram_write_fail_count_ = 0; // # Tx unsuccessful transmits
|
||||
|
||||
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
|
||||
uint8_t retry_count_ = 0; // count for # Tx retries
|
||||
uint32_t delayed_send_ = 0; // manage delay for post send query
|
||||
|
||||
uint8_t tx_telegram_id_ = 0; // queue counter
|
||||
uint8_t tx_telegram_id_ = 0; // queue counter
|
||||
|
||||
void send_telegram(const QueuedTxTelegram & tx_telegram);
|
||||
};
|
||||
|
||||
@@ -214,7 +214,7 @@ void TemperatureSensor::loop() {
|
||||
// LOG_DEBUG("Adding %d sensor(s) from first scan", firstscan_);
|
||||
} else if ((scancnt_ <= 0) && (firstscan_ != sensors_.size())) { // check 2 times for no change of sensor #
|
||||
scancnt_ = SCAN_START;
|
||||
sensors_.clear(); // restart scanning and clear to get correct numbering
|
||||
sensors_.clear(); // restart scanning and clear to get correct numbering
|
||||
}
|
||||
state_ = State::IDLE;
|
||||
}
|
||||
@@ -576,7 +576,7 @@ TemperatureSensor::Sensor::Sensor(const uint8_t addr[])
|
||||
(unsigned int)(internal_id_ >> 48) & 0xFF,
|
||||
(unsigned int)(internal_id_ >> 32) & 0xFFFF,
|
||||
(unsigned int)(internal_id_ >> 16) & 0xFFFF,
|
||||
(unsigned int)(internal_id_)&0xFFFF);
|
||||
(unsigned int)(internal_id_) & 0xFFFF);
|
||||
id_ = std::string(id_s);
|
||||
name_ = std::string{}; // name (alias) is empty
|
||||
offset_ = 0; // 0 degrees offset
|
||||
|
||||
@@ -132,7 +132,7 @@ class TemperatureSensor {
|
||||
static constexpr uint8_t TYPE_DS18B20 = 0x28;
|
||||
static constexpr uint8_t TYPE_DS18S20 = 0x10;
|
||||
static constexpr uint8_t TYPE_DS1822 = 0x22;
|
||||
static constexpr uint8_t TYPE_DS1825 = 0x3B; // also DS1826
|
||||
static constexpr uint8_t TYPE_DS1825 = 0x3B; // also DS1826
|
||||
|
||||
static constexpr uint32_t READ_INTERVAL_MS = 5000; // 5 seconds
|
||||
static constexpr uint32_t CONVERSION_MS = 1000; // 1 seconds
|
||||
|
||||
@@ -86,7 +86,7 @@ void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t
|
||||
uart_set_pin(EMSUART_NUM, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
uart_driver_install(EMSUART_NUM, 129, 0, (EMS_MAXBUFFERSIZE + 1) * 2, &uart_queue, 0); // buffer must be > fifo
|
||||
uart_set_rx_full_threshold(EMSUART_NUM, 1);
|
||||
uart_set_rx_timeout(EMSUART_NUM, 0); // disable
|
||||
uart_set_rx_timeout(EMSUART_NUM, 0); // disable
|
||||
|
||||
// note esp32s3 crashes with 2k stacksize, stack overflow here sometimes wipes settingsfiles.
|
||||
xTaskCreate(uart_event_task, "uart_event_task", 2560, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#ifndef EMSESP_EMSUART_H
|
||||
#define EMSESP_EMSUART_H
|
||||
|
||||
#define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK
|
||||
#define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK
|
||||
|
||||
#define EMSUART_NUM UART_NUM_1 // on C3 and S2 there is no UART2, use UART1 for all
|
||||
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.7.0-dev.2"
|
||||
#define EMSESP_APP_VERSION "3.6.1-dev.0"
|
||||
|
||||
@@ -156,7 +156,7 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
||||
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) {
|
||||
obj["v"] = Helpers::transformNumFloat(sensor.value(), 0); // is optional and is a float
|
||||
} else {
|
||||
obj["v"] = 0; // must have a value for web sorting to work
|
||||
obj["v"] = 0; // must have a value for web sorting to work
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class WebLogService : public uuid::log::Handler {
|
||||
|
||||
void setValues(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
|
||||
AsyncCallbackJsonWebHandler setValues_; // for POSTs
|
||||
AsyncCallbackJsonWebHandler setValues_; // for POSTs
|
||||
|
||||
uint64_t last_transmit_ = 0; // Last transmit time
|
||||
size_t maximum_log_messages_ = MAX_LOG_MESSAGES; // Maximum number of log messages to buffer before they are output
|
||||
|
||||
@@ -86,7 +86,7 @@ StateUpdateResult WebScheduler::update(JsonObject & root, WebScheduler & webSche
|
||||
|
||||
// calculated elapsed minutes
|
||||
si.elapsed_min = Helpers::string2minutes(si.time);
|
||||
si.retry_cnt = 0xFF; // no startup retries
|
||||
si.retry_cnt = 0xFF; // no startup retries
|
||||
|
||||
webScheduler.scheduleItems.push_back(si); // add to list
|
||||
if (!webScheduler.scheduleItems.back().name.empty()) {
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#define EMSESP_SCHEDULER_FILE "/config/emsespScheduler.json"
|
||||
#define EMSESP_SCHEDULER_SERVICE_PATH "/rest/schedule" // GET and POST
|
||||
|
||||
#define SCHEDULEFLAG_SCHEDULE_TIMER 0x80 // 7th bit for Timer
|
||||
#define MAX_STARTUP_RETRIES 3 // retry the start-up commands x times
|
||||
#define SCHEDULEFLAG_SCHEDULE_TIMER 0x80 // 7th bit for Timer
|
||||
#define MAX_STARTUP_RETRIES 3 // retry the start-up commands x times
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
|
||||
@@ -228,61 +228,61 @@ void WebStatusService::mDNS_start() const {
|
||||
const char * WebStatusService::disconnectReason(uint8_t code) {
|
||||
#ifndef EMSESP_STANDALONE
|
||||
switch (code) {
|
||||
case WIFI_REASON_UNSPECIFIED: // = 1,
|
||||
case WIFI_REASON_UNSPECIFIED: // = 1,
|
||||
return "unspecified";
|
||||
case WIFI_REASON_AUTH_EXPIRE: // = 2,
|
||||
case WIFI_REASON_AUTH_EXPIRE: // = 2,
|
||||
return "auth expire";
|
||||
case WIFI_REASON_AUTH_LEAVE: // = 3,
|
||||
case WIFI_REASON_AUTH_LEAVE: // = 3,
|
||||
return "auth leave";
|
||||
case WIFI_REASON_ASSOC_EXPIRE: // = 4,
|
||||
case WIFI_REASON_ASSOC_EXPIRE: // = 4,
|
||||
return "assoc expired";
|
||||
case WIFI_REASON_ASSOC_TOOMANY: // = 5,
|
||||
case WIFI_REASON_ASSOC_TOOMANY: // = 5,
|
||||
return "assoc too many";
|
||||
case WIFI_REASON_NOT_AUTHED: // = 6,
|
||||
case WIFI_REASON_NOT_AUTHED: // = 6,
|
||||
return "not authenticated";
|
||||
case WIFI_REASON_NOT_ASSOCED: // = 7,
|
||||
case WIFI_REASON_NOT_ASSOCED: // = 7,
|
||||
return "not assoc";
|
||||
case WIFI_REASON_ASSOC_LEAVE: // = 8,
|
||||
case WIFI_REASON_ASSOC_LEAVE: // = 8,
|
||||
return "assoc leave";
|
||||
case WIFI_REASON_ASSOC_NOT_AUTHED: // = 9,
|
||||
case WIFI_REASON_ASSOC_NOT_AUTHED: // = 9,
|
||||
return "assoc not authed";
|
||||
case WIFI_REASON_DISASSOC_PWRCAP_BAD: // = 10,
|
||||
case WIFI_REASON_DISASSOC_PWRCAP_BAD: // = 10,
|
||||
return "disassoc powerCAP bad";
|
||||
case WIFI_REASON_DISASSOC_SUPCHAN_BAD: // = 11,
|
||||
case WIFI_REASON_DISASSOC_SUPCHAN_BAD: // = 11,
|
||||
return "disassoc supchan bad";
|
||||
case WIFI_REASON_IE_INVALID: // = 13,
|
||||
case WIFI_REASON_IE_INVALID: // = 13,
|
||||
return "IE invalid";
|
||||
case WIFI_REASON_MIC_FAILURE: // = 14,
|
||||
case WIFI_REASON_MIC_FAILURE: // = 14,
|
||||
return "MIC failure";
|
||||
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: // = 15,
|
||||
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: // = 15,
|
||||
return "4way handshake timeout";
|
||||
case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: // = 16,
|
||||
return "group key-update timeout";
|
||||
case WIFI_REASON_IE_IN_4WAY_DIFFERS: // = 17,
|
||||
case WIFI_REASON_IE_IN_4WAY_DIFFERS: // = 17,
|
||||
return "IE in 4way differs";
|
||||
case WIFI_REASON_GROUP_CIPHER_INVALID: // = 18,
|
||||
case WIFI_REASON_GROUP_CIPHER_INVALID: // = 18,
|
||||
return "group cipher invalid";
|
||||
case WIFI_REASON_PAIRWISE_CIPHER_INVALID: // = 19,
|
||||
case WIFI_REASON_PAIRWISE_CIPHER_INVALID: // = 19,
|
||||
return "pairwise cipher invalid";
|
||||
case WIFI_REASON_AKMP_INVALID: // = 20,
|
||||
case WIFI_REASON_AKMP_INVALID: // = 20,
|
||||
return "AKMP invalid";
|
||||
case WIFI_REASON_UNSUPP_RSN_IE_VERSION: // = 21,
|
||||
case WIFI_REASON_UNSUPP_RSN_IE_VERSION: // = 21,
|
||||
return "unsupported RSN_IE version";
|
||||
case WIFI_REASON_INVALID_RSN_IE_CAP: // = 22,
|
||||
case WIFI_REASON_INVALID_RSN_IE_CAP: // = 22,
|
||||
return "invalid RSN_IE_CAP";
|
||||
case WIFI_REASON_802_1X_AUTH_FAILED: // = 23,
|
||||
case WIFI_REASON_802_1X_AUTH_FAILED: // = 23,
|
||||
return "802 X1 auth failed";
|
||||
case WIFI_REASON_CIPHER_SUITE_REJECTED: // = 24,
|
||||
case WIFI_REASON_CIPHER_SUITE_REJECTED: // = 24,
|
||||
return "cipher suite rejected";
|
||||
case WIFI_REASON_BEACON_TIMEOUT: // = 200,
|
||||
case WIFI_REASON_BEACON_TIMEOUT: // = 200,
|
||||
return "beacon timeout";
|
||||
case WIFI_REASON_NO_AP_FOUND: // = 201,
|
||||
case WIFI_REASON_NO_AP_FOUND: // = 201,
|
||||
return "no AP found";
|
||||
case WIFI_REASON_AUTH_FAIL: // = 202,
|
||||
case WIFI_REASON_AUTH_FAIL: // = 202,
|
||||
return "auth fail";
|
||||
case WIFI_REASON_ASSOC_FAIL: // = 203,
|
||||
case WIFI_REASON_ASSOC_FAIL: // = 203,
|
||||
return "assoc fail";
|
||||
case WIFI_REASON_HANDSHAKE_TIMEOUT: // = 204,
|
||||
case WIFI_REASON_HANDSHAKE_TIMEOUT: // = 204,
|
||||
return "handshake timeout";
|
||||
default:
|
||||
return "unknown";
|
||||
|
||||
Reference in New Issue
Block a user