Merge pull request #1874 from proddy/dev

web updates and scheduler
This commit is contained in:
Proddy
2024-07-20 15:49:55 +02:00
committed by GitHub
18 changed files with 184 additions and 84 deletions

View File

@@ -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",

View File

@@ -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)}&nbsp;</span> <span>{paddedLevelLabel(e.l)}&nbsp;</span>
<span>{paddedIDLabel(e.i)} </span> <span>{paddedIDLabel(e.i)} </span>

View File

@@ -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()}&nbsp;{LL.ENTITY()} {creating ? LL.ADD(1) + ' ' + LL.NEW(1) : LL.EDIT()}&nbsp;{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()}

View File

@@ -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()}

View File

@@ -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}

View File

@@ -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()}&nbsp; {creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}&nbsp;
{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()}

View File

@@ -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()}&nbsp; {creating ? LL.ADD(1) + ' ' + LL.NEW(0) : LL.EDIT()}&nbsp;
{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()}

View File

@@ -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()}&nbsp;{LL.TEMP_SENSOR()} {LL.EDIT()}&nbsp;{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()}

View File

@@ -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'
} }
] ]
}); });

View File

@@ -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"

View 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_ */

View File

@@ -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;
}; };

View File

@@ -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');

View File

@@ -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
} }

View File

@@ -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

View File

@@ -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();
} }