This commit is contained in:
MichaelDvP
2025-03-15 13:31:48 +01:00
16 changed files with 169 additions and 189 deletions

View File

@@ -58,7 +58,7 @@
"rollup-plugin-visualizer": "^5.14.0",
"terser": "^5.39.0",
"typescript-eslint": "8.26.1",
"vite": "^6.2.1",
"vite": "^6.2.2",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.1.4"
},

View File

@@ -62,7 +62,10 @@ const CustomEntitiesDialog = ({
...selectedItem,
device_id: selectedItem.device_id.toString(16).toUpperCase(),
type_id: selectedItem.type_id.toString(16).toUpperCase(),
factor: selectedItem.value_type === DeviceValueType.BOOL ? selectedItem.factor.toString(16).toUpperCase() : selectedItem.factor
factor:
selectedItem.value_type === DeviceValueType.BOOL
? selectedItem.factor.toString(16).toUpperCase()
: selectedItem.factor
});
}
}, [open, selectedItem]);
@@ -83,7 +86,10 @@ const CustomEntitiesDialog = ({
if (typeof editItem.type_id === 'string') {
editItem.type_id = parseInt(editItem.type_id, 16);
}
if (editItem.value_type === DeviceValueType.BOOL && typeof editItem.factor === 'string') {
if (
editItem.value_type === DeviceValueType.BOOL &&
typeof editItem.factor === 'string'
) {
editItem.factor = parseInt(editItem.factor, 16);
}
onSave(editItem);

View File

@@ -51,30 +51,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/core@npm:^7.22.1":
version: 7.26.9
resolution: "@babel/core@npm:7.26.9"
dependencies:
"@ampproject/remapping": "npm:^2.2.0"
"@babel/code-frame": "npm:^7.26.2"
"@babel/generator": "npm:^7.26.9"
"@babel/helper-compilation-targets": "npm:^7.26.5"
"@babel/helper-module-transforms": "npm:^7.26.0"
"@babel/helpers": "npm:^7.26.9"
"@babel/parser": "npm:^7.26.9"
"@babel/template": "npm:^7.26.9"
"@babel/traverse": "npm:^7.26.9"
"@babel/types": "npm:^7.26.9"
convert-source-map: "npm:^2.0.0"
debug: "npm:^4.1.0"
gensync: "npm:^1.0.0-beta.2"
json5: "npm:^2.2.3"
semver: "npm:^6.3.1"
checksum: 10c0/ed7212ff42a9453765787019b7d191b167afcacd4bd8fec10b055344ef53fa0cc648c9a80159ae4ecf870016a6318731e087042dcb68d1a2a9d34eb290dc014b
languageName: node
linkType: hard
"@babel/core@npm:^7.26.10":
"@babel/core@npm:^7.22.1, @babel/core@npm:^7.26.10":
version: 7.26.10
resolution: "@babel/core@npm:7.26.10"
dependencies:
@@ -97,7 +74,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/generator@npm:^7.26.10":
"@babel/generator@npm:^7.26.10, @babel/generator@npm:^7.26.5":
version: 7.26.10
resolution: "@babel/generator@npm:7.26.10"
dependencies:
@@ -110,19 +87,6 @@ __metadata:
languageName: node
linkType: hard
"@babel/generator@npm:^7.26.5, @babel/generator@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/generator@npm:7.26.9"
dependencies:
"@babel/parser": "npm:^7.26.9"
"@babel/types": "npm:^7.26.9"
"@jridgewell/gen-mapping": "npm:^0.3.5"
"@jridgewell/trace-mapping": "npm:^0.3.25"
jsesc: "npm:^3.0.2"
checksum: 10c0/6b78872128205224a9a9761b9ea7543a9a7902a04b82fc2f6801ead4de8f59056bab3fd17b1f834ca7b049555fc4c79234b9a6230dd9531a06525306050becad
languageName: node
linkType: hard
"@babel/helper-annotate-as-pure@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/helper-annotate-as-pure@npm:7.25.9"
@@ -206,17 +170,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/helpers@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/helpers@npm:7.26.9"
dependencies:
"@babel/template": "npm:^7.26.9"
"@babel/types": "npm:^7.26.9"
checksum: 10c0/3d4dbc4a33fe4181ed810cac52318b578294745ceaec07e2f6ecccf6cda55d25e4bfcea8f085f333bf911c9e1fc13320248dd1d5315ab47ad82ce1077410df05
languageName: node
linkType: hard
"@babel/parser@npm:^7.26.10":
"@babel/parser@npm:^7.26.10, @babel/parser@npm:^7.26.7, @babel/parser@npm:^7.26.9":
version: 7.26.10
resolution: "@babel/parser@npm:7.26.10"
dependencies:
@@ -227,17 +181,6 @@ __metadata:
languageName: node
linkType: hard
"@babel/parser@npm:^7.26.7, @babel/parser@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/parser@npm:7.26.9"
dependencies:
"@babel/types": "npm:^7.26.9"
bin:
parser: ./bin/babel-parser.js
checksum: 10c0/4b9ef3c9a0d4c328e5e5544f50fe8932c36f8a2c851e7f14a85401487cd3da75cad72c2e1bcec1eac55599a6bbb2fdc091f274c4fcafa6bdd112d4915ff087fc
languageName: node
linkType: hard
"@babel/plugin-syntax-jsx@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/plugin-syntax-jsx@npm:7.25.9"
@@ -275,12 +218,12 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
version: 7.26.9
resolution: "@babel/runtime@npm:7.26.9"
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.26.0, @babel/runtime@npm:^7.26.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
version: 7.26.10
resolution: "@babel/runtime@npm:7.26.10"
dependencies:
regenerator-runtime: "npm:^0.14.0"
checksum: 10c0/e8517131110a6ec3a7360881438b85060e49824e007f4a64b5dfa9192cf2bb5c01e84bfc109f02d822c7edb0db926928dd6b991e3ee460b483fb0fac43152d9b
checksum: 10c0/6dc6d88c7908f505c4f7770fb4677dfa61f68f659b943c2be1f2a99cb6680343462867abf2d49822adc435932919b36c77ac60125793e719ea8745f2073d3745
languageName: node
linkType: hard
@@ -295,22 +238,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.7, @babel/traverse@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/traverse@npm:7.26.9"
dependencies:
"@babel/code-frame": "npm:^7.26.2"
"@babel/generator": "npm:^7.26.9"
"@babel/parser": "npm:^7.26.9"
"@babel/template": "npm:^7.26.9"
"@babel/types": "npm:^7.26.9"
debug: "npm:^4.3.1"
globals: "npm:^11.1.0"
checksum: 10c0/51dd57fa39ea34d04816806bfead04c74f37301269d24c192d1406dc6e244fea99713b3b9c5f3e926d9ef6aa9cd5c062ad4f2fc1caa9cf843d5e864484ac955e
languageName: node
linkType: hard
"@babel/traverse@npm:^7.26.10":
"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.26.10, @babel/traverse@npm:^7.26.7":
version: 7.26.10
resolution: "@babel/traverse@npm:7.26.10"
dependencies:
@@ -325,17 +253,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.7, @babel/types@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/types@npm:7.26.9"
dependencies:
"@babel/helper-string-parser": "npm:^7.25.9"
"@babel/helper-validator-identifier": "npm:^7.25.9"
checksum: 10c0/999c56269ba00e5c57aa711fbe7ff071cd6990bafd1b978341ea7572cc78919986e2aa6ee51dacf4b6a7a6fa63ba4eb3f1a03cf55eee31b896a56d068b895964
languageName: node
linkType: hard
"@babel/types@npm:^7.26.10":
"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.10, @babel/types@npm:^7.26.7, @babel/types@npm:^7.26.9":
version: 7.26.10
resolution: "@babel/types@npm:7.26.10"
dependencies:
@@ -674,13 +592,13 @@ __metadata:
linkType: hard
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0":
version: 4.4.1
resolution: "@eslint-community/eslint-utils@npm:4.4.1"
version: 4.5.1
resolution: "@eslint-community/eslint-utils@npm:4.5.1"
dependencies:
eslint-visitor-keys: "npm:^3.4.3"
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
checksum: 10c0/2aa0ac2fc50ff3f234408b10900ed4f1a0b19352f21346ad4cc3d83a1271481bdda11097baa45d484dd564c895e0762a27a8240be7a256b3ad47129e96528252
checksum: 10c0/b520ae1b7bd04531a5c5da2021071815df4717a9f7d13720e3a5ddccf5c9c619532039830811fcbae1c2f1c9d133e63af2435ee69e0fc0fabbd6d928c6800fb2
languageName: node
linkType: hard
@@ -1000,14 +918,16 @@ __metadata:
linkType: hard
"@mui/types@npm:^7.2.21":
version: 7.2.23
resolution: "@mui/types@npm:7.2.23"
version: 7.3.0
resolution: "@mui/types@npm:7.3.0"
dependencies:
"@babel/runtime": "npm:^7.26.9"
peerDependencies:
"@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/e7aebed6a79186f76b35354f094aed0c33291eaae4494fe471a6f4a4ebe6d6998071085c76b569d859723954a10eee7e751b39aa1fd85b0ce6d888922e05937d
checksum: 10c0/3700c3c9708ac85b9723269eb54a8faf62b0ff280b87667e29cf3cf4825708c3bcc7a4fe0bd32fe8c44d809586e02b64321f8d0b198a4250d01ed7b442312221
languageName: node
linkType: hard
@@ -1707,7 +1627,7 @@ __metadata:
typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.8.2"
typescript-eslint: "npm:8.26.1"
vite: "npm:^6.2.1"
vite: "npm:^6.2.2"
vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^5.1.4"
languageName: unknown
@@ -2121,9 +2041,9 @@ __metadata:
linkType: hard
"caniuse-lite@npm:^1.0.30001688":
version: 1.0.30001703
resolution: "caniuse-lite@npm:1.0.30001703"
checksum: 10c0/ed88e318da28e9e59c4ac3a2e3c42859558b7b713aebf03696a1f916e4ed4b70734dda82be04635e2b62ec355b8639bbed829b7b12ff528d7f9cc31a3a5bea91
version: 1.0.30001704
resolution: "caniuse-lite@npm:1.0.30001704"
checksum: 10c0/4efa0ece51ef58e7ce7e7c8cd7b50372bcb910581a47397be5c086c046c3cd436d123b734351fb20f638c322b339198edf89b5b632ff59bdd171c74ff7f4efcf
languageName: node
linkType: hard
@@ -2704,9 +2624,9 @@ __metadata:
linkType: hard
"electron-to-chromium@npm:^1.5.73":
version: 1.5.114
resolution: "electron-to-chromium@npm:1.5.114"
checksum: 10c0/cb86057d78f1aeb53ab6550dedacfd9496bcc6676bab7b48466c3958ba9ce0ed78c7213b1eab99ba38542cbaaa176eb7f8ea8b0274c0688b8ce3058291549430
version: 1.5.119
resolution: "electron-to-chromium@npm:1.5.119"
checksum: 10c0/f4ca0eb3af21d16d2c1fd480c5a43428ce4423ca887338d69bd3eadae818b6d6e799c62b1baac1bc4f76e4226f5fb15a6b0dc8965f601ac053e86508d3e8e41c
languageName: node
linkType: hard
@@ -6920,15 +6840,16 @@ __metadata:
linkType: hard
"vite-prerender-plugin@npm:^0.5.3":
version: 0.5.6
resolution: "vite-prerender-plugin@npm:0.5.6"
version: 0.5.7
resolution: "vite-prerender-plugin@npm:0.5.7"
dependencies:
kolorist: "npm:^1.8.0"
magic-string: "npm:^0.30.6"
node-html-parser: "npm:^6.1.12"
simple-code-frame: "npm:^1.3.0"
source-map: "npm:^0.7.4"
stack-trace: "npm:^1.0.0-pre2"
checksum: 10c0/74e0d860b4f539804da23e85ea6f16b341cc882c8c1ccffc5467b4c726c399aea87cd1bf244a21b58c664e27ad8de5aac56c070292332ccaed93ddf1e29f17dc
checksum: 10c0/77005008315d39d5bb87f7462046cc08b074388f900905678ce9782378bf4c8ca6ea5c0321506403b8f22fe6edd55c49cc423903ce545fefd0d4f046f06823cb
languageName: node
linkType: hard
@@ -6948,9 +6869,9 @@ __metadata:
languageName: node
linkType: hard
"vite@npm:^6.2.1":
version: 6.2.1
resolution: "vite@npm:6.2.1"
"vite@npm:^6.2.2":
version: 6.2.2
resolution: "vite@npm:6.2.2"
dependencies:
esbuild: "npm:^0.25.0"
fsevents: "npm:~2.3.3"
@@ -6996,7 +6917,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 10c0/2c024376a840eae2ce9cfba98d62e9f1eae93caa8304875854dbc0740414aedcfbe157c2244567bd456cdb60a300312af02ae9b5c63c147d35cf4da3a0591312
checksum: 10c0/52f5b1c10cfe5e3b6382c6de1811ebbf76df9b5a8bab3d65169446c6b54a5f1528f775b1548009a6d8aad11def20fba046bb3e9abb10c0c2c9ccd78118623bb8
languageName: node
linkType: hard

View File

@@ -9,7 +9,7 @@
"format": "prettier -l -w '**/*.{ts,tsx,js,css,json,md}'"
},
"dependencies": {
"@msgpack/msgpack": "^3.1.0",
"@msgpack/msgpack": "^3.1.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"formidable": "^3.5.2",
"itty-router": "^5.0.18",

View File

@@ -16,16 +16,16 @@ __metadata:
languageName: node
linkType: hard
"@babel/generator@npm:^7.26.5, @babel/generator@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/generator@npm:7.26.9"
"@babel/generator@npm:^7.26.10, @babel/generator@npm:^7.26.5":
version: 7.26.10
resolution: "@babel/generator@npm:7.26.10"
dependencies:
"@babel/parser": "npm:^7.26.9"
"@babel/types": "npm:^7.26.9"
"@babel/parser": "npm:^7.26.10"
"@babel/types": "npm:^7.26.10"
"@jridgewell/gen-mapping": "npm:^0.3.5"
"@jridgewell/trace-mapping": "npm:^0.3.25"
jsesc: "npm:^3.0.2"
checksum: 10c0/6b78872128205224a9a9761b9ea7543a9a7902a04b82fc2f6801ead4de8f59056bab3fd17b1f834ca7b049555fc4c79234b9a6230dd9531a06525306050becad
checksum: 10c0/88b3b3ea80592fc89349c4e1a145e1386e4042866d2507298adf452bf972f68d13bf699a845e6ab8c028bd52c2247013eb1221b86e1db5c9779faacba9c4b10e
languageName: node
linkType: hard
@@ -43,14 +43,14 @@ __metadata:
languageName: node
linkType: hard
"@babel/parser@npm:^7.26.7, @babel/parser@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/parser@npm:7.26.9"
"@babel/parser@npm:^7.26.10, @babel/parser@npm:^7.26.7, @babel/parser@npm:^7.26.9":
version: 7.26.10
resolution: "@babel/parser@npm:7.26.10"
dependencies:
"@babel/types": "npm:^7.26.9"
"@babel/types": "npm:^7.26.10"
bin:
parser: ./bin/babel-parser.js
checksum: 10c0/4b9ef3c9a0d4c328e5e5544f50fe8932c36f8a2c851e7f14a85401487cd3da75cad72c2e1bcec1eac55599a6bbb2fdc091f274c4fcafa6bdd112d4915ff087fc
checksum: 10c0/c47f5c0f63cd12a663e9dc94a635f9efbb5059d98086a92286d7764357c66bceba18ccbe79333e01e9be3bfb8caba34b3aaebfd8e62c3d5921c8cf907267be75
languageName: node
linkType: hard
@@ -66,27 +66,27 @@ __metadata:
linkType: hard
"@babel/traverse@npm:^7.26.7":
version: 7.26.9
resolution: "@babel/traverse@npm:7.26.9"
version: 7.26.10
resolution: "@babel/traverse@npm:7.26.10"
dependencies:
"@babel/code-frame": "npm:^7.26.2"
"@babel/generator": "npm:^7.26.9"
"@babel/parser": "npm:^7.26.9"
"@babel/generator": "npm:^7.26.10"
"@babel/parser": "npm:^7.26.10"
"@babel/template": "npm:^7.26.9"
"@babel/types": "npm:^7.26.9"
"@babel/types": "npm:^7.26.10"
debug: "npm:^4.3.1"
globals: "npm:^11.1.0"
checksum: 10c0/51dd57fa39ea34d04816806bfead04c74f37301269d24c192d1406dc6e244fea99713b3b9c5f3e926d9ef6aa9cd5c062ad4f2fc1caa9cf843d5e864484ac955e
checksum: 10c0/4e86bb4e3c30a6162bb91df86329df79d96566c3e2d9ccba04f108c30473a3a4fd360d9990531493d90f6a12004f10f616bf9b9229ca30c816b708615e9de2ac
languageName: node
linkType: hard
"@babel/types@npm:^7.26.7, @babel/types@npm:^7.26.9":
version: 7.26.9
resolution: "@babel/types@npm:7.26.9"
"@babel/types@npm:^7.26.10, @babel/types@npm:^7.26.7, @babel/types@npm:^7.26.9":
version: 7.26.10
resolution: "@babel/types@npm:7.26.10"
dependencies:
"@babel/helper-string-parser": "npm:^7.25.9"
"@babel/helper-validator-identifier": "npm:^7.25.9"
checksum: 10c0/999c56269ba00e5c57aa711fbe7ff071cd6990bafd1b978341ea7572cc78919986e2aa6ee51dacf4b6a7a6fa63ba4eb3f1a03cf55eee31b896a56d068b895964
checksum: 10c0/7a7f83f568bfc3dfabfaf9ae3a97ab5c061726c0afa7dcd94226d4f84a81559da368ed79671e3a8039d16f12476cf110381a377ebdea07587925f69628200dac
languageName: node
linkType: hard
@@ -132,10 +132,10 @@ __metadata:
languageName: node
linkType: hard
"@msgpack/msgpack@npm:^3.1.0":
version: 3.1.0
resolution: "@msgpack/msgpack@npm:3.1.0"
checksum: 10c0/d31c299cc9f7620715eec77b12ec0cb4950943fd8b0c23275e37afe6ad30efe237e61333e8e340a0a433eca7a4595212fb905e70b4506ae5b866758e4291289b
"@msgpack/msgpack@npm:^3.1.1":
version: 3.1.1
resolution: "@msgpack/msgpack@npm:3.1.1"
checksum: 10c0/f7048d2145ee39e4979b4e6bb9d9723db031ea7b4f00d0ec96258fbff40b8af027783f391ee294e5385a5a91849a77d934ad08eb11d08253484eee8f8f0866ff
languageName: node
linkType: hard
@@ -260,7 +260,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "mock-api@workspace:."
dependencies:
"@msgpack/msgpack": "npm:^3.1.0"
"@msgpack/msgpack": "npm:^3.1.1"
"@trivago/prettier-plugin-sort-imports": "npm:^5.2.2"
formidable: "npm:^3.5.2"
itty-router: "npm:^5.0.18"

View File

@@ -184,7 +184,8 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
}
// call the command based on the type
uint8_t return_code = CommandRet::ERROR;
uint8_t return_code = CommandRet::OK;
if (data.is<const char *>()) {
return_code = Command::call(device_type, command_p, data.as<const char *>(), is_admin, id_n, output);
} else if (data.is<int>()) {
@@ -312,11 +313,17 @@ bool Command::set_attribute(JsonObject output, const char * cmd, const char * at
return true;
}
// not found
output.clear();
// attribute isn't found
// it could be a value command, but the value doesn't exist?
if (strcmp(attribute, "value") == 0) {
LOG_DEBUG("%s has no value set", cmd);
return false; // fail
}
char error[100];
snprintf(error, sizeof(error), "no %s in %s", attribute, cmd);
snprintf(error, sizeof(error), "no attribute '%s' in %s", attribute, cmd);
output["message"] = error;
return false;
}
@@ -356,7 +363,7 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
return CommandRet::OK;
}
} else if (device_type == EMSdevice::DeviceType::SYSTEM && strchr(cmd, '/')) {
// check service commands, if not found continue with commandsfunctions
// check service commands, if not found continue with command functions
if (EMSESP::system_.command_service(cmd, value)) {
return CommandRet::OK;
}
@@ -376,14 +383,23 @@ uint8_t Command::call(const uint8_t device_type, const char * command, const cha
flag = CommandFlag::CMD_FLAG_AHS;
}
// see if there is a command registered and it's valid
// see if there is a command registered for this EMS device
auto cf = find_command(device_type, device_id, cmd, flag);
if (!cf) {
// if we don't already have a message set, set it to invalid command
if (output["message"]) {
LOG_WARNING("Command failed: %s", output["message"].as<const char *>());
return CommandRet::ERROR;
} else {
std::string err = "no " + std::string(cmd) + " in " + dname;
// not an error, no test if we're fetching a value, but the value is not set
auto attribute_s = Command::get_attribute(cmd);
if (attribute_s) {
if (strcmp(attribute_s, "value") == 0) {
return CommandRet::NO_VALUE;
}
}
std::string err = "no entity '" + std::string(cmd) + "' in " + dname;
output["message"] = err;
LOG_WARNING("Command failed: %s", err.c_str());
}
@@ -496,7 +512,7 @@ Command::CmdFunction * Command::find_command(const uint8_t device_type, const ui
}
}
return nullptr; // command not found
return nullptr; // command not found, could be an attribute?
}
void Command::erase_device_commands(const uint8_t device_type) {

View File

@@ -48,7 +48,8 @@ enum CommandRet : uint8_t {
NOT_FOUND, // 2
ERROR, // 3
NOT_ALLOWED, // 4 - needs authentication
INVALID // 5 - invalid (tag)
INVALID, // 5 - invalid (tag)
NO_VALUE // 6 - no value
};
using cmd_function_p = std::function<bool(const char * data, const int8_t id)>;

View File

@@ -1528,6 +1528,7 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t
if (cmd_s == Helpers::toLower(dv.short_name) && (tag <= 0 || tag == dv.tag)) {
get_value_json(output, dv);
// if we're filtering on an attribute, go find it
// if we can't find it, maybe it exists but doesn't not have a value assigned yet
return Command::set_attribute(output, cmd_s, attribute_s);
}
}

