Merge pull request #421 from proddy/dev

fixes #411
This commit is contained in:
Proddy
2022-03-28 17:52:44 +02:00
committed by GitHub
8 changed files with 275 additions and 279 deletions

View File

@@ -12,7 +12,7 @@
"@emotion/styled": "^11.8.1", "@emotion/styled": "^11.8.1",
"@msgpack/msgpack": "^2.7.2", "@msgpack/msgpack": "^2.7.2",
"@mui/icons-material": "^5.5.1", "@mui/icons-material": "^5.5.1",
"@mui/material": "^5.5.2", "@mui/material": "^5.5.3",
"@types/lodash": "^4.14.180", "@types/lodash": "^4.14.180",
"@types/node": "^17.0.23", "@types/node": "^17.0.23",
"@types/react": "^17.0.43", "@types/react": "^17.0.43",
@@ -2849,13 +2849,14 @@
} }
}, },
"node_modules/@mui/base": { "node_modules/@mui/base": {
"version": "5.0.0-alpha.73", "version": "5.0.0-alpha.74",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.73.tgz", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.74.tgz",
"integrity": "sha512-TEUCIIEAWrngAqpIa+dY3nofGSNj70LC3KC9WcCzyXPK3M4AG2GNi7ndd/g/0DtC55kbxrudzlV8TG3vrB2Vjw==", "integrity": "sha512-pw3T1xNXpW8pLo9+BvtyazZb0CSjNJsjbzznlbV/aNkBfjNPXQVI3X1NDm3WSI8y6M96WDIVO7XrHAohOwALSQ==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@emotion/is-prop-valid": "^1.1.2", "@emotion/is-prop-valid": "^1.1.2",
"@mui/utils": "^5.4.4", "@mui/types": "^7.1.3",
"@mui/utils": "^5.5.3",
"@popperjs/core": "^2.11.4", "@popperjs/core": "^2.11.4",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
@@ -2905,15 +2906,15 @@
} }
}, },
"node_modules/@mui/material": { "node_modules/@mui/material": {
"version": "5.5.2", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.5.2.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.5.3.tgz",
"integrity": "sha512-r4p1u9eDlSqW3TS/Iq9yolifWHpuW6e0BSeqEJW3EEIcKfPVVk4WNUNJ+s8DtN7dBoDcveXxcQVVjYXTIv1d9g==", "integrity": "sha512-eADa3kUYbbr1jNjcufn0a7HeU8cSo0agbrkj720hodxVFNIfzq7a2e58Z+PaZqll55kMGBvlYJ7rTcXU399x5A==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@mui/base": "5.0.0-alpha.73", "@mui/base": "5.0.0-alpha.74",
"@mui/system": "^5.5.2", "@mui/system": "^5.5.3",
"@mui/types": "^7.1.3", "@mui/types": "^7.1.3",
"@mui/utils": "^5.4.4", "@mui/utils": "^5.5.3",
"@types/react-transition-group": "^4.4.4", "@types/react-transition-group": "^4.4.4",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"csstype": "^3.0.11", "csstype": "^3.0.11",
@@ -2949,12 +2950,12 @@
} }
}, },
"node_modules/@mui/private-theming": { "node_modules/@mui/private-theming": {
"version": "5.4.4", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.4.4.tgz", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.5.3.tgz",
"integrity": "sha512-V/gxttr6736yJoU9q+4xxXsa0K/w9Hn9pg99zsOHt7i/O904w2CX5NHh5WqDXtoUzVcayLF0RB17yr6l79CE+A==", "integrity": "sha512-Wf7NurY7lk8SBWelSBY2U02zxLt1773JpIcXTHuEC9/GZdQA4CXCJGl2cVQzheKhee5rZ+8JwGulrRiVl1m+4A==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@mui/utils": "^5.4.4", "@mui/utils": "^5.5.3",
"prop-types": "^15.7.2" "prop-types": "^15.7.2"
}, },
"engines": { "engines": {
@@ -3005,15 +3006,15 @@
} }
}, },
"node_modules/@mui/system": { "node_modules/@mui/system": {
"version": "5.5.2", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.5.2.tgz", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.5.3.tgz",
"integrity": "sha512-OATYFI36nliud8xh0u+ZNqDo0jWjxpO0vZLlzqNB+ZtkR5Q/+1X3GgboA9ruiB8Rq+udnJlMBQNGW0qqjvAOHQ==", "integrity": "sha512-J9JcySJuEqfEoP334K/2gEWm2vOx73Uqjii3qlFVhWRBOAJ0Pjyk0sN5W/eVRbwhUm95DNgh2V5s8dRK3vzyVw==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@mui/private-theming": "^5.4.4", "@mui/private-theming": "^5.5.3",
"@mui/styled-engine": "^5.5.2", "@mui/styled-engine": "^5.5.2",
"@mui/types": "^7.1.3", "@mui/types": "^7.1.3",
"@mui/utils": "^5.4.4", "@mui/utils": "^5.5.3",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"csstype": "^3.0.11", "csstype": "^3.0.11",
"prop-types": "^15.7.2" "prop-types": "^15.7.2"
@@ -3057,9 +3058,9 @@
} }
}, },
"node_modules/@mui/utils": { "node_modules/@mui/utils": {
"version": "5.4.4", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.4.4.tgz", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.5.3.tgz",
"integrity": "sha512-hfYIXEuhc2mXMGN5nUPis8beH6uE/zl3uMWJcyHX0/LN/+QxO9zhYuV6l8AsAaphHFyS/fBv0SW3Nid7jw5hKQ==", "integrity": "sha512-t627eVRpl3SlxVya0cIVNs8jPl4KCEiGaTSWY9iKKTcMNaeDbuRML+zv/CFHDPr1zFv+FjJSP02ySB+tZ8xIag==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@types/prop-types": "^15.7.4", "@types/prop-types": "^15.7.4",
@@ -19706,13 +19707,14 @@
"integrity": "sha512-rYEi46+gIzufyYUAoHDnRzkWGxajpD9vVXFQ3g1vbjrBm6P7MBmm+s/fqPa46sxa+8FOUdEuRQKaugo5a4JWpw==" "integrity": "sha512-rYEi46+gIzufyYUAoHDnRzkWGxajpD9vVXFQ3g1vbjrBm6P7MBmm+s/fqPa46sxa+8FOUdEuRQKaugo5a4JWpw=="
}, },
"@mui/base": { "@mui/base": {
"version": "5.0.0-alpha.73", "version": "5.0.0-alpha.74",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.73.tgz", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.74.tgz",
"integrity": "sha512-TEUCIIEAWrngAqpIa+dY3nofGSNj70LC3KC9WcCzyXPK3M4AG2GNi7ndd/g/0DtC55kbxrudzlV8TG3vrB2Vjw==", "integrity": "sha512-pw3T1xNXpW8pLo9+BvtyazZb0CSjNJsjbzznlbV/aNkBfjNPXQVI3X1NDm3WSI8y6M96WDIVO7XrHAohOwALSQ==",
"requires": { "requires": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@emotion/is-prop-valid": "^1.1.2", "@emotion/is-prop-valid": "^1.1.2",
"@mui/utils": "^5.4.4", "@mui/types": "^7.1.3",
"@mui/utils": "^5.5.3",
"@popperjs/core": "^2.11.4", "@popperjs/core": "^2.11.4",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
@@ -19728,15 +19730,15 @@
} }
}, },
"@mui/material": { "@mui/material": {
"version": "5.5.2", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.5.2.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.5.3.tgz",
"integrity": "sha512-r4p1u9eDlSqW3TS/Iq9yolifWHpuW6e0BSeqEJW3EEIcKfPVVk4WNUNJ+s8DtN7dBoDcveXxcQVVjYXTIv1d9g==", "integrity": "sha512-eADa3kUYbbr1jNjcufn0a7HeU8cSo0agbrkj720hodxVFNIfzq7a2e58Z+PaZqll55kMGBvlYJ7rTcXU399x5A==",
"requires": { "requires": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@mui/base": "5.0.0-alpha.73", "@mui/base": "5.0.0-alpha.74",
"@mui/system": "^5.5.2", "@mui/system": "^5.5.3",
"@mui/types": "^7.1.3", "@mui/types": "^7.1.3",
"@mui/utils": "^5.4.4", "@mui/utils": "^5.5.3",
"@types/react-transition-group": "^4.4.4", "@types/react-transition-group": "^4.4.4",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"csstype": "^3.0.11", "csstype": "^3.0.11",
@@ -19747,12 +19749,12 @@
} }
}, },
"@mui/private-theming": { "@mui/private-theming": {
"version": "5.4.4", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.4.4.tgz", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.5.3.tgz",
"integrity": "sha512-V/gxttr6736yJoU9q+4xxXsa0K/w9Hn9pg99zsOHt7i/O904w2CX5NHh5WqDXtoUzVcayLF0RB17yr6l79CE+A==", "integrity": "sha512-Wf7NurY7lk8SBWelSBY2U02zxLt1773JpIcXTHuEC9/GZdQA4CXCJGl2cVQzheKhee5rZ+8JwGulrRiVl1m+4A==",
"requires": { "requires": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@mui/utils": "^5.4.4", "@mui/utils": "^5.5.3",
"prop-types": "^15.7.2" "prop-types": "^15.7.2"
} }
}, },
@@ -19767,15 +19769,15 @@
} }
}, },
"@mui/system": { "@mui/system": {
"version": "5.5.2", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.5.2.tgz", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.5.3.tgz",
"integrity": "sha512-OATYFI36nliud8xh0u+ZNqDo0jWjxpO0vZLlzqNB+ZtkR5Q/+1X3GgboA9ruiB8Rq+udnJlMBQNGW0qqjvAOHQ==", "integrity": "sha512-J9JcySJuEqfEoP334K/2gEWm2vOx73Uqjii3qlFVhWRBOAJ0Pjyk0sN5W/eVRbwhUm95DNgh2V5s8dRK3vzyVw==",
"requires": { "requires": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@mui/private-theming": "^5.4.4", "@mui/private-theming": "^5.5.3",
"@mui/styled-engine": "^5.5.2", "@mui/styled-engine": "^5.5.2",
"@mui/types": "^7.1.3", "@mui/types": "^7.1.3",
"@mui/utils": "^5.4.4", "@mui/utils": "^5.5.3",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"csstype": "^3.0.11", "csstype": "^3.0.11",
"prop-types": "^15.7.2" "prop-types": "^15.7.2"
@@ -19788,9 +19790,9 @@
"requires": {} "requires": {}
}, },
"@mui/utils": { "@mui/utils": {
"version": "5.4.4", "version": "5.5.3",
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.4.4.tgz", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.5.3.tgz",
"integrity": "sha512-hfYIXEuhc2mXMGN5nUPis8beH6uE/zl3uMWJcyHX0/LN/+QxO9zhYuV6l8AsAaphHFyS/fBv0SW3Nid7jw5hKQ==", "integrity": "sha512-t627eVRpl3SlxVya0cIVNs8jPl4KCEiGaTSWY9iKKTcMNaeDbuRML+zv/CFHDPr1zFv+FjJSP02ySB+tZ8xIag==",
"requires": { "requires": {
"@babel/runtime": "^7.17.2", "@babel/runtime": "^7.17.2",
"@types/prop-types": "^15.7.4", "@types/prop-types": "^15.7.4",

View File

@@ -8,7 +8,7 @@
"@emotion/styled": "^11.8.1", "@emotion/styled": "^11.8.1",
"@msgpack/msgpack": "^2.7.2", "@msgpack/msgpack": "^2.7.2",
"@mui/icons-material": "^5.5.1", "@mui/icons-material": "^5.5.1",
"@mui/material": "^5.5.2", "@mui/material": "^5.5.3",
"@types/lodash": "^4.14.180", "@types/lodash": "^4.14.180",
"@types/node": "^17.0.23", "@types/node": "^17.0.23",
"@types/react": "^17.0.43", "@types/react": "^17.0.43",

View File

@@ -20,8 +20,7 @@ import {
ListItem, ListItem,
ListItemText, ListItemText,
Grid, Grid,
useMediaQuery, useMediaQuery
Tooltip
} from '@mui/material'; } from '@mui/material';
import TableCell, { tableCellClasses } from '@mui/material/TableCell'; import TableCell, { tableCellClasses } from '@mui/material/TableCell';
@@ -38,6 +37,8 @@ import CancelIcon from '@mui/icons-material/Cancel';
import SendIcon from '@mui/icons-material/TrendingFlat'; import SendIcon from '@mui/icons-material/TrendingFlat';
import SaveIcon from '@mui/icons-material/Save'; import SaveIcon from '@mui/icons-material/Save';
import RemoveIcon from '@mui/icons-material/RemoveCircleOutline'; import RemoveIcon from '@mui/icons-material/RemoveCircleOutline';
import FavoriteIcon from '@mui/icons-material/Favorite';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import DeviceIcon from './DeviceIcon'; import DeviceIcon from './DeviceIcon';
@@ -219,7 +220,7 @@ const DashboardData: FC = () => {
{deviceValue.l && ( {deviceValue.l && (
<ValidatedTextField <ValidatedTextField
name="v" name="v"
label={deviceValue.n} label={deviceValue.n.slice(2)}
value={deviceValue.v} value={deviceValue.v}
autoFocus autoFocus
sx={{ width: '30ch' }} sx={{ width: '30ch' }}
@@ -234,7 +235,7 @@ const DashboardData: FC = () => {
{!deviceValue.l && ( {!deviceValue.l && (
<ValidatedTextField <ValidatedTextField
name="v" name="v"
label={deviceValue.n} label={deviceValue.n.slice(2)}
value={deviceValue.u ? numberValue(deviceValue.v) : deviceValue.v} value={deviceValue.u ? numberValue(deviceValue.v) : deviceValue.v}
autoFocus autoFocus
sx={{ width: '30ch' }} sx={{ width: '30ch' }}
@@ -493,16 +494,29 @@ const DashboardData: FC = () => {
}; };
const renderNameCell = (dv: DeviceValue) => { const renderNameCell = (dv: DeviceValue) => {
var mask = Number(dv.n.slice(0, 2));
var name = dv.n.slice(2);
if (dv.v === undefined && dv.c) { if (dv.v === undefined && dv.c) {
return ( return (
<StyledTableCell component="th" scope="row" sx={{ color: 'yellow' }}> <StyledTableCell component="th" scope="row">
command:&nbsp;{dv.n} {name}&nbsp;
<PlayArrowIcon color="primary" sx={{ fontSize: 10 }} />
</StyledTableCell> </StyledTableCell>
); );
} }
if ((mask & 8) === 8) {
return (
<StyledTableCell component="th" scope="row">
{name}&nbsp;
<FavoriteIcon color="error" sx={{ fontSize: 10 }} />
</StyledTableCell>
);
}
return ( return (
<StyledTableCell component="th" scope="row"> <StyledTableCell component="th" scope="row">
{dv.n} {name}
</StyledTableCell> </StyledTableCell>
); );
}; };
@@ -526,9 +540,7 @@ const DashboardData: FC = () => {
<StyledTableCell padding="checkbox"> <StyledTableCell padding="checkbox">
{dv.c && me.admin && ( {dv.c && me.admin && (
<IconButton size="small"> <IconButton size="small">
<Tooltip title="Change value..."> <EditIcon color="primary" fontSize="small" />
<EditIcon color="primary" fontSize="small" />
</Tooltip>
</IconButton> </IconButton>
)} )}
</StyledTableCell> </StyledTableCell>

View File

@@ -14,8 +14,7 @@ import {
DialogContent, DialogContent,
DialogTitle, DialogTitle,
ToggleButton, ToggleButton,
ToggleButtonGroup, ToggleButtonGroup
Tooltip
} from '@mui/material'; } from '@mui/material';
import TableCell, { tableCellClasses } from '@mui/material/TableCell'; import TableCell, { tableCellClasses } from '@mui/material/TableCell';
@@ -117,10 +116,14 @@ const SettingsCustomization: FC = () => {
return ( return (
<> <>
<Box color="warning.main"> <Box mb={2} color="warning.main">
<Typography variant="body2"> <Typography variant="body2">
You can mark an entity as a favorite to be listed first in the Web Dashboard, or remove it from the You can mark an entity as a favorite to be listed first in the Dashboard (
Dashboard, or disable it's write operation or exclude it from the MQTT and API outputs. <FavoriteBorderOutlinedIcon fontSize="small" />) ,or remove it entirely from the Dashboard (
<VisibilityOffOutlinedIcon fontSize="small" />) ,or disable it's write operation (
<EditOffOutlinedIcon fontSize="small" />) or have it excluded from the MQTT and API outputs (
<CommentsDisabledOutlinedIcon fontSize="small" />
).
</Typography> </Typography>
</Box> </Box>
<ValidatedTextField <ValidatedTextField
@@ -174,19 +177,9 @@ const SettingsCustomization: FC = () => {
const setMask = (de: DeviceEntity, newMask: string[]) => { const setMask = (de: DeviceEntity, newMask: string[]) => {
var new_mask = 0; var new_mask = 0;
if (newMask.includes('1')) { for (let entry of newMask) {
new_mask |= 1; new_mask |= Number(entry);
} }
if (newMask.includes('2')) {
new_mask |= 2;
}
if (newMask.includes('4')) {
new_mask |= 4;
}
if (newMask.includes('8')) {
new_mask |= 8;
}
de.m = new_mask; de.m = new_mask;
setMasks(newMask); setMasks(newMask);
}; };
@@ -220,35 +213,27 @@ const SettingsCustomization: FC = () => {
</TableHead> </TableHead>
<TableBody> <TableBody>
{deviceEntities.map((de) => ( {deviceEntities.map((de) => (
<TableRow key={de.i}> <TableRow key={de.i} hover>
<StyledTableCell padding="checkbox"> <StyledTableCell padding="checkbox">
<ToggleButtonGroup <ToggleButtonGroup
size="small" size="small"
color="error" color="secondary"
value={getMask(de)} value={getMask(de)}
onChange={(event, mask) => { onChange={(event, mask) => {
setMask(de, mask); setMask(de, mask);
}} }}
> >
<ToggleButton value="8" color="success" disabled={(de.m & 1) !== 0}> <ToggleButton value="8" color="success" disabled={(de.m & 1) !== 0}>
<Tooltip title="Favorite"> <FavoriteBorderOutlinedIcon fontSize="small" />
<FavoriteBorderOutlinedIcon fontSize="small" />
</Tooltip>
</ToggleButton> </ToggleButton>
<ToggleButton value="4" disabled={!de.w}> <ToggleButton value="4" disabled={!de.w}>
<Tooltip title="Force read-only"> <EditOffOutlinedIcon fontSize="small" />
<EditOffOutlinedIcon fontSize="small" />
</Tooltip>
</ToggleButton> </ToggleButton>
<ToggleButton value="2"> <ToggleButton value="2">
<Tooltip title="Exclude in MQTT and API"> <CommentsDisabledOutlinedIcon fontSize="small" />
<CommentsDisabledOutlinedIcon fontSize="small" />
</Tooltip>
</ToggleButton> </ToggleButton>
<ToggleButton value="1"> <ToggleButton value="1">
<Tooltip title="Don't show Web Dashboard"> <VisibilityOffOutlinedIcon fontSize="small" />
<VisibilityOffOutlinedIcon fontSize="small" />
</Tooltip>
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
</StyledTableCell> </StyledTableCell>

View File

@@ -455,31 +455,31 @@ const emsesp_devicedata_1 = {
{ {
v: '(0)', v: '(0)',
u: 0, u: 0,
n: 'error code', n: '00error code',
c: '', c: '',
}, },
{ {
v: '14:54:39 06/06/2021', v: '14:54:39 06/06/2021',
u: 0, u: 0,
n: 'date/time', n: '00date/time',
c: '', c: '',
}, },
{ {
v: 18, v: 18,
u: 1, u: 1,
n: 'hc1 selected room temperature', n: '00hc1 selected room temperature',
c: 'hc1/seltemp', c: 'hc1/seltemp',
}, },
{ {
v: 22.6, v: 22.6,
u: 1, u: 1,
n: 'hc1 current room temperature', n: '00hc1 current room temperature',
c: '', c: '',
}, },
{ {
v: 'auto', v: 'auto',
u: 0, u: 0,
n: 'hc1 mode', n: '00hc1 mode',
c: 'hc1/mode', c: 'hc1/mode',
}, },
], ],
@@ -488,81 +488,81 @@ const emsesp_devicedata_1 = {
const emsesp_devicedata_2 = { const emsesp_devicedata_2 = {
label: 'Boiler: Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i', label: 'Boiler: Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i',
data: [ data: [
{ u: 0, n: 'reset', c: 'reset', l: ['-', 'maintenance', 'error'] }, { v: 'false', u: 0, n: '08heating active' },
{ v: 'false', u: 0, n: 'heating active' }, { v: 'false', u: 0, n: '08tapwater active' },
{ v: 'false', u: 0, n: 'tapwater active' }, { u: 0, n: '00reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
{ v: 5, u: 1, n: 'selected flow temperature', c: 'selflowtemp' }, { v: 5, u: 1, n: '00selected flow temperature', c: 'selflowtemp' },
{ v: 0, u: 3, n: 'burner selected max power', c: 'selburnpow' }, { v: 0, u: 3, n: '00burner selected max power', c: 'selburnpow' },
{ v: 0, u: 3, n: 'heating pump modulation' }, { v: 0, u: 3, n: '00heating pump modulation' },
{ v: 53.4, u: 1, n: 'current flow temperature' }, { v: 53.4, u: 1, n: '00current flow temperature' },
{ v: 52.7, u: 1, n: 'return temperature' }, { v: 52.7, u: 1, n: '00return temperature' },
{ v: 1.3, u: 10, n: 'system pressure' }, { v: 1.3, u: 10, n: '00system pressure' },
{ v: 54.9, u: 1, n: 'actual boiler temperature' }, { v: 54.9, u: 1, n: '00actual boiler temperature' },
{ v: 'false', u: 0, n: 'gas' }, { v: 'false', u: 0, n: '00gas' },
{ v: 'false', u: 0, n: 'gas stage 2' }, { v: 'false', u: 0, n: '00gas stage 2' },
{ v: 0, u: 9, n: 'flame current' }, { v: 0, u: 9, n: '00flame current' },
{ v: 'false', u: 0, n: 'heating pump' }, { v: 'false', u: 0, n: '00heating pump' },
{ v: 'false', u: 0, n: 'fan' }, { v: 'false', u: 0, n: '00fan' },
{ v: 'false', u: 0, n: 'ignition' }, { v: 'false', u: 0, n: '00ignition' },
{ v: 'false', u: 0, n: 'oil preheating' }, { v: 'false', u: 0, n: '00oil preheating' },
{ v: 'true', u: 0, n: 'heating activated', c: 'heatingactivated', l: ['off', 'on'] }, { v: 'true', u: 0, n: '00heating activated', c: 'heatingactivated', l: ['off', 'on'] },
{ v: 80, u: 1, n: 'heating temperature', c: 'heatingtemp' }, { v: 80, u: 1, n: '00heating temperature', c: 'heatingtemp' },
{ v: 70, u: 3, n: 'burner pump max power', c: 'pumpmodmax' }, { v: 70, u: 3, n: '00burner pump max power', c: 'pumpmodmax' },
{ v: 30, u: 3, n: 'burner pump min power', c: 'pumpmodmin' }, { v: 30, u: 3, n: '00burner pump min power', c: 'pumpmodmin' },
{ v: 1, u: 8, n: 'pump delay', c: 'pumpdelay' }, { v: 1, u: 8, n: '00pump delay', c: 'pumpdelay' },
{ v: 10, u: 8, n: 'burner min period', c: 'burnminperiod' }, { v: 10, u: 8, n: '00burner min period', c: 'burnminperiod' },
{ v: 0, u: 3, n: 'burner min power', c: 'burnminpower' }, { v: 0, u: 3, n: '00burner min power', c: 'burnminpower' },
{ v: 50, u: 3, n: 'burner max power', c: 'burnmaxpower' }, { v: 50, u: 3, n: '00burner max power', c: 'burnmaxpower' },
{ v: -6, u: 2, n: 'hysteresis on temperature', c: 'boilhyston' }, { v: -6, u: 2, n: '00hysteresis on temperature', c: 'boilhyston' },
{ v: 6, u: 2, n: 'hysteresis off temperature', c: 'boilhystoff' }, { v: 6, u: 2, n: '00hysteresis off temperature', c: 'boilhystoff' },
{ v: 0, u: 1, n: 'set flow temperature' }, { v: 0, u: 1, n: '00set flow temperature' },
{ v: 0, u: 3, n: 'burner set power' }, { v: 0, u: 3, n: '00burner set power' },
{ v: 0, u: 3, n: 'burner current power' }, { v: 0, u: 3, n: '00burner current power' },
{ v: 326323, u: 0, n: 'burner starts' }, { v: 326323, u: 0, n: '00burner starts' },
{ v: 553437, u: 8, n: 'total burner operating time' }, { v: 553437, u: 8, n: '00total burner operating time' },
{ v: 451286, u: 8, n: 'total heat operating time' }, { v: 451286, u: 8, n: '00total heat operating time' },
{ v: 4672173, u: 8, n: 'total UBA operating time' }, { v: 4672173, u: 8, n: '00total UBA operating time' },
{ v: '1C(210) 06.06.2020 12:07 (0 min)', u: 0, n: 'last error code' }, { v: '1C(210) 06.06.2020 12:07 (0 min)', u: 0, n: '00last error code' },
{ v: '0H', u: 0, n: 'service code' }, { v: '0H', u: 0, n: '00service code' },
{ v: 203, u: 0, n: 'service code number' }, { v: 203, u: 0, n: '00service code number' },
{ v: 'H00', u: 0, n: 'maintenance message' }, { v: 'H00', u: 0, n: '00maintenance message' },
{ v: 'manual', u: 0, n: 'maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] }, { v: 'manual', u: 0, n: '00maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] },
{ v: 6000, u: 7, n: 'time to next maintenance', c: 'maintenancetime' }, { v: 6000, u: 7, n: '00time to next maintenance', c: 'maintenancetime' },
{ v: '01.01.2012', u: 0, n: 'next maintenance date', c: 'maintenancedate', o: 'Format: < dd.mm.yyyy >' }, { v: '01.01.2012', u: 0, n: '00next maintenance date', c: 'maintenancedate', o: 'Format: < dd.mm.yyyy >' },
{ v: 'true', u: 0, n: 'dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] }, { v: 'true', u: 0, n: '00dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] },
{ v: 62, u: 1, n: 'dhw set temperature' }, { v: 62, u: 1, n: '00dhw set temperature' },
{ v: 60, u: 1, n: 'dhw selected temperature', c: 'wwseltemp' }, { v: 60, u: 1, n: '00dhw selected temperature', c: 'wwseltemp' },
{ v: 'flow', u: 0, n: 'dhw type' }, { v: 'flow', u: 0, n: '00dhw type' },
{ v: 'hot', u: 0, n: 'dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] }, { v: 'hot', u: 0, n: '00dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] },
{ v: 40, u: 2, n: 'dhw flow temperature offset', c: 'wwflowtempoffset' }, { v: 40, u: 2, n: '00dhw flow temperature offset', c: 'wwflowtempoffset' },
{ v: 100, u: 3, n: 'dhw max power', c: 'wwmaxpower' }, { v: 100, u: 3, n: '00dhw max power', c: 'wwmaxpower' },
{ v: 'false', u: 0, n: 'dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] }, { v: 'false', u: 0, n: '00dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] },
{ v: '3-way valve', u: 0, n: 'dhw charging type' }, { v: '3-way valve', u: 0, n: '00dhw charging type' },
{ v: -5, u: 2, n: 'dhw hysteresis on temperature', c: 'wwhyston' }, { v: -5, u: 2, n: '00dhw hysteresis on temperature', c: 'wwhyston' },
{ v: 0, u: 2, n: 'dhw hysteresis off temperature', c: 'wwhystoff' }, { v: 0, u: 2, n: '00dhw hysteresis off temperature', c: 'wwhystoff' },
{ v: 70, u: 1, n: 'dhw disinfection temperature', c: 'wwdisinfectiontemp' }, { v: 70, u: 1, n: '00dhw disinfection temperature', c: 'wwdisinfectiontemp' },
{ {
v: 'off', v: 'off',
u: 0, u: 0,
n: 'dhw circulation pump mode', n: '00dhw circulation pump mode',
c: 'wwcircmode', c: 'wwcircmode',
l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'], l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous'],
}, },
{ v: 'false', u: 0, n: 'dhw circulation active', c: 'wwcirc', l: ['off', 'on'] }, { v: 'false', u: 0, n: '00dhw circulation active', c: 'wwcirc', l: ['off', 'on'] },
{ v: 47.3, u: 1, n: 'dhw current intern temperature' }, { v: 47.3, u: 1, n: '00dhw current intern temperature' },
{ v: 0, u: 4, n: 'dhw current tap water flow' }, { v: 0, u: 4, n: '00dhw current tap water flow' },
{ v: 47.3, u: 1, n: 'dhw storage intern temperature' }, { v: 47.3, u: 1, n: '00dhw storage intern temperature' },
{ v: 'true', u: 0, n: 'dhw activated', c: 'wwactivated', l: ['off', 'on'] }, { v: 'true', u: 0, n: '00dhw activated', c: 'wwactivated', l: ['off', 'on'] },
{ v: 'false', u: 0, n: 'dhw one time charging', c: 'wwonetime', l: ['off', 'on'] }, { v: 'false', u: 0, n: '00dhw one time charging', c: 'wwonetime', l: ['off', 'on'] },
{ v: 'false', u: 0, n: 'dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] }, { v: 'false', u: 0, n: '00dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] },
{ v: 'false', u: 0, n: 'dhw charging' }, { v: 'false', u: 0, n: '00dhw charging' },
{ v: 'false', u: 0, n: 'dhw recharging' }, { v: 'false', u: 0, n: '00dhw recharging' },
{ v: 'true', u: 0, n: 'dhw temperature ok' }, { v: 'true', u: 0, n: '00dhw temperature ok' },
{ v: 'false', u: 0, n: 'dhw active' }, { v: 'false', u: 0, n: '00dhw active' },
{ v: 'true', u: 0, n: 'dhw 3way valve active' }, { v: 'true', u: 0, n: '00dhw 3way valve active' },
{ v: 0, u: 3, n: 'dhw set pump power' }, { v: 0, u: 3, n: '00dhw set pump power' },
{ v: 288768, u: 0, n: 'dhw starts' }, { v: 288768, u: 0, n: '00dhw starts' },
{ v: 102151, u: 8, n: 'dhw active time' }, { v: 102151, u: 8, n: '00dhw active time' },
], ],
} }
@@ -572,19 +572,19 @@ const emsesp_devicedata_4 = {
{ {
v: 16, v: 16,
u: 1, u: 1,
n: 'hc2 selected room temperature', n: '00hc2 selected room temperature',
c: 'hc2/seltemp', c: 'hc2/seltemp',
}, },
{ {
v: 18.6, v: 18.6,
u: 1, u: 1,
n: 'hc2 current room temperature', n: '00hc2 current room temperature',
c: '', c: '',
}, },
{ {
v: 'off', v: 'off',
u: 0, u: 0,
n: 'hc2 mode', n: '00hc2 mode',
c: 'hc2/mode', c: 'hc2/mode',
}, },
], ],
@@ -593,21 +593,21 @@ const emsesp_devicedata_4 = {
const emsesp_deviceentities_1 = [ const emsesp_deviceentities_1 = [
{ {
v: '(0)', v: '(0)',
n: 'error code', n: '00error code',
s: 'errorcode', s: 'errorcode',
m: 0, m: 0,
i: 1, i: 1,
}, },
{ {
v: '14:54:39 06/06/2021', v: '14:54:39 06/06/2021',
n: 'date/time', n: '00date/time',
s: 'datetime', s: 'datetime',
m: 0, m: 0,
i: 2, i: 2,
}, },
{ {
v: 18.22, v: 18.22,
n: 'hc1 selected room temperature', n: '00hc1 selected room temperature',
s: 'hc1/seltemp', s: 'hc1/seltemp',
m: 0, m: 0,
w: true, w: true,
@@ -615,14 +615,14 @@ const emsesp_deviceentities_1 = [
}, },
{ {
v: 22.6, v: 22.6,
n: 'hc1 current room temperature', n: '00hc1 current room temperature',
s: 'hc1/curtemp', s: 'hc1/curtemp',
m: 0, m: 0,
i: 4, i: 4,
}, },
{ {
v: 'auto', v: 'auto',
n: 'hc1 mode', n: '00hc1 mode',
s: 'hc1/mode', s: 'hc1/mode',
m: 0, m: 0,
w: true, w: true,

View File

@@ -637,119 +637,116 @@ void EMSdevice::generate_values_web(JsonObject & output) {
output["label"] = to_string_short(); output["label"] = to_string_short();
JsonArray data = output.createNestedArray("data"); JsonArray data = output.createNestedArray("data");
// sort the device values // do two passes. First for all entities marked as favourites, then for all others. This sorts the list.
std::sort(devicevalues_.begin(), devicevalues_.end(), [](const emsesp::DeviceValue & a, const emsesp::DeviceValue & b __attribute__((unused))) { for (uint8_t i = 0; i < 2; i++) {
return a.has_state(DeviceValueState::DV_FAVORITE); for (auto & dv : devicevalues_) {
}); bool state = (!i && dv.has_state(DeviceValueState::DV_FAVORITE)) || (i && !dv.has_state(DeviceValueState::DV_FAVORITE));
if (state && (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.full_name && (dv.hasValue() || (dv.type == DeviceValueType::CMD)))) {
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value
uint8_t fahrenheit = 0;
for (auto & dv : devicevalues_) { // handle Booleans (true, false)
// check conditions: if (dv.type == DeviceValueType::BOOL) {
// 1. full_name cannot be empty bool value_b = *(bool *)(dv.value_p);
// 2. it must have a valid value, if it is not a command like 'reset' if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
obj["v"] = value_b ? "true" : "false";
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
obj["v"] = value_b ? 1 : 0;
} else {
char s[7];
obj["v"] = Helpers::render_boolean(s, value_b);
}
}
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.full_name && (dv.hasValue() || (dv.type == DeviceValueType::CMD))) { // handle TEXT strings
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value else if (dv.type == DeviceValueType::STRING) {
uint8_t fahrenheit = 0; obj["v"] = (char *)(dv.value_p);
}
// handle Booleans (true, false) // handle ENUMs
if (dv.type == DeviceValueType::BOOL) { else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) {
bool value_b = *(bool *)(dv.value_p); obj["v"] = dv.options[*(uint8_t *)(dv.value_p)];
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) { }
obj["v"] = value_b ? "true" : "false";
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) { // handle numbers
obj["v"] = value_b ? 1 : 0; else {
// If a divider is specified, do the division to 2 decimals places and send back as double/float
// otherwise force as an integer whole
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0;
fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(int8_t *)(dv.value_p), divider, fahrenheit);
} else if ((dv.type == DeviceValueType::UINT) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(uint8_t *)(dv.value_p), divider, fahrenheit);
} else if ((dv.type == DeviceValueType::SHORT) && Helpers::hasValue(*(int16_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(int16_t *)(dv.value_p), divider, fahrenheit);
} else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(uint16_t *)(dv.value_p), divider, fahrenheit);
} else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(uint32_t *)(dv.value_p), divider, fahrenheit);
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
uint32_t time_value = *(uint32_t *)(dv.value_p);
obj["v"] = (divider > 0) ? time_value / divider : time_value; // sometimes we need to divide by 60
}
}
// add the unit of measure (uom)
obj["u"] = fahrenheit ? (uint8_t)DeviceValueUOM::FAHRENHEIT : dv.uom;
auto mask = Helpers::hextoa((uint8_t)(dv.state >> 4), false); // create mask to a 2-char string
// add name, prefixing the tag if it exists
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["n"] = mask + read_flash_string(dv.full_name);
} else if (dv.tag < DeviceValueTAG::TAG_HC1) {
obj["n"] = mask + tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name);
} else { } else {
char s[7]; obj["n"] = mask + tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name);
obj["v"] = Helpers::render_boolean(s, value_b);
} }
}
// handle TEXT strings // add commands and options
else if (dv.type == DeviceValueType::STRING) { if (dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY)) {
obj["v"] = (char *)(dv.value_p); // add the name of the Command function
} if (dv.tag >= DeviceValueTAG::TAG_HC1) {
obj["c"] = tag_to_mqtt(dv.tag) + "/" + read_flash_string(dv.short_name);
// handle ENUMs } else {
else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) { obj["c"] = dv.short_name;
obj["v"] = dv.options[*(uint8_t *)(dv.value_p)]; }
} // add the Command options
if (dv.type == DeviceValueType::ENUM || (dv.type == DeviceValueType::CMD && dv.options_size > 1)) {
// handle numbers JsonArray l = obj.createNestedArray("l");
else { for (uint8_t i = 0; i < dv.options_size; i++) {
// If a divider is specified, do the division to 2 decimals places and send back as double/float if (!read_flash_string(dv.options[i]).empty()) {
// otherwise force as an integer whole l.add(read_flash_string(dv.options[i]));
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler }
int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0; }
fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; } else if (dv.type == DeviceValueType::BOOL) {
JsonArray l = obj.createNestedArray("l");
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) { l.add("off");
obj["v"] = Helpers::round2(*(int8_t *)(dv.value_p), divider, fahrenheit); l.add("on");
} else if ((dv.type == DeviceValueType::UINT) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) { }
obj["v"] = Helpers::round2(*(uint8_t *)(dv.value_p), divider, fahrenheit); // add command help template
} else if ((dv.type == DeviceValueType::SHORT) && Helpers::hasValue(*(int16_t *)(dv.value_p))) { else if (dv.type == DeviceValueType::STRING || dv.type == DeviceValueType::CMD) {
obj["v"] = Helpers::round2(*(int16_t *)(dv.value_p), divider, fahrenheit); if (dv.options_size == 1) {
} else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) { obj["h"] = dv.options[0];
obj["v"] = Helpers::round2(*(uint16_t *)(dv.value_p), divider, fahrenheit);
} else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(uint32_t *)(dv.value_p), divider, fahrenheit);
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
uint32_t time_value = *(uint32_t *)(dv.value_p);
obj["v"] = (divider > 0) ? time_value / divider : time_value; // sometimes we need to divide by 60
}
}
// add the unit of measure (uom)
obj["u"] = fahrenheit ? (uint8_t)DeviceValueUOM::FAHRENHEIT : dv.uom;
// add name, prefixing the tag if it exists
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["n"] = dv.full_name;
} else if (dv.tag < DeviceValueTAG::TAG_HC1) {
obj["n"] = tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name);
} else {
obj["n"] = tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name);
}
// add commands and options
if (dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY)) {
// add the name of the Command function
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
obj["c"] = tag_to_mqtt(dv.tag) + "/" + read_flash_string(dv.short_name);
} else {
obj["c"] = dv.short_name;
}
// add the Command options
if (dv.type == DeviceValueType::ENUM || (dv.type == DeviceValueType::CMD && dv.options_size > 1)) {
JsonArray l = obj.createNestedArray("l");
for (uint8_t i = 0; i < dv.options_size; i++) {
if (!read_flash_string(dv.options[i]).empty()) {
l.add(read_flash_string(dv.options[i]));
} }
} }
} else if (dv.type == DeviceValueType::BOOL) { // add steps to numeric values with divider/multiplier
JsonArray l = obj.createNestedArray("l"); else {
l.add("off"); int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0;
l.add("on"); char s[10];
} if (divider > 0) {
// add command help template obj["s"] = Helpers::render_value(s, (float)1 / divider, 1);
else if (dv.type == DeviceValueType::STRING || dv.type == DeviceValueType::CMD) { } else if (divider < 0) {
if (dv.options_size == 1) { obj["s"] = Helpers::render_value(s, (-1) * divider, 0);
obj["h"] = dv.options[0]; }
} int16_t dv_set_min, dv_set_max;
} if (dv.get_min_max(dv_set_min, dv_set_max)) {
// add steps to numeric values with divider/multiplier obj["m"] = Helpers::render_value(s, dv_set_min, 0);
else { obj["x"] = Helpers::render_value(s, dv_set_max, 0);
int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0; }
char s[10];
if (divider > 0) {
obj["s"] = Helpers::render_value(s, (float)1 / divider, 1);
} else if (divider < 0) {
obj["s"] = Helpers::render_value(s, (-1) * divider, 0);
}
int16_t dv_set_min, dv_set_max;
if (dv.get_min_max(dv_set_min, dv_set_max)) {
obj["m"] = Helpers::render_value(s, dv_set_min, 0);
obj["x"] = Helpers::render_value(s, dv_set_max, 0);
} }
} }
} }
@@ -853,7 +850,7 @@ void EMSdevice::generate_values_web_all(JsonArray & output) {
// this is called before loading in the exclude entities list from the customization service // this is called before loading in the exclude entities list from the customization service
void EMSdevice::reset_entity_masks() { void EMSdevice::reset_entity_masks() {
for (auto & dv : devicevalues_) { for (auto & dv : devicevalues_) {
dv.state &= 0x0F; dv.state &= 0x0F; // clear high nibble
} }
} }

View File

@@ -988,7 +988,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
// create the topic, depending on the type and whether the device entity is writable (a command) // create the topic, depending on the type and whether the device entity is writable (a command)
// https://developers.home-assistant.io/docs/core/entity // https://developers.home-assistant.io/docs/core/entity
char topic[MQTT_TOPIC_MAX_SIZE]; char topic[MQTT_TOPIC_MAX_SIZE];
// if it's a command then we can use Number, Switch. Otherwise stick to Sensor // if it's a command then we can use Number, Switch, Select. Otherwise stick to Sensor
if (has_cmd) { if (has_cmd) {
switch (type) { switch (type) {
case DeviceValueType::INT: case DeviceValueType::INT:
@@ -996,13 +996,13 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
case DeviceValueType::SHORT: case DeviceValueType::SHORT:
case DeviceValueType::USHORT: case DeviceValueType::USHORT:
case DeviceValueType::ULONG: case DeviceValueType::ULONG:
// number - https://www.home-assistant.io/integrations/number.mqtt/ // number - https://www.home-assistant.io/integrations/number.mqtt
// https://developers.home-assistant.io/docs/core/entity/number // https://developers.home-assistant.io/docs/core/entity/number
snprintf(topic, sizeof(topic), "number/%s/%s/config", mqtt_base_.c_str(), uniq); snprintf(topic, sizeof(topic), "number/%s/%s/config", mqtt_base_.c_str(), uniq);
break; break;
case DeviceValueType::BOOL: case DeviceValueType::BOOL:
// switch - https://www.home-assistant.io/integrations/switch.mqtt/ // switch - https://www.home-assistant.io/integrations/switch.mqtt
snprintf(topic, sizeof(topic), "switch/%s/%s/config", mqtt_base_.c_str(), uniq); snprintf(topic, sizeof(topic), "switch/%s/%s/config", mqtt_base_.c_str(), uniq);
break; break;
case DeviceValueType::ENUM: case DeviceValueType::ENUM:

View File

@@ -208,7 +208,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request, J
request->send(response); request->send(response);
} }
// takes a list of masked ids send from the webUI // takes a list of masked ids sent from the webUI
// saves it in the customization service // saves it in the customization service
// and updates the entity list real-time // and updates the entity list real-time
void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, JsonVariant & json) { void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, JsonVariant & json) {