mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
@@ -24,8 +24,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alova/adapter-xhr": "^1.0.6",
|
"@alova/adapter-xhr": "^1.0.6",
|
||||||
"@alova/scene-react": "^1.6.1",
|
"@alova/scene-react": "^1.6.1",
|
||||||
"@emotion/react": "^11.12.0",
|
"@emotion/react": "^11.13.0",
|
||||||
"@emotion/styled": "^11.12.0",
|
"@emotion/styled": "^11.13.0",
|
||||||
"@mui/icons-material": "^5.16.4",
|
"@mui/icons-material": "^5.16.4",
|
||||||
"@mui/material": "^5.16.4",
|
"@mui/material": "^5.16.4",
|
||||||
"@table-library/react-table-library": "4.1.7",
|
"@table-library/react-table-library": "4.1.7",
|
||||||
|
|||||||
@@ -31,13 +31,22 @@ import type { LogEntry, LogSettings } from 'types';
|
|||||||
import { LogLevel } from 'types';
|
import { LogLevel } from 'types';
|
||||||
import { updateValueDirty, useRest } from 'utils';
|
import { updateValueDirty, useRest } from 'utils';
|
||||||
|
|
||||||
const LogEntryLine = styled('div')(() => ({
|
const ButtonTextColors = {
|
||||||
color: '#bbbbbb',
|
[LogLevel.ERROR]: '#ff0000', // red
|
||||||
fontFamily: 'monospace',
|
[LogLevel.WARNING]: '#ffcc00', // yellow
|
||||||
fontSize: '14px',
|
[LogLevel.NOTICE]: '#ffffff', // white
|
||||||
letterSpacing: 'normal',
|
[LogLevel.INFO]: '#ffffff', // yellow
|
||||||
|
[LogLevel.DEBUG]: '#00ffff', // cyan
|
||||||
|
[LogLevel.TRACE]: '#00ffff' // cyan
|
||||||
|
};
|
||||||
|
|
||||||
|
const LogEntryLine = styled('div')(
|
||||||
|
({ details: { level } }: { details: { level: LogLevel } }) => ({
|
||||||
|
color: ButtonTextColors[level],
|
||||||
|
font: '14px monospace',
|
||||||
whiteSpace: 'nowrap'
|
whiteSpace: 'nowrap'
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const topOffset = () =>
|
const topOffset = () =>
|
||||||
document.getElementById('log-window')?.getBoundingClientRect().bottom || 0;
|
document.getElementById('log-window')?.getBoundingClientRect().bottom || 0;
|
||||||
@@ -265,7 +274,7 @@ const SystemLog: FC = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{logEntries.map((e) => (
|
{logEntries.map((e) => (
|
||||||
<LogEntryLine key={e.i}>
|
<LogEntryLine details={{ level: e.l }} key={e.i}>
|
||||||
<span>{e.t}</span>
|
<span>{e.t}</span>
|
||||||
<span>{paddedLevelLabel(e.l)} </span>
|
<span>{paddedLevelLabel(e.l)} </span>
|
||||||
<span>{paddedIDLabel(e.i)} </span>
|
<span>{paddedIDLabel(e.i)} </span>
|
||||||
|
|||||||
@@ -64,8 +64,10 @@ const CustomEntitiesDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const close = () => {
|
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
@@ -90,7 +92,7 @@ const CustomEntitiesDialog = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog sx={dialogStyle} open={open} onClose={close}>
|
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
{creating ? LL.ADD(1) + ' ' + LL.NEW(1) : LL.EDIT()} {LL.ENTITY()}
|
{creating ? LL.ADD(1) + ' ' + LL.NEW(1) : LL.EDIT()} {LL.ENTITY()}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
@@ -314,7 +316,7 @@ const CustomEntitiesDialog = ({
|
|||||||
<Button
|
<Button
|
||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={close}
|
onClick={onClose}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
>
|
>
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
|
|||||||
@@ -54,8 +54,10 @@ const CustomizationDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const close = () => {
|
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = () => {
|
const save = () => {
|
||||||
@@ -76,7 +78,7 @@ const CustomizationDialog = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog sx={dialogStyle} open={open} onClose={close}>
|
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
|
||||||
<DialogTitle>{LL.EDIT() + ' ' + LL.ENTITY()}</DialogTitle>
|
<DialogTitle>{LL.EDIT() + ' ' + LL.ENTITY()}</DialogTitle>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
<Grid container direction="row">
|
<Grid container direction="row">
|
||||||
@@ -115,7 +117,7 @@ const CustomizationDialog = ({
|
|||||||
name="cn"
|
name="cn"
|
||||||
label={LL.NEW_NAME_OF(LL.ENTITY())}
|
label={LL.NEW_NAME_OF(LL.ENTITY())}
|
||||||
value={editItem.cn}
|
value={editItem.cn}
|
||||||
autoFocus
|
// autoFocus
|
||||||
sx={{ width: '30ch' }}
|
sx={{ width: '30ch' }}
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
/>
|
/>
|
||||||
@@ -155,7 +157,7 @@ const CustomizationDialog = ({
|
|||||||
<Button
|
<Button
|
||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={close}
|
onClick={onClose}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
>
|
>
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ const DevicesDialog = ({
|
|||||||
label={LL.VALUE(0)}
|
label={LL.VALUE(0)}
|
||||||
value={editItem.v}
|
value={editItem.v}
|
||||||
disabled={!writeable}
|
disabled={!writeable}
|
||||||
autoFocus
|
// autoFocus
|
||||||
sx={{ width: '30ch' }}
|
sx={{ width: '30ch' }}
|
||||||
select
|
select
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
@@ -162,7 +162,7 @@ const DevicesDialog = ({
|
|||||||
label={LL.VALUE(0)}
|
label={LL.VALUE(0)}
|
||||||
value={editItem.v}
|
value={editItem.v}
|
||||||
disabled={!writeable}
|
disabled={!writeable}
|
||||||
autoFocus
|
// autoFocus
|
||||||
sx={{ width: '30ch' }}
|
sx={{ width: '30ch' }}
|
||||||
multiline={editItem.u ? false : true}
|
multiline={editItem.u ? false : true}
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
|
|||||||
@@ -62,10 +62,6 @@ const SchedulerDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const close = () => {
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
try {
|
try {
|
||||||
setFieldErrors(undefined);
|
setFieldErrors(undefined);
|
||||||
@@ -151,8 +147,14 @@ const SchedulerDialog = ({
|
|||||||
</Typography>
|
</Typography>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
|
if (reason !== 'backdropClick') {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog sx={dialogStyle} open={open} onClose={close}>
|
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
{creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}
|
{creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}
|
||||||
{LL.SCHEDULE(1)}
|
{LL.SCHEDULE(1)}
|
||||||
@@ -294,6 +296,7 @@ const SchedulerDialog = ({
|
|||||||
<TextField
|
<TextField
|
||||||
name="time"
|
name="time"
|
||||||
label={isCondition ? 'Condition' : 'On Change Value'}
|
label={isCondition ? 'Condition' : 'On Change Value'}
|
||||||
|
multiline
|
||||||
fullWidth
|
fullWidth
|
||||||
value={
|
value={
|
||||||
editItem.time == '00:00' ? (editItem.time = '') : editItem.time
|
editItem.time == '00:00' ? (editItem.time = '') : editItem.time
|
||||||
@@ -327,6 +330,7 @@ const SchedulerDialog = ({
|
|||||||
fieldErrors={fieldErrors}
|
fieldErrors={fieldErrors}
|
||||||
name="cmd"
|
name="cmd"
|
||||||
label={LL.COMMAND(0)}
|
label={LL.COMMAND(0)}
|
||||||
|
multiline
|
||||||
fullWidth
|
fullWidth
|
||||||
value={editItem.cmd}
|
value={editItem.cmd}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
@@ -369,7 +373,7 @@ const SchedulerDialog = ({
|
|||||||
<Button
|
<Button
|
||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={close}
|
onClick={onClose}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
>
|
>
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
|
|||||||
@@ -57,8 +57,10 @@ const SensorsAnalogDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const close = () => {
|
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
@@ -77,7 +79,7 @@ const SensorsAnalogDialog = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog sx={dialogStyle} open={open} onClose={close}>
|
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
{creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}
|
{creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}
|
||||||
{LL.ANALOG_SENSOR(0)}
|
{LL.ANALOG_SENSOR(0)}
|
||||||
@@ -318,7 +320,7 @@ const SensorsAnalogDialog = ({
|
|||||||
<Button
|
<Button
|
||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={close}
|
onClick={onClose}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
>
|
>
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
|
|||||||
@@ -52,8 +52,10 @@ const SensorsTemperatureDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const close = () => {
|
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
@@ -67,7 +69,7 @@ const SensorsTemperatureDialog = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog sx={dialogStyle} open={open} onClose={close}>
|
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
{LL.EDIT()} {LL.TEMP_SENSOR()}
|
{LL.EDIT()} {LL.TEMP_SENSOR()}
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
@@ -84,7 +86,7 @@ const SensorsTemperatureDialog = ({
|
|||||||
name="n"
|
name="n"
|
||||||
label={LL.NAME(0)}
|
label={LL.NAME(0)}
|
||||||
value={editItem.n}
|
value={editItem.n}
|
||||||
autoFocus
|
// autoFocus
|
||||||
sx={{ width: '30ch' }}
|
sx={{ width: '30ch' }}
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
/>
|
/>
|
||||||
@@ -110,7 +112,7 @@ const SensorsTemperatureDialog = ({
|
|||||||
<Button
|
<Button
|
||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={close}
|
onClick={onClose}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
>
|
>
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ export const schedulerItemValidation = (
|
|||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
pattern: /^[a-zA-Z0-9_\\.]{0,19}$/,
|
pattern: /^[a-zA-Z0-9_\\.]{0,19}$/,
|
||||||
message: "Must be <20 characters: alpha numeric, '_' or '.'"
|
message: "Must be <20 characters: alphanumeric, '_' or '.'"
|
||||||
},
|
},
|
||||||
...[uniqueNameValidator(schedule, scheduleItem.o_name)]
|
...[uniqueNameValidator(schedule, scheduleItem.o_name)]
|
||||||
],
|
],
|
||||||
@@ -317,8 +317,8 @@ export const schedulerItemValidation = (
|
|||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 64,
|
max: 300,
|
||||||
message: 'Command must be 1-64 characters'
|
message: 'Command must be 1-300 characters'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
@@ -350,7 +350,7 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte
|
|||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
pattern: /^[a-zA-Z0-9_\\.]{1,19}$/,
|
pattern: /^[a-zA-Z0-9_\\.]{1,19}$/,
|
||||||
message: "Must be <20 characters: alpha numeric, '_' or '.'"
|
message: "Must be <20 characters: alphanumeric, '_' or '.'"
|
||||||
},
|
},
|
||||||
...[uniqueCustomNameValidator(entity, entityItem.o_name)]
|
...[uniqueCustomNameValidator(entity, entityItem.o_name)]
|
||||||
],
|
],
|
||||||
@@ -404,7 +404,7 @@ export const temperatureSensorItemValidation = (sensors: TemperatureSensor[]) =>
|
|||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
pattern: /^[a-zA-Z0-9_\\.]{0,19}$/,
|
pattern: /^[a-zA-Z0-9_\\.]{0,19}$/,
|
||||||
message: "Must be <20 characters: alpha numeric, '_' or '.'"
|
message: "Must be <20 characters: alphanumeric, '_' or '.'"
|
||||||
},
|
},
|
||||||
...[uniqueTemperatureNameValidator(sensors)]
|
...[uniqueTemperatureNameValidator(sensors)]
|
||||||
]
|
]
|
||||||
@@ -444,7 +444,7 @@ export const analogSensorItemValidation = (
|
|||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
pattern: /^[a-zA-Z0-9_\\.]{0,19}$/,
|
pattern: /^[a-zA-Z0-9_\\.]{0,19}$/,
|
||||||
message: "Must be <20 characters: alpha numeric, '_' or '.'"
|
message: "Must be <20 characters: alphanumeric, '_' or '.'"
|
||||||
},
|
},
|
||||||
...[uniqueAnalogNameValidator(sensors)]
|
...[uniqueAnalogNameValidator(sensors)]
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export const createUserValidator = (users: UserType[], creating: boolean) =>
|
|||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
pattern: /^[a-zA-Z0-9_\\.]{1,24}$/,
|
pattern: /^[a-zA-Z0-9_\\.]{1,24}$/,
|
||||||
message: "Must be 1-24 characters: alpha numeric, '_' or '.'"
|
message: "Must be 1-24 characters: alphanumeric, '_' or '.'"
|
||||||
},
|
},
|
||||||
...(creating ? [createUniqueUsernameValidator(users)] : [])
|
...(creating ? [createUniqueUsernameValidator(users)] : [])
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -697,16 +697,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/cache@npm:^11.12.0":
|
"@emotion/cache@npm:^11.13.0":
|
||||||
version: 11.12.0
|
version: 11.13.0
|
||||||
resolution: "@emotion/cache@npm:11.12.0"
|
resolution: "@emotion/cache@npm:11.13.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@emotion/memoize": "npm:^0.9.0"
|
"@emotion/memoize": "npm:^0.9.0"
|
||||||
"@emotion/sheet": "npm:^1.3.0"
|
"@emotion/sheet": "npm:^1.4.0"
|
||||||
"@emotion/utils": "npm:^1.3.0"
|
"@emotion/utils": "npm:^1.4.0"
|
||||||
"@emotion/weak-memoize": "npm:^0.4.0"
|
"@emotion/weak-memoize": "npm:^0.4.0"
|
||||||
stylis: "npm:4.2.0"
|
stylis: "npm:4.2.0"
|
||||||
checksum: 10c0/b6909597a41dfc1d07ada1b8a719697d2c0155a8f71c14079b7a089e281093a4c0710933592c864185e9176621ce6eff96e5ce2eb6774ba7959235232892d3c8
|
checksum: 10c0/24cfba12a3494fb49b1ce522cba7ffdca45794a412e8a0da7658c5cb70b4182a852078116e4f66252f167ccd58e5876cfc4f9d1bfcb2618b1887febf835f816a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -740,16 +740,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/react@npm:^11.12.0":
|
"@emotion/react@npm:^11.13.0":
|
||||||
version: 11.12.0
|
version: 11.13.0
|
||||||
resolution: "@emotion/react@npm:11.12.0"
|
resolution: "@emotion/react@npm:11.13.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime": "npm:^7.18.3"
|
"@babel/runtime": "npm:^7.18.3"
|
||||||
"@emotion/babel-plugin": "npm:^11.12.0"
|
"@emotion/babel-plugin": "npm:^11.12.0"
|
||||||
"@emotion/cache": "npm:^11.12.0"
|
"@emotion/cache": "npm:^11.13.0"
|
||||||
"@emotion/serialize": "npm:^1.2.0"
|
"@emotion/serialize": "npm:^1.3.0"
|
||||||
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1"
|
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0"
|
||||||
"@emotion/utils": "npm:^1.3.0"
|
"@emotion/utils": "npm:^1.4.0"
|
||||||
"@emotion/weak-memoize": "npm:^0.4.0"
|
"@emotion/weak-memoize": "npm:^0.4.0"
|
||||||
hoist-non-react-statics: "npm:^3.3.1"
|
hoist-non-react-statics: "npm:^3.3.1"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -757,7 +757,7 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
"@types/react":
|
"@types/react":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 10c0/a2035e0a5788ec6748b595ae898732aa845515dea52657fcf2661288d01c7da16133588fdaa4288c05175dc4c39938546af265bb039065efca20a729c486da9b
|
checksum: 10c0/28ee0ba6818ccf2726b31da0ecf3a6ac091983c8e03b3f5d6d2eb02165e3b3d1b95c267fccd08bff2f9769e0ff7361d791810583b858a9dd788de7cf82f6667d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -774,6 +774,19 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@emotion/serialize@npm:^1.3.0":
|
||||||
|
version: 1.3.0
|
||||||
|
resolution: "@emotion/serialize@npm:1.3.0"
|
||||||
|
dependencies:
|
||||||
|
"@emotion/hash": "npm:^0.9.2"
|
||||||
|
"@emotion/memoize": "npm:^0.9.0"
|
||||||
|
"@emotion/unitless": "npm:^0.9.0"
|
||||||
|
"@emotion/utils": "npm:^1.4.0"
|
||||||
|
csstype: "npm:^3.0.2"
|
||||||
|
checksum: 10c0/dd3f9041b05e79664c27188d8aad0cf726baee6da934ac31fd96c03691ce2a2e222669252c8cd623f2b0e488c7f8cfe384798153f36685d48b98340e63655813
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/sheet@npm:^1.2.2":
|
"@emotion/sheet@npm:^1.2.2":
|
||||||
version: 1.2.2
|
version: 1.2.2
|
||||||
resolution: "@emotion/sheet@npm:1.2.2"
|
resolution: "@emotion/sheet@npm:1.2.2"
|
||||||
@@ -781,30 +794,30 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/sheet@npm:^1.3.0":
|
"@emotion/sheet@npm:^1.4.0":
|
||||||
version: 1.3.0
|
version: 1.4.0
|
||||||
resolution: "@emotion/sheet@npm:1.3.0"
|
resolution: "@emotion/sheet@npm:1.4.0"
|
||||||
checksum: 10c0/99ce618d426e0646f58591200619cf3cd6f452e829c0b0339f66b3e4bfd7d51773f49d0200e14334861bee9db1dfb5d46328b20eafbfdd28f857584688fad8f4
|
checksum: 10c0/3ca72d1650a07d2fbb7e382761b130b4a887dcd04e6574b2d51ce578791240150d7072a9bcb4161933abbcd1e38b243a6fb4464a7fe991d700c17aa66bb5acc7
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/styled@npm:^11.12.0":
|
"@emotion/styled@npm:^11.13.0":
|
||||||
version: 11.12.0
|
version: 11.13.0
|
||||||
resolution: "@emotion/styled@npm:11.12.0"
|
resolution: "@emotion/styled@npm:11.13.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime": "npm:^7.18.3"
|
"@babel/runtime": "npm:^7.18.3"
|
||||||
"@emotion/babel-plugin": "npm:^11.12.0"
|
"@emotion/babel-plugin": "npm:^11.12.0"
|
||||||
"@emotion/is-prop-valid": "npm:^1.3.0"
|
"@emotion/is-prop-valid": "npm:^1.3.0"
|
||||||
"@emotion/serialize": "npm:^1.2.0"
|
"@emotion/serialize": "npm:^1.3.0"
|
||||||
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1"
|
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.1.0"
|
||||||
"@emotion/utils": "npm:^1.3.0"
|
"@emotion/utils": "npm:^1.4.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@emotion/react": ^11.0.0-rc.0
|
"@emotion/react": ^11.0.0-rc.0
|
||||||
react: ">=16.8.0"
|
react: ">=16.8.0"
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
"@types/react":
|
"@types/react":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 10c0/f87466ade3c872c6452091969f2784b97dcec821f812f641088e1289ad039ddea7165e8b1221895911f199469d07a9ffc786434e496ae3cb62156f72a5686ad7
|
checksum: 10c0/5e2cc85c8a2f6e7bd012731cf0b6da3aef5906225e87e8d4a5c19da50572e24d9aaf92615aa36aa863f0fe6b62a121033356e1cad62617c48bfdaa2c3cf0d8a4
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -815,12 +828,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1":
|
"@emotion/use-insertion-effect-with-fallbacks@npm:^1.1.0":
|
||||||
version: 1.0.1
|
version: 1.1.0
|
||||||
resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1"
|
resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ">=16.8.0"
|
react: ">=16.8.0"
|
||||||
checksum: 10c0/a15b2167940e3a908160687b73fc4fcd81e59ab45136b6967f02c7c419d9a149acd22a416b325c389642d4f1c3d33cf4196cad6b618128b55b7c74f6807a240b
|
checksum: 10c0/a883480f3a7139fb4a43e71d3114ca57e2b7ae5ff204e05cd9e59251a113773b8f64eb75d3997726250aca85eb73447638c8f51930734bdd16b96762b65e58c3
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -838,6 +851,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@emotion/utils@npm:^1.4.0":
|
||||||
|
version: 1.4.0
|
||||||
|
resolution: "@emotion/utils@npm:1.4.0"
|
||||||
|
checksum: 10c0/b2ae698d6e935f4961a8349286b5b0a6117a16e179459cbf9c8d97d5daa7d96c99876b950f09b1a793d6b295713b2c8f89544bd8c3f26b8e4db60a218a0d4c42
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/weak-memoize@npm:^0.3.1":
|
"@emotion/weak-memoize@npm:^0.3.1":
|
||||||
version: 0.3.1
|
version: 0.3.1
|
||||||
resolution: "@emotion/weak-memoize@npm:0.3.1"
|
resolution: "@emotion/weak-memoize@npm:0.3.1"
|
||||||
@@ -2054,8 +2074,8 @@ __metadata:
|
|||||||
"@alova/adapter-xhr": "npm:^1.0.6"
|
"@alova/adapter-xhr": "npm:^1.0.6"
|
||||||
"@alova/scene-react": "npm:^1.6.1"
|
"@alova/scene-react": "npm:^1.6.1"
|
||||||
"@babel/core": "npm:^7.24.9"
|
"@babel/core": "npm:^7.24.9"
|
||||||
"@emotion/react": "npm:^11.12.0"
|
"@emotion/react": "npm:^11.13.0"
|
||||||
"@emotion/styled": "npm:^11.12.0"
|
"@emotion/styled": "npm:^11.13.0"
|
||||||
"@eslint/js": "npm:^9.7.0"
|
"@eslint/js": "npm:^9.7.0"
|
||||||
"@mui/icons-material": "npm:^5.16.4"
|
"@mui/icons-material": "npm:^5.16.4"
|
||||||
"@mui/material": "npm:^5.16.4"
|
"@mui/material": "npm:^5.16.4"
|
||||||
|
|||||||
27
lib_standalone/HTTPClient.h
Normal file
27
lib_standalone/HTTPClient.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef HTTPClient_H_
|
||||||
|
#define HTTPClient_H_
|
||||||
|
|
||||||
|
#include "WString.h"
|
||||||
|
|
||||||
|
class HTTPClient {
|
||||||
|
public:
|
||||||
|
// HTTPClient();
|
||||||
|
// ~HTTPClient();
|
||||||
|
|
||||||
|
bool begin(String url) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
void end(void) {};
|
||||||
|
int GET() {
|
||||||
|
return 200;
|
||||||
|
};
|
||||||
|
int POST(String payload) {
|
||||||
|
return 200;
|
||||||
|
};
|
||||||
|
void addHeader(const String & name, const String & value, bool first = false, bool replace = true) {};
|
||||||
|
String getString(void) {
|
||||||
|
return "Hello, World!";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* HTTPClient_H_ */
|
||||||
@@ -53,6 +53,14 @@ class String {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int len() const {
|
||||||
|
return _str.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool startsWith(const char * prefix) const {
|
||||||
|
return _str.find(prefix) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string _str;
|
std::string _str;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ rest_server.get(ES_LOG_ENDPOINT, (_req, res) => {
|
|||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
const data = {
|
const data = {
|
||||||
t: new Date().toISOString(),
|
t: new Date().toISOString(),
|
||||||
l: 7, // debug
|
l: (3 + (count % 6)),
|
||||||
i: count,
|
i: count,
|
||||||
n: 'system',
|
n: 'system',
|
||||||
m: 'message #' + count++
|
m: 'message #' + count++
|
||||||
@@ -55,6 +55,8 @@ rest_server.get(ES_LOG_ENDPOINT, (_req, res) => {
|
|||||||
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
||||||
}, INTERVAL);
|
}, INTERVAL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// if client closes connection
|
// if client closes connection
|
||||||
res.on('close', () => {
|
res.on('close', () => {
|
||||||
console.log('Closing ES connection');
|
console.log('Closing ES connection');
|
||||||
|
|||||||
@@ -985,7 +985,7 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// some devices store the protocol type (HT3, Buderus) in the last byte
|
// some devices store the protocol type (HT3, Buderus) in the last byte
|
||||||
uint8_t brand;
|
uint8_t brand;
|
||||||
if (telegram->message_length >= 10) {
|
if (telegram->message_length >= 10) {
|
||||||
brand = EMSdevice::decode_brand(telegram->message_data[9]);
|
brand = EMSdevice::decode_brand(telegram->message_data[9]); // TODO should be offset + 9?
|
||||||
} else {
|
} else {
|
||||||
brand = EMSdevice::Brand::NO_BRAND; // unknown
|
brand = EMSdevice::Brand::NO_BRAND; // unknown
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,22 +342,44 @@ bool WebSchedulerService::command(const char * name, const char * cmd, const cha
|
|||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
String url = doc["url"];
|
String url = doc["url"];
|
||||||
if (http.begin(url)) {
|
if (http.begin(url)) {
|
||||||
|
// It's an HTTP call
|
||||||
|
|
||||||
|
// add any given headers
|
||||||
for (JsonPair p : doc["header"].as<JsonObject>()) {
|
for (JsonPair p : doc["header"].as<JsonObject>()) {
|
||||||
http.addHeader(p.key().c_str(), p.value().as<String>().c_str());
|
http.addHeader(p.key().c_str(), p.value().as<String>().c_str());
|
||||||
}
|
}
|
||||||
String value = doc["value"] | "";
|
String value = doc["value"] | data; // extract value if its in the command, or take the data
|
||||||
|
String method = doc["method"] | "GET"; // default GET
|
||||||
|
|
||||||
|
// if there is data, force a POST
|
||||||
if (value.length()) {
|
if (value.length()) {
|
||||||
|
if (value.startsWith("{")) {
|
||||||
|
http.addHeader("Content-Type", "application/json"); // auto-set to JSON
|
||||||
|
}
|
||||||
httpResult = http.POST(value);
|
httpResult = http.POST(value);
|
||||||
} else if (data && data[0] != '\0') { // post
|
|
||||||
httpResult = http.POST(String(data));
|
|
||||||
} else {
|
} else {
|
||||||
httpResult = http.GET();
|
// no value, but check if it still a POST request
|
||||||
|
if (method == "POST") {
|
||||||
|
httpResult = http.POST(value);
|
||||||
|
} else {
|
||||||
|
httpResult = http.GET(); // normal GET
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
http.end();
|
http.end();
|
||||||
|
|
||||||
|
// check HTTP return code
|
||||||
|
if (httpResult != 200) {
|
||||||
|
char error[100];
|
||||||
|
snprintf(error, sizeof(error), "Schedule %s: URL command failed with http code %d", name, httpResult);
|
||||||
|
emsesp::EMSESP::logger().warning(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return httpResult > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonDocument doc_input;
|
JsonDocument doc_input;
|
||||||
JsonObject input = doc_input.to<JsonObject>();
|
JsonObject input = doc_input.to<JsonObject>();
|
||||||
if (strlen(data)) { // empty data queries a value
|
if (strlen(data)) { // empty data queries a value
|
||||||
@@ -562,6 +584,8 @@ void WebSchedulerService::test() {
|
|||||||
// (14 - 40) * 2.8 + 5 = -67.8
|
// (14 - 40) * 2.8 + 5 = -67.8
|
||||||
test_value = "(custom/seltemp - boiler/flowtempoffset) * 2.8 + 5";
|
test_value = "(custom/seltemp - boiler/flowtempoffset) * 2.8 + 5";
|
||||||
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
command("test", test_cmd.c_str(), compute(test_value).c_str());
|
||||||
|
|
||||||
|
// TODO add some HTTP/URI tests
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -583,13 +583,11 @@ std::string calculate(const std::string & expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// concatenate all elements in stack to a single string, separated by spaces and return
|
// concatenate all elements in stack to a single string, separated by spaces and return
|
||||||
// experimental - for MDvP to check
|
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
for (const auto & s : stack) {
|
for (const auto & s : stack) {
|
||||||
result += s;
|
result += s;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// return stack.back();
|
// return stack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user