mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
add export button
This commit is contained in:
@@ -24,10 +24,11 @@ import { useSnackbar } from 'notistack';
|
|||||||
|
|
||||||
import { Table } from '@table-library/react-table-library/table';
|
import { Table } from '@table-library/react-table-library/table';
|
||||||
import { useTheme } from '@table-library/react-table-library/theme';
|
import { useTheme } from '@table-library/react-table-library/theme';
|
||||||
import { useSort, HeaderCellSort } from '@table-library/react-table-library/sort';
|
import { useSort } from '@table-library/react-table-library/sort';
|
||||||
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
import { useRowSelect } from '@table-library/react-table-library/select';
|
import { useRowSelect } from '@table-library/react-table-library/select';
|
||||||
|
|
||||||
|
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
|
||||||
@@ -98,8 +99,8 @@ const DashboardData: FC = () => {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
HeaderRow: `
|
HeaderRow: `
|
||||||
|
text-transform: uppercase;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
font-size: 14px;
|
|
||||||
border-bottom: 1px solid #e0e0e0;
|
border-bottom: 1px solid #e0e0e0;
|
||||||
`,
|
`,
|
||||||
Row: `
|
Row: `
|
||||||
@@ -165,8 +166,9 @@ const DashboardData: FC = () => {
|
|||||||
height: 32px;
|
height: 32px;
|
||||||
`,
|
`,
|
||||||
HeaderRow: `
|
HeaderRow: `
|
||||||
|
text-transform: uppercase;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
font-size: 14px;
|
color: #90CAF9;
|
||||||
border-bottom: 1px solid #e0e0e0;
|
border-bottom: 1px solid #e0e0e0;
|
||||||
`,
|
`,
|
||||||
Row: `
|
Row: `
|
||||||
@@ -195,6 +197,7 @@ const DashboardData: FC = () => {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
BaseCell: `
|
BaseCell: `
|
||||||
|
padding-left: 8px;
|
||||||
border-top: 1px solid transparent;
|
border-top: 1px solid transparent;
|
||||||
border-right: 1px solid transparent;
|
border-right: 1px solid transparent;
|
||||||
border-bottom: 1px solid transparent;
|
border-bottom: 1px solid transparent;
|
||||||
@@ -202,9 +205,22 @@ const DashboardData: FC = () => {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
min-width: 64px;
|
min-width: 64px;
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
HeaderCell: `
|
||||||
|
padding-left: 0px;
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getSortIcon = (state: any, sortKey: any) => {
|
||||||
|
if (state.sortKey === sortKey && state.reverse) {
|
||||||
|
return <KeyboardArrowDownOutlinedIcon />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.sortKey === sortKey && !state.reverse) {
|
||||||
|
return <KeyboardArrowUpOutlinedIcon />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const analog_sort = useSort(
|
const analog_sort = useSort(
|
||||||
{ nodes: sensorData.analogs },
|
{ nodes: sensorData.analogs },
|
||||||
{
|
{
|
||||||
@@ -222,7 +238,8 @@ const DashboardData: FC = () => {
|
|||||||
sortFns: {
|
sortFns: {
|
||||||
GPIO: (array) => array.sort((a, b) => a.i - b.i),
|
GPIO: (array) => array.sort((a, b) => a.i - b.i),
|
||||||
NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)),
|
NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)),
|
||||||
TYPE: (array) => array.sort((a, b) => a.t - b.t)
|
TYPE: (array) => array.sort((a, b) => a.t - b.t),
|
||||||
|
VALUE: (array) => array.sort((a, b) => a.v.toString().localeCompare(b.v.toString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -250,16 +267,21 @@ const DashboardData: FC = () => {
|
|||||||
|
|
||||||
const dv_sort = useSort(
|
const dv_sort = useSort(
|
||||||
{ nodes: deviceData.data },
|
{ nodes: deviceData.data },
|
||||||
{},
|
{
|
||||||
|
state: {
|
||||||
|
sortKey: 'NAME',
|
||||||
|
reverse: false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
sortIcon: {
|
sortIcon: {
|
||||||
margin: '0px',
|
|
||||||
iconDefault: null,
|
iconDefault: null,
|
||||||
iconUp: <KeyboardArrowUpOutlinedIcon />,
|
iconUp: <KeyboardArrowUpOutlinedIcon />,
|
||||||
iconDown: <KeyboardArrowDownOutlinedIcon />
|
iconDown: <KeyboardArrowDownOutlinedIcon />
|
||||||
},
|
},
|
||||||
sortFns: {
|
sortFns: {
|
||||||
NAME: (array) => array.sort((a, b) => a.id.slice(2).localeCompare(b.id.slice(2)))
|
NAME: (array) => array.sort((a, b) => a.id.slice(2).localeCompare(b.id.slice(2))),
|
||||||
|
VALUE: (array) => array.sort((a, b) => a.v.toString().localeCompare(b.v.toString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -279,6 +301,52 @@ const DashboardData: FC = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const escapeCsvCell = (cell: any) => {
|
||||||
|
if (cell == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const sc = cell.toString().trim();
|
||||||
|
if (sc === '' || sc === '""') {
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
if (sc.includes('"') || sc.includes(',') || sc.includes('\n') || sc.includes('\r')) {
|
||||||
|
return '"' + sc.replace(/"/g, '""') + '"';
|
||||||
|
}
|
||||||
|
return sc;
|
||||||
|
};
|
||||||
|
|
||||||
|
const makeCsvData = (columns: any, data: any) => {
|
||||||
|
return data.reduce((csvString: any, rowItem: any) => {
|
||||||
|
return csvString + columns.map(({ accessor }: any) => escapeCsvCell(accessor(rowItem))).join(',') + '\r\n';
|
||||||
|
}, columns.map(({ name }: any) => escapeCsvCell(name)).join(',') + '\r\n');
|
||||||
|
};
|
||||||
|
|
||||||
|
const downloadAsCsv = (columns: any, data: any, filename: string) => {
|
||||||
|
const csvData = makeCsvData(columns, data);
|
||||||
|
const csvFile = new Blob([csvData], { type: 'text/csv' });
|
||||||
|
const downloadLink = document.createElement('a');
|
||||||
|
|
||||||
|
downloadLink.download = filename;
|
||||||
|
downloadLink.href = window.URL.createObjectURL(csvFile);
|
||||||
|
document.body.appendChild(downloadLink);
|
||||||
|
downloadLink.click();
|
||||||
|
document.body.removeChild(downloadLink);
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasMask = (id: string, mask: number) => (parseInt(id.slice(0, 2), 16) & mask) === mask;
|
||||||
|
|
||||||
|
const handleDownloadCsv = () => {
|
||||||
|
const columns = [
|
||||||
|
{ accessor: (dv: any) => dv.id.slice(2), name: 'Entity' },
|
||||||
|
{ accessor: (dv: any) => formatValue(dv.v, dv.u), name: 'Value' }
|
||||||
|
];
|
||||||
|
downloadAsCsv(
|
||||||
|
columns,
|
||||||
|
onlyFav ? deviceData.data.filter((dv) => hasMask(dv.id, DeviceEntityMask.DV_FAVORITE)) : deviceData.data,
|
||||||
|
'device_entities'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const refreshData = () => {
|
const refreshData = () => {
|
||||||
const selectedDevice = device_select.state.id;
|
const selectedDevice = device_select.state.id;
|
||||||
if (selectedDevice === 'sensor') {
|
if (selectedDevice === 'sensor') {
|
||||||
@@ -451,7 +519,7 @@ const DashboardData: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const addAnalogSensor = () => {
|
const addAnalogSensor = () => {
|
||||||
setAnalog({ id: '0', n: '', u: 0, v: 0, o: 0, t: 0, f: 1 });
|
setAnalog({ id: '0', i: 0, n: '', u: 0, v: 0, o: 0, t: 0, f: 1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendSensor = async () => {
|
const sendSensor = async () => {
|
||||||
@@ -585,8 +653,6 @@ const DashboardData: FC = () => {
|
|||||||
return <FormLoader errorMessage={errorMessage} />;
|
return <FormLoader errorMessage={errorMessage} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('** Rendering main data');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconContext.Provider value={{ color: 'lightblue', size: '24', style: { verticalAlign: 'middle' } }}>
|
<IconContext.Provider value={{ color: 'lightblue', size: '24', style: { verticalAlign: 'middle' } }}>
|
||||||
{coreData.devices.length === 0 && <MessageBox my={2} level="warning" message="Scanning for EMS devices..." />}
|
{coreData.devices.length === 0 && <MessageBox my={2} level="warning" message="Scanning for EMS devices..." />}
|
||||||
@@ -647,8 +713,6 @@ const DashboardData: FC = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasMask = (id: string, mask: number) => (parseInt(id.slice(0, 2), 16) & mask) === mask;
|
|
||||||
|
|
||||||
const sendCommand = (dv: DeviceValue) => {
|
const sendCommand = (dv: DeviceValue) => {
|
||||||
if (dv.c && me.admin && !hasMask(dv.id, DeviceEntityMask.DV_READONLY)) {
|
if (dv.c && me.admin && !hasMask(dv.id, DeviceEntityMask.DV_READONLY)) {
|
||||||
setDeviceValue(dv);
|
setDeviceValue(dv);
|
||||||
@@ -672,8 +736,8 @@ const DashboardData: FC = () => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={<Checkbox name="onlyFav" checked={onlyFav} onChange={() => setOnlyFav(!onlyFav)} />}
|
control={<Checkbox size="small" name="onlyFav" checked={onlyFav} onChange={() => setOnlyFav(!onlyFav)} />}
|
||||||
label="show favorites only"
|
label={<span style={{ fontSize: '12px' }}>favorites only</span>}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
@@ -689,10 +753,26 @@ const DashboardData: FC = () => {
|
|||||||
<>
|
<>
|
||||||
<Header>
|
<Header>
|
||||||
<HeaderRow>
|
<HeaderRow>
|
||||||
<HeaderCellSort resize sortKey="NAME">
|
<HeaderCell resize>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(dv_sort.state, 'NAME')}
|
||||||
|
onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'NAME' })}
|
||||||
|
>
|
||||||
ENTITY NAME
|
ENTITY NAME
|
||||||
</HeaderCellSort>
|
</Button>
|
||||||
<HeaderCell>VALUE</HeaderCell>
|
</HeaderCell>
|
||||||
|
<HeaderCell>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(dv_sort.state, 'VALUE')}
|
||||||
|
onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'VALUE' })}
|
||||||
|
>
|
||||||
|
VALUE
|
||||||
|
</Button>
|
||||||
|
</HeaderCell>
|
||||||
<HeaderCell />
|
<HeaderCell />
|
||||||
</HeaderRow>
|
</HeaderRow>
|
||||||
</Header>
|
</Header>
|
||||||
@@ -745,10 +825,26 @@ const DashboardData: FC = () => {
|
|||||||
<>
|
<>
|
||||||
<Header>
|
<Header>
|
||||||
<HeaderRow>
|
<HeaderRow>
|
||||||
<HeaderCellSort resize sortKey="NAME">
|
<HeaderCell resize>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(sensor_sort.state, 'NAME')}
|
||||||
|
onClick={() => sensor_sort.fns.onToggleSort({ sortKey: 'NAME' })}
|
||||||
|
>
|
||||||
NAME
|
NAME
|
||||||
</HeaderCellSort>
|
</Button>
|
||||||
<HeaderCellSort sortKey="TEMPERATURE">TEMPERATURE</HeaderCellSort>
|
</HeaderCell>
|
||||||
|
<HeaderCell>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(sensor_sort.state, 'TEMPERATURE')}
|
||||||
|
onClick={() => sensor_sort.fns.onToggleSort({ sortKey: 'TEMPERATURE' })}
|
||||||
|
>
|
||||||
|
TEMPERATURE
|
||||||
|
</Button>
|
||||||
|
</HeaderCell>
|
||||||
<HeaderCell />
|
<HeaderCell />
|
||||||
</HeaderRow>
|
</HeaderRow>
|
||||||
</Header>
|
</Header>
|
||||||
@@ -784,16 +880,46 @@ const DashboardData: FC = () => {
|
|||||||
<>
|
<>
|
||||||
<Header>
|
<Header>
|
||||||
<HeaderRow>
|
<HeaderRow>
|
||||||
<HeaderCellSort resize sortKey="GPIO">
|
<HeaderCell resize>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(analog_sort.state, 'GPIO')}
|
||||||
|
onClick={() => analog_sort.fns.onToggleSort({ sortKey: 'GPIO' })}
|
||||||
|
>
|
||||||
GPIO
|
GPIO
|
||||||
</HeaderCellSort>
|
</Button>
|
||||||
<HeaderCellSort resize sortKey="NAME">
|
</HeaderCell>
|
||||||
|
<HeaderCell resize>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(analog_sort.state, 'NAME')}
|
||||||
|
onClick={() => analog_sort.fns.onToggleSort({ sortKey: 'NAME' })}
|
||||||
|
>
|
||||||
NAME
|
NAME
|
||||||
</HeaderCellSort>
|
</Button>
|
||||||
<HeaderCellSort resize sortKey="TYPE">
|
</HeaderCell>
|
||||||
|
<HeaderCell resize>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(analog_sort.state, 'TYPE')}
|
||||||
|
onClick={() => analog_sort.fns.onToggleSort({ sortKey: 'TYPE' })}
|
||||||
|
>
|
||||||
TYPE
|
TYPE
|
||||||
</HeaderCellSort>
|
</Button>
|
||||||
<HeaderCell>VALUE</HeaderCell>
|
</HeaderCell>
|
||||||
|
<HeaderCell>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
||||||
|
endIcon={getSortIcon(analog_sort.state, 'VALUE')}
|
||||||
|
onClick={() => analog_sort.fns.onToggleSort({ sortKey: 'VALUE' })}
|
||||||
|
>
|
||||||
|
VALUE
|
||||||
|
</Button>
|
||||||
|
</HeaderCell>
|
||||||
<HeaderCell />
|
<HeaderCell />
|
||||||
</HeaderRow>
|
</HeaderRow>
|
||||||
</Header>
|
</Header>
|
||||||
@@ -803,7 +929,7 @@ const DashboardData: FC = () => {
|
|||||||
<Cell>{a.id}</Cell>
|
<Cell>{a.id}</Cell>
|
||||||
<Cell>{a.n}</Cell>
|
<Cell>{a.n}</Cell>
|
||||||
<Cell>{AnalogTypeNames[a.t]} </Cell>
|
<Cell>{AnalogTypeNames[a.t]} </Cell>
|
||||||
<Cell>{formatValue(a.v, a.u)}</Cell>
|
<Cell>{a.t ? formatValue(a.v, a.u) : ''}</Cell>
|
||||||
<Cell>
|
<Cell>
|
||||||
{me.admin && (
|
{me.admin && (
|
||||||
<IconButton onClick={() => updateAnalog(a)}>
|
<IconButton onClick={() => updateAnalog(a)}>
|
||||||
@@ -824,7 +950,7 @@ const DashboardData: FC = () => {
|
|||||||
if (analog) {
|
if (analog) {
|
||||||
try {
|
try {
|
||||||
const response = await EMSESP.writeAnalog({
|
const response = await EMSESP.writeAnalog({
|
||||||
id: analog.id,
|
i: analog.i,
|
||||||
name: analog.n,
|
name: analog.n,
|
||||||
offset: analog.o,
|
offset: analog.o,
|
||||||
factor: analog.f,
|
factor: analog.f,
|
||||||
@@ -852,7 +978,7 @@ const DashboardData: FC = () => {
|
|||||||
if (analog) {
|
if (analog) {
|
||||||
try {
|
try {
|
||||||
const response = await EMSESP.writeAnalog({
|
const response = await EMSESP.writeAnalog({
|
||||||
id: analog.id,
|
i: analog.i,
|
||||||
name: analog.n,
|
name: analog.n,
|
||||||
offset: analog.o,
|
offset: analog.o,
|
||||||
factor: analog.f,
|
factor: analog.f,
|
||||||
@@ -885,11 +1011,10 @@ const DashboardData: FC = () => {
|
|||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<ValidatedTextField
|
<ValidatedTextField
|
||||||
name="id"
|
name="i"
|
||||||
label="GPIO"
|
label="GPIO"
|
||||||
value={analog.id}
|
value={analog.i}
|
||||||
// TODO add validation
|
type="number"
|
||||||
// type="number"
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
autoFocus
|
autoFocus
|
||||||
onChange={updateValue(setAnalog)}
|
onChange={updateValue(setAnalog)}
|
||||||
@@ -1084,6 +1209,11 @@ const DashboardData: FC = () => {
|
|||||||
<Button startIcon={<RefreshIcon />} variant="outlined" color="secondary" onClick={refreshData}>
|
<Button startIcon={<RefreshIcon />} variant="outlined" color="secondary" onClick={refreshData}>
|
||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
|
{device_select.state.id && device_select.state.id !== 'sensor' && (
|
||||||
|
<Button startIcon={<DownloadIcon />} variant="outlined" onClick={handleDownloadCsv}>
|
||||||
|
Export
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</ButtonRow>
|
</ButtonRow>
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -88,9 +88,10 @@ export interface Sensor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Analog {
|
export interface Analog {
|
||||||
id: string; // id string, is GPIO
|
id: string; // id string
|
||||||
|
i: number; // GPIO
|
||||||
n: string;
|
n: string;
|
||||||
v?: number;
|
v: number; // is optional
|
||||||
u: number;
|
u: number;
|
||||||
o: number;
|
o: number;
|
||||||
f: number;
|
f: number;
|
||||||
@@ -127,10 +128,10 @@ export interface Devices {
|
|||||||
|
|
||||||
export interface DeviceValue {
|
export interface DeviceValue {
|
||||||
id: string; // index, contains mask+name
|
id: string; // index, contains mask+name
|
||||||
v?: any; // value, in any format
|
v: any; // value, in any format
|
||||||
u: number; // uom
|
u: number; // uom
|
||||||
c?: string; // command
|
c?: string; // command, optional
|
||||||
l?: string[]; // list
|
l?: string[]; // list, optional
|
||||||
h?: string; // help text, optional
|
h?: string; // help text, optional
|
||||||
s?: string; // steps for up/down, optional
|
s?: string; // steps for up/down, optional
|
||||||
m?: string; // min, optional
|
m?: string; // min, optional
|
||||||
@@ -277,7 +278,7 @@ export interface WriteValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface WriteAnalog {
|
export interface WriteAnalog {
|
||||||
id: string;
|
i: number;
|
||||||
name: string;
|
name: string;
|
||||||
factor: number;
|
factor: number;
|
||||||
offset: number;
|
offset: number;
|
||||||
|
|||||||
@@ -410,10 +410,10 @@ const emsesp_sensordata = {
|
|||||||
],
|
],
|
||||||
// sensors: [],
|
// sensors: [],
|
||||||
analogs: [
|
analogs: [
|
||||||
{ id: '36', n: 'motor', u: 0, o: 17, f: 0, t: 0 },
|
{ id: '36', i: 36, n: 'motor', v: 0, u: 0, o: 17, f: 0, t: 0 },
|
||||||
{ id: '37', n: 'External switch', v: 13, u: 0, o: 17, f: 0, t: 1 },
|
{ id: '37', i: 37, n: 'External switch', v: 13, u: 0, o: 17, f: 0, t: 1 },
|
||||||
{ id: '39', n: 'Pulse count', v: 144, u: 0, o: 0, f: 0, t: 2 },
|
{ id: '39', i: 39, n: 'Pulse count', v: 144, u: 0, o: 0, f: 0, t: 2 },
|
||||||
{ id: '40', n: 'Pressure', v: 16, u: 17, o: 0, f: 0, t: 3 },
|
{ id: '40', i: 40, n: 'Pressure', v: 16, u: 17, o: 0, f: 0, t: 3 },
|
||||||
],
|
],
|
||||||
// analogs: [],
|
// analogs: [],
|
||||||
}
|
}
|
||||||
@@ -485,7 +485,7 @@ 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, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
|
{ v: 0, u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
|
||||||
{ v: 'false', u: 0, id: '08heating active' },
|
{ v: 'false', u: 0, id: '08heating active' },
|
||||||
{ v: 'false', u: 0, id: '04tapwater active' },
|
{ v: 'false', u: 0, id: '04tapwater active' },
|
||||||
{ v: 5, u: 1, id: '04selected flow temperature', c: 'selflowtemp' },
|
{ v: 5, u: 1, id: '04selected flow temperature', c: 'selflowtemp' },
|
||||||
@@ -872,7 +872,6 @@ rest_server.get(EMSESP_CORE_DATA_ENDPOINT, (req, res) => {
|
|||||||
})
|
})
|
||||||
rest_server.get(EMSESP_SENSOR_DATA_ENDPOINT, (req, res) => {
|
rest_server.get(EMSESP_SENSOR_DATA_ENDPOINT, (req, res) => {
|
||||||
console.log('send back sensor data...')
|
console.log('send back sensor data...')
|
||||||
|
|
||||||
res.json(emsesp_sensordata)
|
res.json(emsesp_sensordata)
|
||||||
})
|
})
|
||||||
rest_server.get(EMSESP_DEVICES_ENDPOINT, (req, res) => {
|
rest_server.get(EMSESP_DEVICES_ENDPOINT, (req, res) => {
|
||||||
@@ -996,12 +995,13 @@ rest_server.post(EMSESP_WRITE_SENSOR_ENDPOINT, (req, res) => {
|
|||||||
rest_server.post(EMSESP_WRITE_ANALOG_ENDPOINT, (req, res) => {
|
rest_server.post(EMSESP_WRITE_ANALOG_ENDPOINT, (req, res) => {
|
||||||
const analog = req.body
|
const analog = req.body
|
||||||
console.log('Write analog: ' + JSON.stringify(analog))
|
console.log('Write analog: ' + JSON.stringify(analog))
|
||||||
objIndex = emsesp_sensordata.analogs.findIndex((obj) => obj.id == analog.id)
|
objIndex = emsesp_sensordata.analogs.findIndex((obj) => obj.i == analog.i)
|
||||||
|
|
||||||
if (objIndex === -1) {
|
if (objIndex === -1) {
|
||||||
console.log('new analog')
|
console.log('new analog')
|
||||||
emsesp_sensordata.analogs.push({
|
emsesp_sensordata.analogs.push({
|
||||||
id: analog.id,
|
id: analog.i.toString(),
|
||||||
|
i: analog.i,
|
||||||
n: analog.name,
|
n: analog.name,
|
||||||
f: analog.factor,
|
f: analog.factor,
|
||||||
o: analog.offset,
|
o: analog.offset,
|
||||||
@@ -1010,9 +1010,10 @@ rest_server.post(EMSESP_WRITE_ANALOG_ENDPOINT, (req, res) => {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (analog.type === -1) {
|
if (analog.type === -1) {
|
||||||
console.log('removing analog ' + analog.id)
|
console.log('removing analog ' + analog.i)
|
||||||
emsesp_sensordata.analogs[objIndex].t = -1
|
emsesp_sensordata.analogs[objIndex].t = -1
|
||||||
} else {
|
} else {
|
||||||
|
console.log('updating analog ' + analog.i)
|
||||||
emsesp_sensordata.analogs[objIndex].n = analog.name
|
emsesp_sensordata.analogs[objIndex].n = analog.name
|
||||||
emsesp_sensordata.analogs[objIndex].o = analog.offset
|
emsesp_sensordata.analogs[objIndex].o = analog.offset
|
||||||
emsesp_sensordata.analogs[objIndex].f = analog.factor
|
emsesp_sensordata.analogs[objIndex].f = analog.factor
|
||||||
|
|||||||
Reference in New Issue
Block a user