View File

@@ -780,6 +780,7 @@ bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8
}
}
}
// if the EMS device was valid, but the cmd not found exit. it will be handled upstream.
if (found_device) {
return false;

View File

@@ -380,7 +380,13 @@ std::string commands(std::string & expr, bool quotes = true) {
JsonObject output = doc_out.to<JsonObject>();
JsonObject input = doc_in.to<JsonObject>();
std::string cmd_s = "api/" + std::string(cmd);
emsesp::Command::process(cmd_s.c_str(), true, input, output);
auto return_code = emsesp::Command::process(cmd_s.c_str(), true, input, output);
// check for no value (entity is valid but has no value set)
if (return_code != emsesp::CommandRet::OK && return_code != emsesp::CommandRet::NO_VALUE) {
return expr = "";
}
std::string data = output["api_data"] | "";
if (!isnum(data) && quotes) {
data.insert(data.begin(), '"');

View File

@@ -324,20 +324,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
if (command == "general") {
shell.printfln("Testing adding a boiler, thermostat, all sensors, scheduler and custom entities...");
// setup fake data
// EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
// add devices
test("general");
// EMSESP::webCustomEntityService.test(); // add custom entities
// EMSESP::temperaturesensor_.test(); // add temperature sensors
// EMSESP::webSchedulerService.test(); // add scheduler items
EMSESP::webCustomEntityService.test(); // custom entities
EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
EMSESP::temperaturesensor_.test(); // add temperature sensors
EMSESP::webSchedulerService.test(); // run scheduler tests, and conditions
// shell.invoke_command("show devices");
// shell.invoke_command("show values");
// shell.invoke_command("call system publish");
// shell.invoke_command("show mqtt");
shell.invoke_command("show values");
ok = true;
}
@@ -1089,6 +1084,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// request.url("/api/boiler/comfort/value");
// EMSESP::webAPIService.webAPIService(&request);
// this should fail but it doesn't
// request.url("/api/boiler/bad/value");
// EMSESP::webAPIService.webAPIService(&request);
// POST COMMANDS
request.method(HTTP_POST);

View File

@@ -134,12 +134,13 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
}
// send the json that came back from the command call
// sequence is FAIL, OK, NOT_FOUND, ERROR, NOT_ALLOWED, INVALID
// sequence matches CommandRet in command.h (FAIL, OK, NOT_FOUND, ERROR, NOT_ALLOWED, INVALID, NO_VALUE)
// 400 (bad request)
// 200 (OK)
// 404 (not found)
// 401 (unauthorized)
int ret_codes[6] = {400, 200, 404, 400, 401, 400};
// 400 (invalid)
int ret_codes[7] = {400, 200, 404, 400, 401, 400, 404};
response->setCode(ret_codes[return_code]);
response->setLength();
response->setContentType("application/json; charset=utf-8");

View File

@@ -165,6 +165,7 @@ bool WebSchedulerService::get_value_info(JsonObject output, const char * cmd) {
}
return true;
}
for (const ScheduleItem & scheduleItem : *scheduleItems_) {
if (Helpers::toLower(scheduleItem.name) == cmd) {
get_value_json(output, scheduleItem);
@@ -385,7 +386,6 @@ bool WebSchedulerService::command(const char * name, const std::string & command
snprintf(command_str, sizeof(command_str), "/api/%s", cmd.c_str());
uint8_t return_code = Command::process(command_str, true, input, output); // admin set
if (return_code == CommandRet::OK) {
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("Schedule command '%s' with data '%s' was successful", cmd.c_str(), data.c_str());
@@ -596,10 +596,6 @@ void WebSchedulerService::test() {
test_value = "(custom/seltemp)";
command("test5", test_cmd.c_str(), compute(test_value).c_str());
// note: this will fail unless test("boiler") is loaded before hand
test_value = "(boiler/outdoortemp)";
command("test6", test_cmd.c_str(), compute(test_value).c_str());
test_value = "boiler/flowtempoffset";
command("test7", test_cmd.c_str(), compute(test_value).c_str());
@@ -613,10 +609,35 @@ void WebSchedulerService::test() {
test_value = "(custom/seltemp - boiler/flowtempoffset) * 2.8 + 5";
command("test10", test_cmd.c_str(), compute(test_value).c_str());
test_cmd = "{\"method\":\"POST\",\"url\":\"http://192.168.1.42:8123/api/services/script/test_notify2\", \"header\":{\"authorization\":\"Bearer "
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMmNlYWI5NDgzMmI0ODE2YWQ2NzU4MjkzZDE2YWMxZSIsImlhdCI6MTcyMTM5MTI0NCwiZXhwIjoyMDM2NzUxMjQ0fQ."
"S5sago1tEI6lNhrDCO0dM_WsVQHkD_laAjcks8tWAqo\"}}";
command("test11", test_cmd.c_str(), "");
// test case conversion
test_value = "(thermostat/hc1/modetype == \"comfort\")";
command("test11a", test_cmd.c_str(), compute(test_value).c_str()); // should be 1 true
test_value = "(thermostat/hc1/modetype == \"Comfort\")";
command("test11b", test_cmd.c_str(), compute(test_value).c_str()); // should be 1 true
test_value = "(thermostat/hc1/modetype == \"unknown\")";
command("test11c", test_cmd.c_str(), compute(test_value).c_str()); // should be 0 false
// can't find entity, should fail
test_value = "(boiler/storagetemp/value1)";
command("test12", test_cmd.c_str(), compute(test_value).c_str());
// can't find attribute, should fail
test_value = "(boiler/storagetemp1/value1)";
command("test13", test_cmd.c_str(), compute(test_value).c_str());
// check when entity has no value, should pass
test_value = "(boiler/storagetemp2/value)";
command("test14", test_cmd.c_str(), compute(test_value).c_str());
// should pass
test_value = "(boiler/storagetemp1/value)";
command("test15", test_cmd.c_str(), compute(test_value).c_str());
// test HTTP POST to call HA script
// test_cmd = "{\"method\":\"POST\",\"url\":\"http://192.168.1.42:8123/api/services/script/test_notify2\", \"header\":{\"authorization\":\"Bearer "
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMmNlYWI5NDgzMmI0ODE2YWQ2NzU4MjkzZDE2YWMxZSIsImlhdCI6MTcyMTM5MTI0NCwiZXhwIjoyMDM2NzUxMjQ0fQ."
// "S5sago1tEI6lNhrDCO0dM_WsVQHkD_laAjcks8tWAqo\"}}";
// command("test99", test_cmd.c_str(), "");
}
#endif

View File

@@ -294,82 +294,82 @@ void test_36() {
}
void test_37() {
auto expected_response = "[{\"message\":\"no bad/value in boiler\"}]";
auto expected_response = "[{}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/boiler/bad/value"));
}
void test_38() {
auto expected_response = "[{\"message\":\"no valu in comfort\"}]";
auto expected_response = "[{\"message\":\"no attribute 'valu' in comfort\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/boiler/comfort/valu"));
}
void test_39() {
auto expected_response = "[{\"message\":\"no settings in system\"}]";
auto expected_response = "[{\"message\":\"no entity 'settings' in system\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/system/settings/locale2"));
}
void test_40() {
auto expected_response = "[{\"message\":\"no settings2 in system\"}]";
auto expected_response = "[{\"message\":\"no entity 'settings2' in system\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/system/settings2"));
}
void test_41() {
auto expected_response = "[{\"message\":\"no settings2 in system\"}]";
auto expected_response = "[{\"message\":\"no entity 'settings2' in system\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/system/settings2/locale2"));
}
void test_42() {
auto expected_response = "[{\"message\":\"no test_scheduler2 in scheduler\"}]";
auto expected_response = "[{\"message\":\"no entity 'test_scheduler2' in scheduler\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/scheduler/test_scheduler2"));
}
void test_43() {
auto expected_response = "[{\"message\":\"no val in test_scheduler\"}]";
auto expected_response = "[{\"message\":\"no attribute 'val' in test_scheduler\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/scheduler/test_scheduler/val"));
}
void test_44() {
auto expected_response = "[{\"message\":\"no test_scheduler2 in scheduler\"}]";
auto expected_response = "[{\"message\":\"no entity 'test_scheduler2' in scheduler\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/scheduler/test_scheduler2/val2"));
}
void test_45() {
auto expected_response = "[{\"message\":\"no seltemp2 in custom\"}]";
auto expected_response = "[{\"message\":\"no entity 'seltemp2' in custom\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/custom/seltemp2"));
}
void test_46() {
auto expected_response = "[{\"message\":\"no val in seltemp\"}]";
auto expected_response = "[{\"message\":\"no attribute 'val' in seltemp\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/custom/seltemp/val"));
}
void test_47() {
auto expected_response = "[{\"message\":\"no test_sensor20 in temperaturesensor\"}]";
auto expected_response = "[{\"message\":\"no entity 'test_sensor20' in temperaturesensor\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/temperaturesensor/test_sensor20"));
}
void test_48() {
auto expected_response = "[{\"message\":\"no 0b_0c0d_0e0f_xxxx in temperaturesensor\"}]";
auto expected_response = "[{\"message\":\"no entity '0b_0c0d_0e0f_xxxx' in temperaturesensor\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/temperaturesensor/0B_0C0D_0E0F_XXXX"));
}
void test_49() {
auto expected_response = "[{\"message\":\"no bad in test_tempsensor2\"}]";
auto expected_response = "[{\"message\":\"no attribute 'bad' in test_tempsensor2\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/temperaturesensor/test_tempsensor2/bad"));
}
void test_50() {
auto expected_response = "[{\"message\":\"no bad in test_analogsensor1\"}]";
auto expected_response = "[{\"message\":\"no attribute 'bad' in test_analogsensor1\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor/test_analogsensor1/bad"));
}
void test_51() {
auto expected_response = "[{\"message\":\"no test_analog10 in analogsensor\"}]";
auto expected_response = "[{\"message\":\"no entity 'test_analog10' in analogsensor\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor/test_analog10"));
}
void test_52() {
auto expected_response = "[{\"message\":\"no test_analog10 in analogsensor\"}]";
auto expected_response = "[{\"message\":\"no entity 'test_analog10' in analogsensor\"}]";
TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/analogsensor/test_analog10/bad2"));
}

View File

@@ -18,7 +18,7 @@ void shuntingYard_test2() {
}
void shuntingYard_test3() {
std::string expected_result = "rssi is -23 dbm";
std::string expected_result = "rssi is -23 dBm";
std::string test_value = "\"rssi is \"(system/network/rssi)\" dBm\"";
TEST_ASSERT_EQUAL_STRING(expected_result.c_str(), compute(test_value).c_str());
}
@@ -126,6 +126,12 @@ void shuntingYard_test20() {
TEST_ASSERT_EQUAL_STRING(expected_result.c_str(), compute(test_value).c_str());
}
void shuntingYard_test21() {
std::string expected_result = "";
std::string test_value = "boiler/storagetemp2 == \"\"";
TEST_ASSERT_EQUAL_STRING(expected_result.c_str(), compute(test_value).c_str());
}
void run_shuntingYard_tests() {
RUN_TEST(shuntingYard_test1);
RUN_TEST(shuntingYard_test2);
@@ -147,4 +153,5 @@ void run_shuntingYard_tests() {
RUN_TEST(shuntingYard_test18);
RUN_TEST(shuntingYard_test19);
RUN_TEST(shuntingYard_test20);
RUN_TEST(shuntingYard_test21);
}