updates to data view

This commit is contained in:
Proddy
2023-05-11 18:19:47 +02:00
parent 6575e1d790
commit 4f8d3d27ba
15 changed files with 117 additions and 123 deletions

View File

@@ -25,6 +25,8 @@
"regex": "cpp", "regex": "cpp",
"tuple": "cpp", "tuple": "cpp",
"type_traits": "cpp", "type_traits": "cpp",
"utility": "cpp" "utility": "cpp",
"string": "cpp",
"string_view": "cpp"
} }
} }

View File

@@ -37,7 +37,6 @@ const de: Translation = {
BRAND: 'Marke', BRAND: 'Marke',
ENTITY_NAME: 'Entitätsname', ENTITY_NAME: 'Entitätsname',
VALUE: '{{Wert|wert}}', VALUE: '{{Wert|wert}}',
SHOW_FAV: 'nur Favoriten anzeigen',
DEVICE_DATA: 'Gerätedaten', DEVICE_DATA: 'Gerätedaten',
SENSOR_DATA: 'Sensordaten', SENSOR_DATA: 'Sensordaten',
DEVICES: 'Geräte', DEVICES: 'Geräte',

View File

@@ -37,7 +37,6 @@ const en: Translation = {
BRAND: 'Brand', BRAND: 'Brand',
ENTITY_NAME: 'Entity Name', ENTITY_NAME: 'Entity Name',
VALUE: '{{Value|value}}', VALUE: '{{Value|value}}',
SHOW_FAV: 'only show favorites',
DEVICE_DATA: 'Device Data', DEVICE_DATA: 'Device Data',
SENSOR_DATA: 'Sensor Data', SENSOR_DATA: 'Sensor Data',
DEVICES: 'Devices', DEVICES: 'Devices',

View File

@@ -37,7 +37,6 @@ const fr: Translation = {
BRAND: 'Marque', BRAND: 'Marque',
ENTITY_NAME: 'Nom de l\'entité', ENTITY_NAME: 'Nom de l\'entité',
VALUE: 'Valeur', VALUE: 'Valeur',
SHOW_FAV: 'ne montrer que les favoris',
DEVICE_DATA: 'Données des appareils', DEVICE_DATA: 'Données des appareils',
SENSOR_DATA: 'Données des capteurs', SENSOR_DATA: 'Données des capteurs',
DEVICES: 'Appareils', DEVICES: 'Appareils',

View File

@@ -37,7 +37,6 @@ const nl: Translation = {
BRAND: 'Merk', BRAND: 'Merk',
ENTITY_NAME: 'Entiteit', ENTITY_NAME: 'Entiteit',
VALUE: '{{Waarde|waarde}}', VALUE: '{{Waarde|waarde}}',
SHOW_FAV: 'alleen favorieten weergeven',
SENSOR_DATA: 'Sensor data', SENSOR_DATA: 'Sensor data',
DEVICE_DATA: 'Apparaat data', DEVICE_DATA: 'Apparaat data',
DEVICES: 'Apparaten', DEVICES: 'Apparaten',

View File

@@ -37,7 +37,6 @@ const no: Translation = {
BRAND: 'Fabrikat', BRAND: 'Fabrikat',
ENTITY_NAME: 'Objektsnavn', ENTITY_NAME: 'Objektsnavn',
VALUE: '{{Verdi|verdi}}', VALUE: '{{Verdi|verdi}}',
SHOW_FAV: ' Vis kun favoritter',
DEVICE_DATA: 'Enheterdata', DEVICE_DATA: 'Enheterdata',
SENSOR_DATA: 'Sensordata', SENSOR_DATA: 'Sensordata',
DEVICES: 'Enheter', DEVICES: 'Enheter',

View File

@@ -37,7 +37,6 @@ const pl: BaseTranslation = {
VERSION: 'Wersja', VERSION: 'Wersja',
ENTITY_NAME: 'Nazwa encji', ENTITY_NAME: 'Nazwa encji',
VALUE: '{{W|w|}}artość', VALUE: '{{W|w|}}artość',
SHOW_FAV: 'Pokaż tylko "ulubione"',
DEVICE_DATA: 'Dane z urządzeń', DEVICE_DATA: 'Dane z urządzeń',
SENSOR_DATA: 'Dane z czujników', SENSOR_DATA: 'Dane z czujników',
DEVICES: 'Urządzenia', DEVICES: 'Urządzenia',

View File

@@ -37,7 +37,6 @@ const sv: Translation = {
BRAND: 'Fabrikat', BRAND: 'Fabrikat',
ENTITY_NAME: 'Entitetsnamn', ENTITY_NAME: 'Entitetsnamn',
VALUE: '{{Värde|värde}}', VALUE: '{{Värde|värde}}',
SHOW_FAV: 'Visa enbart favoriter',
DEVICE_DATA: 'Enhets data', DEVICE_DATA: 'Enhets data',
SENSOR_DATA: 'Sensor data', SENSOR_DATA: 'Sensor data',
DEVICES: 'Enheter', DEVICES: 'Enheter',

View File

@@ -37,7 +37,6 @@ const tr: Translation = {
BRAND: 'Marka', BRAND: 'Marka',
ENTITY_NAME: 'Valık Adı', ENTITY_NAME: 'Valık Adı',
VALUE: '{{Değer|değer}}', VALUE: '{{Değer|değer}}',
SHOW_FAV: 'sadece favorileri göster',
DEVICE_DATA: 'Cihaz Bilgisi', DEVICE_DATA: 'Cihaz Bilgisi',
SENSOR_DATA: 'Sensör Bilgisi', SENSOR_DATA: 'Sensör Bilgisi',
DEVICES: 'Cihazlar', DEVICES: 'Cihazlar',

View File

@@ -9,6 +9,7 @@ import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutl
import PlayArrowIcon from '@mui/icons-material/PlayArrow'; import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import RefreshIcon from '@mui/icons-material/Refresh'; import RefreshIcon from '@mui/icons-material/Refresh';
import StarIcon from '@mui/icons-material/Star'; import StarIcon from '@mui/icons-material/Star';
import StarBorderOutlinedIcon from '@mui/icons-material/StarBorderOutlined';
import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined'; import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
import { import {
@@ -21,8 +22,6 @@ import {
List, List,
ListItem, ListItem,
ListItemText, ListItemText,
FormControlLabel,
Checkbox,
Box, Box,
Grid, Grid,
Typography Typography
@@ -54,13 +53,15 @@ import { extractErrorMessage } from 'utils';
const DashboardDevices: FC = () => { const DashboardDevices: FC = () => {
const { me } = useContext(AuthenticatedContext); const { me } = useContext(AuthenticatedContext);
const { LL } = useI18nContext(); const { LL } = useI18nContext();
const [deviceData, setDeviceData] = useState<DeviceData>({ label: '', data: [] }); const [deviceData, setDeviceData] = useState<DeviceData>({ data: [] });
const [selectedDeviceValue, setSelectedDeviceValue] = useState<DeviceValue>(); const [selectedDeviceValue, setSelectedDeviceValue] = useState<DeviceValue>();
const [deviceDetails, setDeviceDetails] = useState<number>(-1);
const [onlyFav, setOnlyFav] = useState(false); const [onlyFav, setOnlyFav] = useState(false);
const [selectedDevice, setSelectedDevice] = useState<number>();
const [deviceValueDialogOpen, setDeviceValueDialogOpen] = useState(false); const [deviceValueDialogOpen, setDeviceValueDialogOpen] = useState(false);
const [showDeviceInfo, setShowDeviceInfo] = useState<boolean>(false);
const [selectedDevice, setSelectedDevice] = useState<number>();
const [coreData, setCoreData] = useState<CoreData>({ const [coreData, setCoreData] = useState<CoreData>({
connected: true, connected: true,
devices: [] devices: []
@@ -95,11 +96,6 @@ const DashboardDevices: FC = () => {
border-top: 1px solid #177ac9; border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9; border-bottom: 1px solid #177ac9;
} }
`,
Cell: `
&:last-of-type {
text-align: right;
},
` `
}); });
@@ -107,7 +103,7 @@ const DashboardDevices: FC = () => {
common_theme, common_theme,
{ {
Table: ` Table: `
--data-table-library_grid-template-columns: 40px 160px repeat(1, minmax(0, 1fr)) 100px 40px; --data-table-library_grid-template-columns: 40px 160px repeat(1, minmax(0, 1fr));
`, `,
BaseRow: ` BaseRow: `
.td { .td {
@@ -136,7 +132,11 @@ const DashboardDevices: FC = () => {
Table: ` Table: `
--data-table-library_grid-template-columns: 300px 150px 40px; --data-table-library_grid-template-columns: 300px 150px 40px;
height: auto; height: auto;
max-height: 92%; max-height: 96%;
overflow-y: scroll;
::-webkit-scrollbar {
display:none;
}
`, `,
BaseCell: ` BaseCell: `
&:nth-of-type(2) { &:nth-of-type(2) {
@@ -192,6 +192,7 @@ const DashboardDevices: FC = () => {
}; };
function onSelectChange(action: any, state: any) { function onSelectChange(action: any, state: any) {
setDeviceData({ data: [] });
setSelectedDevice(state.id); setSelectedDevice(state.id);
if (action.type === 'ADD_BY_ID_EXCLUSIVELY') { if (action.type === 'ADD_BY_ID_EXCLUSIVELY') {
void fetchDeviceData(state.id); void fetchDeviceData(state.id);
@@ -205,13 +206,20 @@ const DashboardDevices: FC = () => {
} }
); );
const escFunction = useCallback((event) => { const resetDeviceSelect = () => {
device_select.fns.onRemoveAll();
};
const escFunction = useCallback(
(event: any) => {
if (event.keyCode === 27) { if (event.keyCode === 27) {
if (device_select) { if (device_select) {
device_select.fns.onRemoveAll(); resetDeviceSelect();
} }
} }
}, []); },
[device_select]
);
useEffect(() => { useEffect(() => {
document.addEventListener('keydown', escFunction); document.addEventListener('keydown', escFunction);
@@ -288,10 +296,18 @@ const DashboardDevices: FC = () => {
}, },
{ accessor: (dv: any) => DeviceValueUOM_s[dv.u], name: 'UoM' } { accessor: (dv: any) => DeviceValueUOM_s[dv.u], name: 'UoM' }
]; ];
// TODO create filename from selected device
const deviceIndex = coreData.devices.findIndex((d) => d.id === device_select.state.id);
if (deviceIndex === -1) {
return;
}
const filename = coreData.devices[deviceIndex].tn + '_' + coreData.devices[deviceIndex].n;
downloadAsCsv( downloadAsCsv(
columns, columns,
onlyFav ? deviceData.data.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE)) : deviceData.data, onlyFav ? deviceData.data.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE)) : deviceData.data,
'device_entities' filename
); );
}; };
@@ -326,42 +342,47 @@ const DashboardDevices: FC = () => {
}; };
const renderDeviceDetails = () => { const renderDeviceDetails = () => {
if (coreData && coreData.devices.length > 0 && deviceDetails !== -1) { if (showDeviceInfo) {
const device = coreData.devices[deviceDetails]; // find record based on device_seelct.state.id
const deviceIndex = coreData.devices.findIndex((d) => d.id === device_select.state.id);
if (deviceIndex === -1) {
return;
}
return ( return (
<Dialog open={deviceDetails !== -1} onClose={() => setDeviceDetails(-1)}> <Dialog open={showDeviceInfo} onClose={() => setShowDeviceInfo(false)}>
<DialogTitle>{LL.DEVICE_DETAILS()}</DialogTitle> <DialogTitle>{LL.DEVICE_DETAILS()}</DialogTitle>
<DialogContent dividers> <DialogContent dividers>
<List dense={true}> <List dense={true}>
<ListItem> <ListItem>
<ListItemText primary={LL.TYPE(0)} secondary={device.tn} /> <ListItemText primary={LL.TYPE(0)} secondary={coreData.devices[deviceIndex].tn} />
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemText primary={LL.NAME(0)} secondary={device.n} /> <ListItemText primary={LL.NAME(0)} secondary={coreData.devices[deviceIndex].n} />
</ListItem> </ListItem>
{device.t !== DeviceType.CUSTOM && ( {coreData.devices[deviceIndex].t !== DeviceType.CUSTOM && (
<> <>
<ListItem> <ListItem>
<ListItemText primary={LL.BRAND()} secondary={device.b} /> <ListItemText primary={LL.BRAND()} secondary={coreData.devices[deviceIndex].b} />
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemText <ListItemText
primary={LL.ID_OF(LL.DEVICE())} primary={LL.ID_OF(LL.DEVICE())}
secondary={'0x' + ('00' + device.d.toString(16).toUpperCase()).slice(-2)} secondary={'0x' + ('00' + coreData.devices[deviceIndex].d.toString(16).toUpperCase()).slice(-2)}
/> />
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemText primary={LL.ID_OF(LL.PRODUCT())} secondary={device.p} /> <ListItemText primary={LL.ID_OF(LL.PRODUCT())} secondary={coreData.devices[deviceIndex].p} />
</ListItem> </ListItem>
<ListItem> <ListItem>
<ListItemText primary={LL.VERSION()} secondary={device.v} /> <ListItemText primary={LL.VERSION()} secondary={coreData.devices[deviceIndex].v} />
</ListItem> </ListItem>
</> </>
)} )}
</List> </List>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button variant="outlined" onClick={() => setDeviceDetails(-1)} color="secondary"> <Button variant="outlined" onClick={() => setShowDeviceInfo(false)} color="secondary">
{LL.CLOSE()} {LL.CLOSE()}
</Button> </Button>
</DialogActions> </DialogActions>
@@ -385,24 +406,16 @@ const DashboardDevices: FC = () => {
<HeaderCell stiff /> <HeaderCell stiff />
<HeaderCell stiff>{LL.TYPE(0)}</HeaderCell> <HeaderCell stiff>{LL.TYPE(0)}</HeaderCell>
<HeaderCell resize>{LL.DESCRIPTION()}</HeaderCell> <HeaderCell resize>{LL.DESCRIPTION()}</HeaderCell>
<HeaderCell stiff>{LL.ENTITIES()}</HeaderCell>
<HeaderCell stiff />
</HeaderRow> </HeaderRow>
</Header> </Header>
<Body> <Body>
{tableList.map((device: Device, index: number) => ( {tableList.map((device: Device) => (
<Row key={device.id} item={device}> <Row key={device.id} item={device}>
<Cell stiff> <Cell stiff>
<DeviceIcon type_id={device.t} /> <DeviceIcon type_id={device.t} />
</Cell> </Cell>
<Cell stiff>{device.tn}</Cell> <Cell stiff>{device.tn}</Cell>
<Cell>{device.n}</Cell> <Cell>{device.n}</Cell>
<Cell stiff>{device.e}</Cell>
<Cell stiff>
<IconButton size="small" onClick={() => setDeviceDetails(index)}>
<InfoOutlinedIcon color="info" sx={{ fontSize: 16, verticalAlign: 'middle' }} />
</IconButton>
</Cell>
</Row> </Row>
))} ))}
</Body> </Body>
@@ -439,13 +452,28 @@ const DashboardDevices: FC = () => {
</> </>
); );
const shown_data = onlyFav
? deviceData.data.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE))
: deviceData.data;
function truncate(str, length) {
if (str.length > length) {
return str.slice(0, length) + '...';
} else return str;
}
const deviceIndex = coreData.devices.findIndex((d) => d.id === device_select.state.id);
if (deviceIndex === -1) {
return;
}
return ( return (
<Box <Box
sx={{ sx={{
backgroundColor: 'black', backgroundColor: 'black',
position: 'absolute', position: 'absolute',
right: 32, right: 16,
bottom: 8, bottom: 16,
top: 128, top: 128,
border: '1px solid #177ac9', border: '1px solid #177ac9',
zIndex: 'modal' zIndex: 'modal'
@@ -453,45 +481,33 @@ const DashboardDevices: FC = () => {
> >
<Grid container justifyContent="space-between"> <Grid container justifyContent="space-between">
<Box color="warning.main" ml={1}> <Box color="warning.main" ml={1}>
<Typography variant="h6">{deviceData.label}</Typography> <Typography variant="h6">
{truncate(coreData.devices[deviceIndex].n, 35)}
&nbsp;({shown_data.length})
<IconButton sx={{ ml: 1 }} onClick={() => setShowDeviceInfo(true)}>
<InfoOutlinedIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} />
</IconButton>
<IconButton onClick={handleDownloadCsv}>
<DownloadIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} />
</IconButton>
<IconButton onClick={() => setOnlyFav(!onlyFav)}>
{onlyFav ? (
<StarIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} />
) : (
<StarBorderOutlinedIcon color="primary" sx={{ fontSize: 18, verticalAlign: 'middle' }} />
)}
</IconButton>
</Typography>
</Box> </Box>
<Grid item justifyContent="flex-end"> <Grid item justifyContent="flex-end">
<Button <IconButton onClick={resetDeviceSelect}>
startIcon={<CancelIcon />} <CancelIcon color="info" sx={{ fontSize: 16, verticalAlign: 'middle' }} />
size="small" </IconButton>
color="info"
onClick={() => device_select.fns.onRemoveAll()}
/>
</Grid> </Grid>
</Grid> </Grid>
<Grid item>
<FormControlLabel
control={<Checkbox size="small" name="onlyFav" checked={onlyFav} onChange={() => setOnlyFav(!onlyFav)} />}
label={
<span style={{ fontSize: '12px' }}>
{LL.SHOW_FAV()}&nbsp;(
<StarIcon color="primary" sx={{ fontSize: 12 }} />)
</span>
}
labelPlacement="start"
/>
<Button
sx={{ ml: 28 }}
startIcon={<DownloadIcon />}
size="small"
variant="outlined"
onClick={handleDownloadCsv}
>
{LL.EXPORT()}
</Button>
</Grid>
<Table <Table
data={{ data={{ nodes: shown_data }}
nodes: onlyFav
? deviceData.data.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE))
: deviceData.data
}}
theme={data_theme} theme={data_theme}
sort={dv_sort} sort={dv_sort}
layout={{ custom: true, fixedHeader: true }} layout={{ custom: true, fixedHeader: true }}

View File

@@ -68,7 +68,6 @@ export interface Device {
d: number; // deviceid d: number; // deviceid
p: number; // productid p: number; // productid
v: string; // version v: string; // version
e: number; // number of entries
} }
export interface TemperatureSensor { export interface TemperatureSensor {
@@ -134,7 +133,6 @@ export interface DeviceValue {
} }
export interface DeviceData { export interface DeviceData {
label: string;
data: DeviceValue[]; data: DeviceValue[];
} }

View File

@@ -395,8 +395,7 @@ const emsesp_coredata = {
n: 'GBx72/Trendline/Cerapur/Greenstar Si/27i', n: 'GBx72/Trendline/Cerapur/Greenstar Si/27i',
d: 8, d: 8,
p: 123, p: 123,
v: '06.01', v: '06.01'
e: 68
}, },
{ {
id: 3, id: 3,
@@ -406,8 +405,7 @@ const emsesp_coredata = {
n: 'GB125/GB135/MC10', n: 'GB125/GB135/MC10',
d: 8, d: 8,
p: 123, p: 123,
v: '06.01', v: '06.01'
e: 56
}, },
{ {
id: 1, id: 1,
@@ -417,8 +415,7 @@ const emsesp_coredata = {
n: 'RC35', n: 'RC35',
d: 24, d: 24,
p: 86, p: 86,
v: '04.01', v: '04.01'
e: 58
}, },
{ {
id: 2, id: 2,
@@ -428,8 +425,7 @@ const emsesp_coredata = {
n: 'RC20/Moduline 300', n: 'RC20/Moduline 300',
d: 23, d: 23,
p: 77, p: 77,
v: '03.03', v: '03.03'
e: 6
}, },
{ {
id: 4, id: 4,
@@ -439,8 +435,7 @@ const emsesp_coredata = {
n: 'RC100/Moduline 1000/1010', n: 'RC100/Moduline 1000/1010',
d: 16, d: 16,
p: 165, p: 165,
v: '04.01', v: '04.01'
e: 3
}, },
{ {
id: 5, id: 5,
@@ -450,8 +445,7 @@ const emsesp_coredata = {
n: 'MM10', n: 'MM10',
d: 32, d: 32,
p: 69, p: 69,
v: '01.01', v: '01.01'
e: 6
}, },
{ {
id: 6, id: 6,
@@ -461,8 +455,7 @@ const emsesp_coredata = {
n: 'SM10', n: 'SM10',
d: 48, d: 48,
p: 73, p: 73,
v: '01.02', v: '01.02'
e: 16
}, },
{ {
id: 99, id: 99,
@@ -472,8 +465,7 @@ const emsesp_coredata = {
n: 'User defined entities', n: 'User defined entities',
d: 1, d: 1,
p: 1, p: 1,
v: '', v: ''
e: 1
} }
] ]
}; };
@@ -526,7 +518,6 @@ const status = {
// 99 - Custom // 99 - Custom
const emsesp_devicedata_7 = { const emsesp_devicedata_7 = {
label: 'Boiler: Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i',
data: [ data: [
{ v: '', u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] }, { v: '', u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
{ v: 'off', u: 0, id: '08heating active' }, { v: 'off', u: 0, id: '08heating active' },
@@ -607,7 +598,6 @@ const emsesp_devicedata_7 = {
}; };
const emsesp_devicedata_1 = { const emsesp_devicedata_1 = {
label: 'Thermostat: RC35',
data: [ data: [
{ {
v: '22(816) 01.05.2023 13:07 (1 min)', v: '22(816) 01.05.2023 13:07 (1 min)',
@@ -1040,7 +1030,6 @@ const emsesp_devicedata_1 = {
}; };
const emsesp_devicedata_2 = { const emsesp_devicedata_2 = {
label: 'Thermostat: RC20/Moduline 300',
data: [ data: [
{ {
v: '(0)', v: '(0)',
@@ -1084,7 +1073,6 @@ const emsesp_devicedata_2 = {
}; };
const emsesp_devicedata_3 = { const emsesp_devicedata_3 = {
label: 'Boiler: GB125/GB135/MC10',
data: [ data: [
{ {
v: '', v: '',
@@ -1557,7 +1545,6 @@ const emsesp_devicedata_3 = {
}; };
const emsesp_devicedata_4 = { const emsesp_devicedata_4 = {
label: 'Thermostat: RC100/Moduline 1000/1010',
data: [ data: [
{ {
v: 16, v: 16,
@@ -1582,7 +1569,6 @@ const emsesp_devicedata_4 = {
}; };
const emsesp_devicedata_5 = { const emsesp_devicedata_5 = {
label: 'Mixer Module: MM10',
data: [ data: [
{ {
v: 30, v: 30,
@@ -1630,7 +1616,6 @@ const emsesp_devicedata_5 = {
}; };
const emsesp_devicedata_6 = { const emsesp_devicedata_6 = {
label: 'Solar Module: SM10',
data: [ data: [
{ {
v: 43.9, v: 43.9,
@@ -1780,7 +1765,6 @@ const emsesp_devicedata_6 = {
}; };
const emsesp_devicedata_99 = { const emsesp_devicedata_99 = {
label: 'User defined entities',
data: [ data: [
{ {
v: 5, v: 5,

View File

@@ -824,7 +824,8 @@ std::string EMSdevice::get_value_uom(const char * key) const {
// except additional data is stored in the JSON document needed for the Web UI like the UOM and command // except additional data is stored in the JSON document needed for the Web UI like the UOM and command
// v=value, u=uom, n=name, c=cmd, h=help string, s=step, m=min, x=max // v=value, u=uom, n=name, c=cmd, h=help string, s=step, m=min, x=max
void EMSdevice::generate_values_web(JsonObject & output) { void EMSdevice::generate_values_web(JsonObject & output) {
output["label"] = to_string_short(); // output["label"] = to_string_short();
// output["label"] = name_;
JsonArray data = output.createNestedArray("data"); JsonArray data = output.createNestedArray("data");
for (auto & dv : devicevalues_) { for (auto & dv : devicevalues_) {

View File

@@ -1124,6 +1124,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
emsdevices.push_back(EMSFactory::add(device_type, device_id, product_id, version, name, flags, brand)); emsdevices.push_back(EMSFactory::add(device_type, device_id, product_id, version, name, flags, brand));
// assign a unique ID. Note that this is not actual unique after a restart as it's dependent on the order that devices are found // assign a unique ID. Note that this is not actual unique after a restart as it's dependent on the order that devices are found
// can't be 0 otherwise web won't work
emsdevices.back()->unique_id(++unique_id_count_); emsdevices.back()->unique_id(++unique_id_count_);
// sort devices based on type // sort devices based on type

View File

@@ -88,7 +88,7 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
obj["d"] = emsdevice->device_id(); // deviceid obj["d"] = emsdevice->device_id(); // deviceid
obj["p"] = emsdevice->product_id(); // productid obj["p"] = emsdevice->product_id(); // productid
obj["v"] = emsdevice->version(); // version obj["v"] = emsdevice->version(); // version
obj["e"] = emsdevice->count_entities(); // number of entities (device values) // obj["e"] = emsdevice->count_entities(); // number of entities (device values)
} }
} }
@@ -103,7 +103,7 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
obj["d"] = 0; // deviceid obj["d"] = 0; // deviceid
obj["p"] = 0; // productid obj["p"] = 0; // productid
obj["v"] = 0; // version obj["v"] = 0; // version
obj["e"] = EMSESP::webEntityService.count_entities(); // number of entities (device values) // obj["e"] = EMSESP::webEntityService.count_entities(); // number of entities (device values)
} }
root["connected"] = EMSESP::bus_status() != 2; root["connected"] = EMSESP::bus_status() != 2;