This commit is contained in:
MichaelDvP
2023-10-22 18:25:40 +02:00
10 changed files with 111 additions and 95 deletions

View File

@@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Power entities - Power entities
- Optional input of BSSID for AP connection - Optional input of BSSID for AP connection
- Return empty json if no entries in scheduler/custom/analogsnesor/temperaturesensor - Return empty json if no entries in scheduler/custom/analogsensor/temperaturesensor
## Fixed ## Fixed

View File

@@ -1,6 +1,6 @@
import { useRequest } from 'alova'; import { useRequest } from 'alova';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom'; import { redirect } from 'react-router-dom';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { AuthenticationContext } from './context'; import { AuthenticationContext } from './context';
import type { FC } from 'react'; import type { FC } from 'react';
@@ -15,8 +15,6 @@ import { useI18nContext } from 'i18n/i18n-react';
const Authentication: FC<RequiredChildrenProps> = ({ children }) => { const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
const { LL } = useI18nContext(); const { LL } = useI18nContext();
const navigate = useNavigate();
const [initialized, setInitialized] = useState<boolean>(false); const [initialized, setInitialized] = useState<boolean>(false);
const [me, setMe] = useState<Me>(); const [me, setMe] = useState<Me>();
@@ -36,11 +34,12 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
} }
}; };
const signOut = (redirect: boolean) => { const signOut = (doRedirect: boolean) => {
AuthenticationApi.clearAccessToken(); AuthenticationApi.clearAccessToken();
setMe(undefined); setMe(undefined);
if (redirect) { if (doRedirect) {
navigate('/'); // navigate('/');
redirect('/');
} }
}; };

View File

@@ -1,6 +1,7 @@
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined'; import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined'; import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered';
import DownloadIcon from '@mui/icons-material/GetApp'; import DownloadIcon from '@mui/icons-material/GetApp';
import HighlightOffIcon from '@mui/icons-material/HighlightOff'; import HighlightOffIcon from '@mui/icons-material/HighlightOff';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
@@ -35,6 +36,7 @@ import { useRequest } from 'alova';
import { useState, useContext, useEffect, useCallback, useLayoutEffect } from 'react'; import { useState, useContext, useEffect, useCallback, useLayoutEffect } from 'react';
import { IconContext } from 'react-icons'; import { IconContext } from 'react-icons';
import { useNavigate } from 'react-router-dom';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import DashboardDevicesDialog from './DashboardDevicesDialog'; import DashboardDevicesDialog from './DashboardDevicesDialog';
import DeviceIcon from './DeviceIcon'; import DeviceIcon from './DeviceIcon';
@@ -62,6 +64,8 @@ const DashboardDevices: FC = () => {
const [showDeviceInfo, setShowDeviceInfo] = useState<boolean>(false); const [showDeviceInfo, setShowDeviceInfo] = useState<boolean>(false);
const [selectedDevice, setSelectedDevice] = useState<number>(); const [selectedDevice, setSelectedDevice] = useState<number>();
const navigate = useNavigate();
const { data: coreData, send: readCoreData } = useRequest(() => EMSESP.readCoreData(), { const { data: coreData, send: readCoreData } = useRequest(() => EMSESP.readCoreData(), {
initialData: { initialData: {
connected: true, connected: true,
@@ -264,13 +268,16 @@ const DashboardDevices: FC = () => {
}, [escFunction]); }, [escFunction]);
const refreshData = () => { const refreshData = () => {
if (deviceValueDialogOpen) { if (!deviceValueDialogOpen) {
return; selectedDevice ? void readDeviceData(selectedDevice) : void readCoreData();
} }
if (selectedDevice) { };
void readDeviceData(selectedDevice);
const customize = () => {
if (selectedDevice == 99) {
navigate('/settings/customentities');
} else { } else {
void readCoreData(); navigate('/settings/customization', { state: selectedDevice });
} }
}; };
@@ -496,10 +503,19 @@ const DashboardDevices: FC = () => {
<Grid container justifyContent="space-between"> <Grid container justifyContent="space-between">
<Typography sx={{ ml: 1 }} variant="subtitle2" color="primary"> <Typography sx={{ ml: 1 }} variant="subtitle2" color="primary">
{shown_data.length + ' ' + LL.ENTITIES(shown_data.length)} {LL.SHOWING() +
' ' +
shown_data.length +
'/' +
coreData.devices[deviceIndex].e +
' ' +
LL.ENTITIES(shown_data.length)}
<IconButton onClick={() => setShowDeviceInfo(true)}> <IconButton onClick={() => setShowDeviceInfo(true)}>
<InfoOutlinedIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} /> <InfoOutlinedIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} />
</IconButton> </IconButton>
<IconButton onClick={customize}>
<FormatListNumberedIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} />
</IconButton>
<IconButton onClick={handleDownloadCsv}> <IconButton onClick={handleDownloadCsv}>
<DownloadIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} /> <DownloadIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} />
</IconButton> </IconButton>

View File

@@ -23,7 +23,7 @@ import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-li
import { useTheme } from '@table-library/react-table-library/theme'; import { useTheme } from '@table-library/react-table-library/theme';
import { useRequest } from 'alova'; import { useRequest } from 'alova';
import { useState, useEffect, useCallback } from 'react'; import { useState, useEffect, useCallback } from 'react';
import { unstable_useBlocker as useBlocker } from 'react-router-dom'; import { unstable_useBlocker as useBlocker, useLocation } from 'react-router-dom';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import EntityMaskToggle from './EntityMaskToggle'; import EntityMaskToggle from './EntityMaskToggle';
@@ -52,19 +52,23 @@ const SettingsCustomization: FC = () => {
const [restarting, setRestarting] = useState<boolean>(false); const [restarting, setRestarting] = useState<boolean>(false);
const [restartNeeded, setRestartNeeded] = useState<boolean>(false); const [restartNeeded, setRestartNeeded] = useState<boolean>(false);
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([]); const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([]);
const [selectedDevice, setSelectedDevice] = useState<number>(-1);
const [confirmReset, setConfirmReset] = useState<boolean>(false); const [confirmReset, setConfirmReset] = useState<boolean>(false);
const [selectedFilters, setSelectedFilters] = useState<number>(0); const [selectedFilters, setSelectedFilters] = useState<number>(0);
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const [selectedDeviceEntity, setSelectedDeviceEntity] = useState<DeviceEntity>(); const [selectedDeviceEntity, setSelectedDeviceEntity] = useState<DeviceEntity>();
const [dialogOpen, setDialogOpen] = useState<boolean>(false); const [dialogOpen, setDialogOpen] = useState<boolean>(false);
// fetch devices first
const { data: devices } = useRequest(EMSESP.readDevices);
// const { state } = useLocation();
const [selectedDevice, setSelectedDevice] = useState<number>(useLocation().state || -1);
const [selectedDeviceName, setSelectedDeviceName] = useState<string>('');
const { send: resetCustomizations } = useRequest(EMSESP.resetCustomizations(), { const { send: resetCustomizations } = useRequest(EMSESP.resetCustomizations(), {
immediate: false immediate: false
}); });
const { data: devices } = useRequest(EMSESP.readDevices);
const { send: writeCustomizationEntities } = useRequest((data) => EMSESP.writeCustomizationEntities(data), { const { send: writeCustomizationEntities } = useRequest((data) => EMSESP.writeCustomizationEntities(data), {
immediate: false immediate: false
}); });
@@ -176,6 +180,22 @@ const SettingsCustomization: FC = () => {
} }
}, [deviceEntities]); }, [deviceEntities]);
useEffect(() => {
if (devices && selectedDevice !== -1) {
void readDeviceEntities(selectedDevice);
const id = devices.devices.findIndex((d) => d.i === selectedDevice);
if (id === -1) {
setSelectedDevice(-1);
setSelectedDeviceName('');
} else {
setSelectedDeviceName(devices.devices[id].tn || '');
setNumChanges(0);
setRestartNeeded(false);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [devices, selectedDevice]);
const restart = async () => { const restart = async () => {
await restartCommand().catch((error) => { await restartCommand().catch((error) => {
toast.error(error.message); toast.error(error.message);
@@ -246,16 +266,6 @@ const SettingsCustomization: FC = () => {
); );
}; };
const changeSelectedDevice = (event: React.ChangeEvent<HTMLInputElement>) => {
if (devices) {
const selected_device = parseInt(event.target.value, 10);
setSelectedDevice(selected_device);
setNumChanges(0);
void readDeviceEntities(devices?.devices[selected_device].i);
setRestartNeeded(false);
}
};
const resetCustomization = async () => { const resetCustomization = async () => {
try { try {
await resetCustomizations(); await resetCustomizations();
@@ -314,30 +324,21 @@ const SettingsCustomization: FC = () => {
return; return;
} }
await writeCustomizationEntities({ id: devices?.devices[selectedDevice].i, entity_ids: masked_entities }).catch( await writeCustomizationEntities({ id: selectedDevice, entity_ids: masked_entities }).catch((error) => {
(error) => { if (error.message === 'Reboot required') {
if (error.message === 'Reboot required') { setRestartNeeded(true);
setRestartNeeded(true); } else {
} else { toast.error(error.message);
toast.error(error.message);
}
} }
); });
setOriginalSettings(deviceEntities); setOriginalSettings(deviceEntities);
} }
}; };
const renderDeviceList = () => ( const renderDeviceList = () => (
<> <>
<Box mb={2} color="warning.main"> <Box mb={1} color="warning.main">
<Typography variant="body2">{LL.CUSTOMIZATIONS_HELP_1()}.</Typography> <Typography variant="body2">{LL.CUSTOMIZATIONS_HELP_1()}.</Typography>
<Typography variant="body2" mt={1}>
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}&nbsp;&nbsp;
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}&nbsp;&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_4()}&nbsp;&nbsp;
<OptionIcon type="web_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_5()}&nbsp;&nbsp;
<OptionIcon type="deleted" isSet={true} />={LL.CUSTOMIZATIONS_HELP_6()}
</Typography>
</Box> </Box>
<TextField <TextField
name="device" name="device"
@@ -346,15 +347,15 @@ const SettingsCustomization: FC = () => {
fullWidth fullWidth
value={selectedDevice} value={selectedDevice}
disabled={numChanges !== 0} disabled={numChanges !== 0}
onChange={changeSelectedDevice} onChange={(e) => setSelectedDevice(parseInt(e.target.value))}
margin="normal" margin="normal"
select select
> >
<MenuItem disabled key={-1} value={-1}> <MenuItem disabled key={-1} value={-1}>
{LL.SELECT_DEVICE()}... {LL.SELECT_DEVICE()}...
</MenuItem> </MenuItem>
{devices.devices.map((device: DeviceShort, index) => ( {devices.devices.map((device: DeviceShort) => (
<MenuItem key={index} value={index}> <MenuItem key={device.i} value={device.i}>
{device.s} {device.s}
</MenuItem> </MenuItem>
))} ))}
@@ -363,14 +364,19 @@ const SettingsCustomization: FC = () => {
); );
const renderDeviceData = () => { const renderDeviceData = () => {
if (deviceEntities.length === 0) {
return;
}
const shown_data = deviceEntities.filter((de) => filter_entity(de)); const shown_data = deviceEntities.filter((de) => filter_entity(de));
return ( return (
<> <>
<Box color="warning.main">
<Typography variant="body2" mt={1}>
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}&nbsp;&nbsp;
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}&nbsp;&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_4()}&nbsp;&nbsp;
<OptionIcon type="web_exclude" isSet={true} />={LL.CUSTOMIZATIONS_HELP_5()}&nbsp;&nbsp;
<OptionIcon type="deleted" isSet={true} />={LL.CUSTOMIZATIONS_HELP_6()}
</Typography>
</Box>
<Grid container mb={1} mt={0} spacing={1} direction="row" justifyContent="flex-start" alignItems="center"> <Grid container mb={1} mt={0} spacing={1} direction="row" justifyContent="flex-start" alignItems="center">
<Grid item xs={2}> <Grid item xs={2}>
<TextField <TextField
@@ -443,7 +449,7 @@ const SettingsCustomization: FC = () => {
</Grid> </Grid>
<Grid item> <Grid item>
<Typography variant="subtitle2" color="primary"> <Typography variant="subtitle2" color="primary">
{LL.SHOWING()}&nbsp;{shown_data.length}/{deviceEntities.length} {LL.SHOWING()}&nbsp;{shown_data.length}/{deviceEntities.length}&nbsp;{LL.ENTITIES(deviceEntities.length)}
</Typography> </Typography>
</Grid> </Grid>
</Grid> </Grid>
@@ -467,7 +473,7 @@ const SettingsCustomization: FC = () => {
</Cell> </Cell>
<Cell> <Cell>
{formatName(de, false)}&nbsp;( {formatName(de, false)}&nbsp;(
<Link target="_blank" href={APIURL + devices?.devices[selectedDevice].tn + '/' + de.id}> <Link target="_blank" href={APIURL + selectedDeviceName + '/' + de.id}>
{de.id} {de.id}
</Link> </Link>
) )
@@ -506,7 +512,7 @@ const SettingsCustomization: FC = () => {
{LL.DEVICE_ENTITIES()} {LL.DEVICE_ENTITIES()}
</Typography> </Typography>
{devices && renderDeviceList()} {devices && renderDeviceList()}
{renderDeviceData()} {deviceEntities && renderDeviceData()}
{restartNeeded && ( {restartNeeded && (
<MessageBox my={2} level="warning" message={LL.RESTART_TEXT()}> <MessageBox my={2} level="warning" message={LL.RESTART_TEXT()}>
<Button startIcon={<PowerSettingsNewIcon />} variant="contained" color="error" onClick={restart}> <Button startIcon={<PowerSettingsNewIcon />} variant="contained" color="error" onClick={restart}>
@@ -523,7 +529,7 @@ const SettingsCustomization: FC = () => {
startIcon={<CancelIcon />} startIcon={<CancelIcon />}
variant="outlined" variant="outlined"
color="secondary" color="secondary"
onClick={() => devices && readDeviceEntities(devices.devices[selectedDevice].i)} onClick={() => devices && readDeviceEntities(selectedDevice)}
> >
{LL.CANCEL()} {LL.CANCEL()}
</Button> </Button>

View File

@@ -85,7 +85,7 @@ typedef struct {
} lwip_event_packet_t; } lwip_event_packet_t;
static QueueHandle_t _async_queue; static QueueHandle_t _async_queue;
static TaskHandle_t _async_service_task_handle = NULL; static TaskHandle_t _async_service_task_handle = NULL;
SemaphoreHandle_t _slots_lock; SemaphoreHandle_t _slots_lock;
@@ -1084,13 +1084,13 @@ bool AsyncClient::getNoDelay() {
return tcp_nagle_disabled(_pcb); return tcp_nagle_disabled(_pcb);
} }
void AsyncClient::setKeepAlive(uint32_t ms, uint8_t cnt){ void AsyncClient::setKeepAlive(uint32_t ms, uint8_t cnt) {
if(ms!=0) { if (ms != 0) {
_pcb->so_options |= SOF_KEEPALIVE; //Turn on TCP Keepalive for the given pcb _pcb->so_options |= SOF_KEEPALIVE; //Turn on TCP Keepalive for the given pcb
// Set the time between keepalive messages in milli-seconds // Set the time between keepalive messages in milli-seconds
_pcb->keep_idle = ms; _pcb->keep_idle = ms;
_pcb->keep_intvl = ms; _pcb->keep_intvl = ms;
_pcb->keep_cnt = cnt; //The number of unanswered probes required to force closure of the socket _pcb->keep_cnt = cnt; //The number of unanswered probes required to force closure of the socket
} else { } else {
_pcb->so_options &= ~SOF_KEEPALIVE; //Turn off TCP Keepalive for the given pcb _pcb->so_options &= ~SOF_KEEPALIVE; //Turn off TCP Keepalive for the given pcb
} }

View File

@@ -1816,7 +1816,7 @@ const emsesp_devicedata_99 = {
}; };
// CUSTOM ENTITIES // CUSTOM ENTITIES
let emsesp_entities = { let emsesp_customentities = {
// entities: [] // entities: []
entities: [ entities: [
{ {
@@ -1876,10 +1876,10 @@ let emsesp_schedule = {
}; };
// CUSTOMIZATIONS // CUSTOMIZATIONS
const emsesp_deviceentities_1 = [{}]; const emsesp_deviceentities_1 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }];
const emsesp_deviceentities_3 = [{}]; const emsesp_deviceentities_3 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }];
const emsesp_deviceentities_5 = [{}]; const emsesp_deviceentities_5 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }];
const emsesp_deviceentities_6 = [{}]; const emsesp_deviceentities_6 = [{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }];
const emsesp_deviceentities_2 = [ const emsesp_deviceentities_2 = [
{ {
@@ -2205,6 +2205,7 @@ rest_server.get(EMSESP_SENSOR_DATA_ENDPOINT, (req, res) => {
res.json(emsesp_sensordata); res.json(emsesp_sensordata);
}); });
rest_server.get(EMSESP_DEVICES_ENDPOINT, (req, res) => { rest_server.get(EMSESP_DEVICES_ENDPOINT, (req, res) => {
console.log('send back list of devices...');
res.json(emsesp_devices); res.json(emsesp_devices);
}); });
rest_server.post(EMSESP_SCANDEVICES_ENDPOINT, (req, res) => { rest_server.post(EMSESP_SCANDEVICES_ENDPOINT, (req, res) => {
@@ -2398,7 +2399,7 @@ rest_server.post(EMSESP_WRITE_SCHEDULE_ENDPOINT, (req, res) => {
rest_server.post(EMSESP_WRITE_ENTITIES_ENDPOINT, (req, res) => { rest_server.post(EMSESP_WRITE_ENTITIES_ENDPOINT, (req, res) => {
console.log('write entities'); console.log('write entities');
console.log(req.body); console.log(req.body);
emsesp_entities = req.body; emsesp_customentities = req.body;
res.sendStatus(200); res.sendStatus(200);
}); });
@@ -2730,7 +2731,7 @@ rest_server.get(GET_CUSTOMIZATIONS_ENDPOINT, (req, res) => {
const GET_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'getEntities'; const GET_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'getEntities';
rest_server.get(GET_ENTITIES_ENDPOINT, (req, res) => { rest_server.get(GET_ENTITIES_ENDPOINT, (req, res) => {
console.log('getEntities'); console.log('getEntities');
res.json(emsesp_entities); res.json(emsesp_customentities);
}); });
const GET_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'getSchedule'; const GET_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'getSchedule';
@@ -2745,10 +2746,10 @@ rest_server.get(SCHEDULE_ENDPOINT, (req, res) => {
res.json(emsesp_schedule); res.json(emsesp_schedule);
}); });
const ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'entities'; const ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customentities';
rest_server.get(ENTITIES_ENDPOINT, (req, res) => { rest_server.get(ENTITIES_ENDPOINT, (req, res) => {
console.log('Sending Custom Entities data'); console.log('Sending Custom Entities data');
res.json(emsesp_entities); res.json(emsesp_customentities);
}); });
// start server // start server

View File

@@ -360,7 +360,7 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
commands->add_command(ShellContext::MAIN, commands->add_command(ShellContext::MAIN,
CommandFlags::ADMIN, CommandFlags::ADMIN,
string_vector{F_(scan), F_(devices)}, string_vector{F_(scan)},
string_vector{F_(deep_optional)}, string_vector{F_(deep_optional)},
[](Shell & shell, const std::vector<std::string> & arguments) { [](Shell & shell, const std::vector<std::string> & arguments) {
if (arguments.size() == 0) { if (arguments.size() == 0) {
@@ -368,29 +368,11 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
} else { } else {
shell.printfln("Performing a deep scan..."); shell.printfln("Performing a deep scan...");
to_app(shell).clear_all_devices(); to_app(shell).clear_all_devices();
std::vector<uint8_t> Device_Ids; // device IDs taken from device_library.h
Device_Ids.push_back(0x08); // Boilers - 0x08
Device_Ids.push_back(0x38); // HeatPump - 0x38
Device_Ids.push_back(0x30); // Solar Module - 0x30
Device_Ids.push_back(0x09); // Controllers - 0x09
Device_Ids.push_back(0x02); // Connect - 0x02
Device_Ids.push_back(0x48); // Gateway - 0x48
Device_Ids.push_back(0x20); // Mixer Devices - 0x20
Device_Ids.push_back(0x21); // Mixer Devices - 0x21
Device_Ids.push_back(0x22); // Mixer Devices - 0x22
Device_Ids.push_back(0x23); // Mixer Devices - 0x23
Device_Ids.push_back(0x28); // Mixer Devices WW- 0x28
Device_Ids.push_back(0x29); // Mixer Devices WW- 0x29
Device_Ids.push_back(0x10); // Thermostats - 0x10
Device_Ids.push_back(0x17); // Thermostats - 0x17
Device_Ids.push_back(0x18); // Thermostat remote - 0x18
Device_Ids.push_back(0x19); // Thermostat remote - 0x19
Device_Ids.push_back(0x1A); // Thermostat remote - 0x1A
Device_Ids.push_back(0x1B); // Thermostat remote - 0x1B
Device_Ids.push_back(0x11); // Switches - 0x11
// send the read command with Version command // send the read command with Version command
const std::vector<uint8_t> Device_Ids = {0x02, 0x08, 0x09, 0x10, 0x11, 0x12, 0x15, 0x17, 0x18, 0x19, 0x1A,
0x1B, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x2A, 0x30, 0x38, 0x40, 0x41, 0x48, 0x50, 0x51, 0x60};
for (const uint8_t device_id : Device_Ids) { for (const uint8_t device_id : Device_Ids) {
to_app(shell).send_read_request(EMSdevice::EMS_TYPE_VERSION, device_id); to_app(shell).send_read_request(EMSdevice::EMS_TYPE_VERSION, device_id);
} }

View File

@@ -101,7 +101,7 @@
{215, DeviceType::THERMOSTAT, "Comfort RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 {215, DeviceType::THERMOSTAT, "Comfort RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18
{216, DeviceType::THERMOSTAT, "CRF200S", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 {216, DeviceType::THERMOSTAT, "CRF200S", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18
{246, DeviceType::THERMOSTAT, "Comfort+2RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18 {246, DeviceType::THERMOSTAT, "Comfort+2RF", DeviceFlags::EMS_DEVICE_FLAG_CRF | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18
{253, DeviceType::THERMOSTAT, "Rego 3000/UI800/BC400", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10 {253, DeviceType::THERMOSTAT, "Rego 3000/UI800/WSW196i/BC400", DeviceFlags::EMS_DEVICE_FLAG_RC300}, // 0x10
// Thermostat - Sieger - 0x10 / 0x17 // Thermostat - Sieger - 0x10 / 0x17
{ 66, DeviceType::THERMOSTAT, "ES72/RC20", DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote { 66, DeviceType::THERMOSTAT, "ES72/RC20", DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote

View File

@@ -102,8 +102,18 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
FL_(setReturnTemp), FL_(setReturnTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_returnTemp)); MAKE_CF_CB(set_returnTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cwFlowRate_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(cwFlowRate), DeviceValueUOM::LMIN); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &netFlowTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(netFlowTemp), DeviceValueUOM::DEGREES); &cwFlowRate_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(cwFlowRate),
DeviceValueUOM::LMIN);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&netFlowTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(netFlowTemp),
DeviceValueUOM::DEGREES);
} }
/* /*
@@ -985,7 +995,7 @@ void Boiler::check_active() {
static uint32_t lastSendHeatingOff = 0; static uint32_t lastSendHeatingOff = 0;
if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && (uuid::get_uptime_sec() - lastSendHeatingOff) >= 60) { if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && (uuid::get_uptime_sec() - lastSendHeatingOff) >= 60) {
lastSendHeatingOff = uuid::get_uptime_sec(); lastSendHeatingOff = uuid::get_uptime_sec();
uint8_t data[] = {0, 0, 0, 0}; uint8_t data[] = {0, 0, 0, 0};
write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0);
} }

View File

@@ -633,10 +633,12 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con
packet_id = mqttClient_->unsubscribe(fulltopic); packet_id = mqttClient_->unsubscribe(fulltopic);
LOG_DEBUG("Unsubscribing to topic '%s', pid %d", fulltopic, packet_id); LOG_DEBUG("Unsubscribing to topic '%s', pid %d", fulltopic, packet_id);
} }
#ifndef EMSESP_STANDALONE
if (packet_id == 0) { if (packet_id == 0) {
LOG_WARNING("%s failed: %s", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe", fulltopic); LOG_WARNING("%s failed: %s", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe", fulltopic);
mqtt_publish_fails_++; mqtt_publish_fails_++;
} }
#endif
return (packet_id != 0); return (packet_id != 0);
} }