Merge pull request #1229 from MichaelDvP/dev2

api/response, Gateway S3, small fixes
This commit is contained in:
Proddy
2023-07-21 23:33:47 +02:00
committed by GitHub
29 changed files with 482 additions and 343 deletions

View File

@@ -36,6 +36,9 @@ There are breaking changes between 3.5.x and earlier versions of 3.6.0. Please r
- Support Buderus AM200 [#1161](https://github.com/emsesp/EMS-ESP32/issues/1161) - Support Buderus AM200 [#1161](https://github.com/emsesp/EMS-ESP32/issues/1161)
- Custom telegram handler [#1155](https://github.com/emsesp/EMS-ESP32/issues/1155) - Custom telegram handler [#1155](https://github.com/emsesp/EMS-ESP32/issues/1155)
- Added support for TLS in MQTT (ESP32-S3 only) [#1178](https://github.com/emsesp/EMS-ESP32/issues/1178) - Added support for TLS in MQTT (ESP32-S3 only) [#1178](https://github.com/emsesp/EMS-ESP32/issues/1178)
- Boardprofile BBQKees Gateway S3
- Custom entity type RAW [#1212](https://github.com/emsesp/EMS-ESP32/discussions/1212)
- API command response [#1212](https://github.com/emsesp/EMS-ESP32/discussions/1212)
## Fixed ## Fixed
@@ -46,6 +49,7 @@ There are breaking changes between 3.5.x and earlier versions of 3.6.0. Please r
- thermostat modetype is not changing when mode changes (e.g. to night) bugSomething isn't working [#1098](https://github.com/emsesp/EMS-ESP32/issues/1098) - thermostat modetype is not changing when mode changes (e.g. to night) bugSomething isn't working [#1098](https://github.com/emsesp/EMS-ESP32/issues/1098)
- NTP: cant apply changed timezone [#1182](https://github.com/emsesp/EMS-ESP32/issues/1182) - NTP: cant apply changed timezone [#1182](https://github.com/emsesp/EMS-ESP32/issues/1182)
- Missing Status of VS1 for Buderus SM200 enhancement [#1034](https://github.com/emsesp/EMS-ESP32/issues/1034) - Missing Status of VS1 for Buderus SM200 enhancement [#1034](https://github.com/emsesp/EMS-ESP32/issues/1034)
- Allowed gpios for S3
## Changed ## Changed
@@ -62,3 +66,4 @@ There are breaking changes between 3.5.x and earlier versions of 3.6.0. Please r
- Use [espMqttClient](https://github.com/bertmelis/espMqttClient) with integrated queue [#1178](https://github.com/emsesp/EMS-ESP32/issues/1178) - Use [espMqttClient](https://github.com/bertmelis/espMqttClient) with integrated queue [#1178](https://github.com/emsesp/EMS-ESP32/issues/1178)
- Move Sensors from Web dashboard to it's own tab enhancement [#1170](https://github.com/emsesp/EMS-ESP32/issues/1170) - Move Sensors from Web dashboard to it's own tab enhancement [#1170](https://github.com/emsesp/EMS-ESP32/issues/1170)
- Optimize WebUI dashboard data [#1169](https://github.com/emsesp/EMS-ESP32/issues/1169) - Optimize WebUI dashboard data [#1169](https://github.com/emsesp/EMS-ESP32/issues/1169)
- Response to `system/send`` raw reads gives combined data for telegrams with more parts

View File

@@ -1,6 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags # Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000, nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, , 0x2000, otadata, data, ota, , 0x2000,
app1, app, ota_1, , 0x140000,
app0, app, ota_0, , 0x2A0000, app0, app, ota_0, , 0x2A0000,
app1, app, ota_1, , 0x140000,
spiffs, data, spiffs, , 64K, spiffs, data, spiffs, , 64K,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0x2000
app1 app ota_1 0x140000
4 app0 app ota_0 0x2A0000
5 app1 app ota_1 0x140000
6 spiffs data spiffs 64K

View File

@@ -1,5 +1,5 @@
{ {
"adapter": "react", "adapter": "react",
"baseLocale": "pl", "baseLocale": "pl",
"$schema": "https://unpkg.com/typesafe-i18n@5.24.4/schema/typesafe-i18n.json" "$schema": "https://unpkg.com/typesafe-i18n@5.25.1/schema/typesafe-i18n.json"
} }

View File

@@ -22,8 +22,8 @@
"@alova/adapter-xhr": "^1.0.1", "@alova/adapter-xhr": "^1.0.1",
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0", "@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.0", "@mui/icons-material": "^5.14.1",
"@mui/material": "^5.14.0", "@mui/material": "^5.14.1",
"@preact/compat": "^17.1.2", "@preact/compat": "^17.1.2",
"@table-library/react-table-library": "4.1.4", "@table-library/react-table-library": "4.1.4",
"@types/lodash-es": "^4.17.8", "@types/lodash-es": "^4.17.8",
@@ -31,7 +31,7 @@
"@types/react": "^18.2.15", "@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.2.7",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"alova": "^2.9.2", "alova": "^2.9.3",
"async-validator": "^4.2.5", "async-validator": "^4.2.5",
"history": "^5.3.0", "history": "^5.3.0",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
@@ -42,17 +42,17 @@
"react-dom": "latest", "react-dom": "latest",
"react-dropzone": "^14.2.3", "react-dropzone": "^14.2.3",
"react-icons": "^4.10.1", "react-icons": "^4.10.1",
"react-router-dom": "^6.14.1", "react-router-dom": "^6.14.2",
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"sockette": "^2.0.6", "sockette": "^2.0.6",
"typesafe-i18n": "^5.24.4", "typesafe-i18n": "^5.25.1",
"typescript": "^5.1.6" "typescript": "^5.1.6"
}, },
"devDependencies": { "devDependencies": {
"@preact/preset-vite": "^2.5.0", "@preact/preset-vite": "^2.5.0",
"@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.0.0", "@typescript-eslint/parser": "^6.1.0",
"cspell": "^6.31.1", "cspell": "^6.31.2",
"eslint": "^8.45.0", "eslint": "^8.45.0",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-airbnb-typescript": "^17.1.0",
@@ -62,14 +62,14 @@
"eslint-plugin-import": "^2.27.5", "eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "alpha", "eslint-plugin-prettier": "alpha",
"eslint-plugin-react": "^7.32.2", "eslint-plugin-react": "^7.33.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"nodemon": "^3.0.1", "nodemon": "^3.0.1",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^3.0.0", "prettier": "^3.0.0",
"rollup-plugin-visualizer": "^5.9.2", "rollup-plugin-visualizer": "^5.9.2",
"terser": "^5.19.0", "terser": "^5.19.1",
"vite": "^4.4.4", "vite": "^4.4.6",
"vite-plugin-svgr": "^3.2.0", "vite-plugin-svgr": "^3.2.0",
"vite-tsconfig-paths": "^4.2.0" "vite-tsconfig-paths": "^4.2.0"
}, },

View File

@@ -68,10 +68,8 @@ const MqttStatusForm: FC = () => {
return 'Malformed credentials'; return 'Malformed credentials';
case MqttDisconnectReason.MQTT_NOT_AUTHORIZED: case MqttDisconnectReason.MQTT_NOT_AUTHORIZED:
return 'Not authorized'; return 'Not authorized';
case MqttDisconnectReason.ESP8266_NOT_ENOUGH_SPACE:
return 'Device out of memory';
case MqttDisconnectReason.TLS_BAD_FINGERPRINT: case MqttDisconnectReason.TLS_BAD_FINGERPRINT:
return 'Server fingerprint invalid'; return 'TSL fingerprint invalid';
default: default:
return 'Unknown'; return 'Unknown';
} }

View File

@@ -17,7 +17,7 @@ import {
} from '@mui/material'; } from '@mui/material';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { DeviceValueUOM_s } from './types'; import { DeviceValueUOM_s, DeviceValueType } from './types';
import type { EntityItem } from './types'; import type { EntityItem } from './types';
import type Schema from 'async-validator'; import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator'; import type { ValidateFieldsError } from 'async-validator';
@@ -166,17 +166,18 @@ const SettingsEntitiesDialog = ({
fullWidth fullWidth
select select
> >
<MenuItem value={0}>BOOL</MenuItem> <MenuItem value={DeviceValueType.BOOL}>BOOL</MenuItem>
<MenuItem value={1}>INT</MenuItem> <MenuItem value={DeviceValueType.INT}>INT</MenuItem>
<MenuItem value={2}>UINT</MenuItem> <MenuItem value={DeviceValueType.UINT}>UINT</MenuItem>
<MenuItem value={3}>SHORT</MenuItem> <MenuItem value={DeviceValueType.SHORT}>SHORT</MenuItem>
<MenuItem value={4}>USHORT</MenuItem> <MenuItem value={DeviceValueType.USHORT}>USHORT</MenuItem>
<MenuItem value={5}>ULONG</MenuItem> <MenuItem value={DeviceValueType.ULONG}>ULONG</MenuItem>
<MenuItem value={6}>TIME</MenuItem> <MenuItem value={DeviceValueType.TIME}>TIME</MenuItem>
<MenuItem value={DeviceValueType.STRING}>RAW</MenuItem>
</TextField> </TextField>
</Grid> </Grid>
{editItem.value_type !== 0 && ( {editItem.value_type !== DeviceValueType.BOOL && editItem.value_type !== DeviceValueType.STRING && (
<> <>
<Grid item xs={4}> <Grid item xs={4}>
<TextField <TextField
@@ -210,6 +211,21 @@ const SettingsEntitiesDialog = ({
</Grid> </Grid>
</> </>
)} )}
{editItem.value_type === DeviceValueType.STRING && (
<Grid item xs={4}>
<TextField
name="factor"
label="Bytes"
value={editItem.factor}
variant="outlined"
onChange={updateFormValue}
fullWidth
margin="normal"
type="number"
inputProps={{ min: '1', max: '27', step: '1' }}
/>
</Grid>
)}
</Grid> </Grid>
</DialogContent> </DialogContent>

View File

@@ -243,7 +243,8 @@ export const BOARD_PROFILES: BoardProfiles = {
OLIMEXPOE: 'Olimex ESP32-POE', OLIMEXPOE: 'Olimex ESP32-POE',
C3MINI: 'Wemos C3 Mini', C3MINI: 'Wemos C3 Mini',
S2MINI: 'Wemos S2 Mini', S2MINI: 'Wemos S2 Mini',
S3MINI: 'Liligo S3' S3MINI: 'Liligo S3',
S32S3: 'BBQKees Gateway S3'
}; };
export interface BoardProfile { export interface BoardProfile {
@@ -364,3 +365,17 @@ export const enum DeviceType {
CUSTOM, CUSTOM,
UNKNOWN UNKNOWN
} }
// matches emsdevicevalue.h
export const enum DeviceValueType {
BOOL,
INT,
UINT,
SHORT,
USHORT,
ULONG,
TIME, // same as ULONG (32 bits)
ENUM,
STRING,
CMD
}

View File

@@ -8,7 +8,7 @@ export const GPIO_VALIDATOR = {
if ( if (
value && value &&
(value === 1 || (value === 1 ||
(value >= 10 && value <= 12) || (value >= 6 && value <= 12) ||
(value >= 14 && value <= 15) || (value >= 14 && value <= 15) ||
value === 20 || value === 20 ||
value === 24 || value === 24 ||
@@ -43,6 +43,23 @@ export const GPIO_VALIDATORS2 = {
} }
}; };
export const GPIO_VALIDATORS3 = {
validator(rule: InternalRuleItem, value: number, callback: (error?: string) => void) {
if (
value &&
((value >= 19 && value <= 20) ||
(value >= 22 && value <= 37) ||
(value >= 39 && value <= 42) ||
value > 48 ||
value < 0)
) {
callback('Must be an valid GPIO port');
} else {
callback();
}
}
};
export const createSettingsValidator = (settings: Settings) => export const createSettingsValidator = (settings: Settings) =>
new Schema({ new Schema({
...(settings.board_profile === 'CUSTOM' && ...(settings.board_profile === 'CUSTOM' &&
@@ -69,6 +86,14 @@ export const createSettingsValidator = (settings: Settings) =>
tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORS2], tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORS2],
rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORS2] rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORS2]
}), }),
...(settings.board_profile === 'CUSTOM' &&
settings.platform === 'ESP32-S3' && {
led_gpio: [{ required: true, message: 'LED GPIO is required' }, GPIO_VALIDATORS3],
dallas_gpio: [{ required: true, message: 'GPIO is required' }, GPIO_VALIDATORS3],
pbutton_gpio: [{ required: true, message: 'Button GPIO is required' }, GPIO_VALIDATORS3],
tx_gpio: [{ required: true, message: 'Tx GPIO is required' }, GPIO_VALIDATORS3],
rx_gpio: [{ required: true, message: 'Rx GPIO is required' }, GPIO_VALIDATORS3]
}),
...(settings.syslog_enabled && { ...(settings.syslog_enabled && {
syslog_host: [{ required: true, message: 'Host is required' }, IP_OR_HOSTNAME_VALIDATOR], syslog_host: [{ required: true, message: 'Host is required' }, IP_OR_HOSTNAME_VALIDATOR],
syslog_port: [ syslog_port: [

View File

@@ -1,12 +1,12 @@
export enum MqttDisconnectReason { export enum MqttDisconnectReason {
TCP_DISCONNECTED = 0, USER_OK = 0,
MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 1, MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 1,
MQTT_IDENTIFIER_REJECTED = 2, MQTT_IDENTIFIER_REJECTED = 2,
MQTT_SERVER_UNAVAILABLE = 3, MQTT_SERVER_UNAVAILABLE = 3,
MQTT_MALFORMED_CREDENTIALS = 4, MQTT_MALFORMED_CREDENTIALS = 4,
MQTT_NOT_AUTHORIZED = 5, MQTT_NOT_AUTHORIZED = 5,
ESP8266_NOT_ENOUGH_SPACE = 6, TLS_BAD_FINGERPRINT = 6,
TLS_BAD_FINGERPRINT = 7 TCP_DISCONNECTED = 7
} }
export interface MqttStatus { export interface MqttStatus {

View File

@@ -269,7 +269,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.5, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7": "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.5, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7":
version: 7.22.6 version: 7.22.6
resolution: "@babel/runtime@npm:7.22.6" resolution: "@babel/runtime@npm:7.22.6"
dependencies: dependencies:
@@ -318,9 +318,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@cspell/cspell-bundled-dicts@npm:6.31.1": "@cspell/cspell-bundled-dicts@npm:6.31.2":
version: 6.31.1 version: 6.31.2
resolution: "@cspell/cspell-bundled-dicts@npm:6.31.1" resolution: "@cspell/cspell-bundled-dicts@npm:6.31.2"
dependencies: dependencies:
"@cspell/dict-ada": ^4.0.1 "@cspell/dict-ada": ^4.0.1
"@cspell/dict-aws": ^3.0.0 "@cspell/dict-aws": ^3.0.0
@@ -339,7 +339,7 @@ __metadata:
"@cspell/dict-en-gb": 1.1.33 "@cspell/dict-en-gb": 1.1.33
"@cspell/dict-en_us": ^4.3.2 "@cspell/dict-en_us": ^4.3.2
"@cspell/dict-filetypes": ^3.0.0 "@cspell/dict-filetypes": ^3.0.0
"@cspell/dict-fonts": ^3.0.1 "@cspell/dict-fonts": ^3.0.2
"@cspell/dict-fullstack": ^3.1.5 "@cspell/dict-fullstack": ^3.1.5
"@cspell/dict-gaming-terms": ^1.0.4 "@cspell/dict-gaming-terms": ^1.0.4
"@cspell/dict-git": ^2.0.0 "@cspell/dict-git": ^2.0.0
@@ -368,7 +368,7 @@ __metadata:
"@cspell/dict-swift": ^2.0.1 "@cspell/dict-swift": ^2.0.1
"@cspell/dict-typescript": ^3.1.1 "@cspell/dict-typescript": ^3.1.1
"@cspell/dict-vue": ^3.0.0 "@cspell/dict-vue": ^3.0.0
checksum: 410028900a67cf84e0c3c4bfc8f4cd1b71a331d2b9541d3018e9919d5645beb8553a118cfbf2a30ef2b5668331464fcbf5791d6bcc41fcf7e1601e5289a1df8a checksum: 266a6a5da4d1e0f1eecefcb1066d54d795e8bfdf8aab29efacb1819c9db0c9493eb8b66c301f72961d25434ec65ad412c64b25a590a529d908e37edd3da8368a
languageName: node languageName: node
linkType: hard linkType: hard
@@ -519,7 +519,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@cspell/dict-fonts@npm:^3.0.1": "@cspell/dict-fonts@npm:^3.0.2":
version: 3.0.2 version: 3.0.2
resolution: "@cspell/dict-fonts@npm:3.0.2" resolution: "@cspell/dict-fonts@npm:3.0.2"
checksum: 69efaa7455242d0a5b62a6e8d0347429a73d3035a205d53025951207768e6950e76166c45f3dd130879ed2ee2c76d9902995cb603cae8a9ad6d2019015666c25 checksum: 69efaa7455242d0a5b62a6e8d0347429a73d3035a205d53025951207768e6950e76166c45f3dd130879ed2ee2c76d9902995cb603cae8a9ad6d2019015666c25
@@ -1040,7 +1040,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.3.0": "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0":
version: 4.4.0 version: 4.4.0
resolution: "@eslint-community/eslint-utils@npm:4.4.0" resolution: "@eslint-community/eslint-utils@npm:4.4.0"
dependencies: dependencies:
@@ -1051,7 +1051,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.5.0": "@eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.5.1":
version: 4.5.1 version: 4.5.1
resolution: "@eslint-community/regexpp@npm:4.5.1" resolution: "@eslint-community/regexpp@npm:4.5.1"
checksum: d79cbd99cc4dcfbb17e8dd30a30bb5aec5da9c60b9471043f886f116615bb15f0d417cb0ca638cefedba0b4c67c339e2011b53d88264a4540775f042a5879e01 checksum: d79cbd99cc4dcfbb17e8dd30a30bb5aec5da9c60b9471043f886f116615bb15f0d417cb0ca638cefedba0b4c67c339e2011b53d88264a4540775f042a5879e01
@@ -1180,14 +1180,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@mui/base@npm:5.0.0-beta.7": "@mui/base@npm:5.0.0-beta.8":
version: 5.0.0-beta.7 version: 5.0.0-beta.8
resolution: "@mui/base@npm:5.0.0-beta.7" resolution: "@mui/base@npm:5.0.0-beta.8"
dependencies: dependencies:
"@babel/runtime": ^7.22.5 "@babel/runtime": ^7.22.6
"@emotion/is-prop-valid": ^1.2.1 "@emotion/is-prop-valid": ^1.2.1
"@mui/types": ^7.2.4 "@mui/types": ^7.2.4
"@mui/utils": ^5.13.7 "@mui/utils": ^5.14.1
"@popperjs/core": ^2.11.8 "@popperjs/core": ^2.11.8
clsx: ^1.2.1 clsx: ^1.2.1
prop-types: ^15.8.1 prop-types: ^15.8.1
@@ -1199,22 +1199,22 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
"@types/react": "@types/react":
optional: true optional: true
checksum: 31e0f319bedc6f89a57d1e8b82ba7a5138edeeabda8d9fac32ba68b0011dda4f05031a4fc8585e87bfbed35607d98a16e5aa0a99ec44bff0112a4ad33429c3e1 checksum: 05274f58ca4ea78b7ca9bf7170d6333010a0ce4cd96c9d4ed7f0741e0c1e72b90327babd8a976af97bc1415beb37064a2fe38b7da8dd74cfddebf478cb3386bf
languageName: node languageName: node
linkType: hard linkType: hard
"@mui/core-downloads-tracker@npm:^5.14.0": "@mui/core-downloads-tracker@npm:^5.14.1":
version: 5.14.0 version: 5.14.1
resolution: "@mui/core-downloads-tracker@npm:5.14.0" resolution: "@mui/core-downloads-tracker@npm:5.14.1"
checksum: b25ca47667a45075d0ba5838e1be46f2f9768ed43154a815d922871f936a513284877637fdfaa44d0f2a1c8d7bc1af63002c27f5a6310eae217705f0004bb6ac checksum: 59e30e15c81bfdf5401b45bc899402dda68e9b042e3e39c85e23635d59592d0552d0a4714c3b23014767a9fdb3fd7d171203a777a39400b6a8f70131b3d6114e
languageName: node languageName: node
linkType: hard linkType: hard
"@mui/icons-material@npm:^5.14.0": "@mui/icons-material@npm:^5.14.1":
version: 5.14.0 version: 5.14.1
resolution: "@mui/icons-material@npm:5.14.0" resolution: "@mui/icons-material@npm:5.14.1"
dependencies: dependencies:
"@babel/runtime": ^7.22.5 "@babel/runtime": ^7.22.6
peerDependencies: peerDependencies:
"@mui/material": ^5.0.0 "@mui/material": ^5.0.0
"@types/react": ^17.0.0 || ^18.0.0 "@types/react": ^17.0.0 || ^18.0.0
@@ -1222,20 +1222,20 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
"@types/react": "@types/react":
optional: true optional: true
checksum: bb82a34b318f1106dec039ccf9ed9d16a7b2d97ef2b87fa7e02acd0118a43573405568d75f78b1833fbbcf21f1ff3108ee7b4582092971335a60560d977279e5 checksum: 5a7bf10bf2b1cf2e73e8857e95d3252936c8a1a25c7797240cc378e37bf842ab3f5dae070f410a228798a6740d84c14f7ee6dad8cd6871cb56d1f1c6b51ce217
languageName: node languageName: node
linkType: hard linkType: hard
"@mui/material@npm:^5.14.0": "@mui/material@npm:^5.14.1":
version: 5.14.0 version: 5.14.1
resolution: "@mui/material@npm:5.14.0" resolution: "@mui/material@npm:5.14.1"
dependencies: dependencies:
"@babel/runtime": ^7.22.5 "@babel/runtime": ^7.22.6
"@mui/base": 5.0.0-beta.7 "@mui/base": 5.0.0-beta.8
"@mui/core-downloads-tracker": ^5.14.0 "@mui/core-downloads-tracker": ^5.14.1
"@mui/system": ^5.14.0 "@mui/system": ^5.14.1
"@mui/types": ^7.2.4 "@mui/types": ^7.2.4
"@mui/utils": ^5.13.7 "@mui/utils": ^5.14.1
"@types/react-transition-group": ^4.4.6 "@types/react-transition-group": ^4.4.6
clsx: ^1.2.1 clsx: ^1.2.1
csstype: ^3.1.2 csstype: ^3.1.2
@@ -1255,7 +1255,7 @@ __metadata:
optional: true optional: true
"@types/react": "@types/react":
optional: true optional: true
checksum: 54d87a27c7ab36fc499d37f65556b469e545c50d0fa9ab15a5c10bfab4402ccd4a47e300d749205248fd712540b5fcae5ac0d6b4a00c92f931aba68f501228ea checksum: 1033116ff4321ebda4d3463dd386d9414bee1f700b1c86b38d009b55212a5079e92db6dbd262f795f004e02a0de3d97897f6c5c58d178cd1588ee8e0430b875e
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1297,15 +1297,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@mui/system@npm:^5.14.0": "@mui/system@npm:^5.14.1":
version: 5.14.0 version: 5.14.1
resolution: "@mui/system@npm:5.14.0" resolution: "@mui/system@npm:5.14.1"
dependencies: dependencies:
"@babel/runtime": ^7.22.5 "@babel/runtime": ^7.22.6
"@mui/private-theming": ^5.13.7 "@mui/private-theming": ^5.13.7
"@mui/styled-engine": ^5.13.2 "@mui/styled-engine": ^5.13.2
"@mui/types": ^7.2.4 "@mui/types": ^7.2.4
"@mui/utils": ^5.13.7 "@mui/utils": ^5.14.1
clsx: ^1.2.1 clsx: ^1.2.1
csstype: ^3.1.2 csstype: ^3.1.2
prop-types: ^15.8.1 prop-types: ^15.8.1
@@ -1321,7 +1321,7 @@ __metadata:
optional: true optional: true
"@types/react": "@types/react":
optional: true optional: true
checksum: df44fc84f52148109c216b5390d5bdc6bcdf84ad0c2e148bda8bf40b04823146eaaaab270c38801eea366677050360bb892ec2b8e2e84b02a98842feff1077f1 checksum: f0ee733311a5320a45e3a6a017dc25d0e8a5c33b3cd2bb726fdd9caee05a712704613d9ad35362fbc2e072ede4c0d633a1219e2b807f2febba0d7ea13ea1d0e4
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1352,6 +1352,21 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@mui/utils@npm:^5.14.1":
version: 5.14.1
resolution: "@mui/utils@npm:5.14.1"
dependencies:
"@babel/runtime": ^7.22.6
"@types/prop-types": ^15.7.5
"@types/react-is": ^18.2.1
prop-types: ^15.8.1
react-is: ^18.2.0
peerDependencies:
react: ^17.0.0 || ^18.0.0
checksum: fb156bce01309affc313417fe1c8d6d486da1b76de11a6b233b8e422a757265d48981696701c098b4a8f30e11fdf4af2cde0cfda9f38ccd8cac7c4be5b5aeaaa
languageName: node
linkType: hard
"@nicolo-ribaudo/semver-v6@npm:^6.3.3": "@nicolo-ribaudo/semver-v6@npm:^6.3.3":
version: 6.3.3 version: 6.3.3
resolution: "@nicolo-ribaudo/semver-v6@npm:6.3.3" resolution: "@nicolo-ribaudo/semver-v6@npm:6.3.3"
@@ -1492,10 +1507,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@remix-run/router@npm:1.7.1": "@remix-run/router@npm:1.7.2":
version: 1.7.1 version: 1.7.2
resolution: "@remix-run/router@npm:1.7.1" resolution: "@remix-run/router@npm:1.7.2"
checksum: 4b0828529dfb2628e8e737c19bbb360dd373c0452803942611184a2ed304e39fe13996333edd05fda3c265875a78a7f31af743dbb098cbf1186105b76e10949f checksum: 01b1b57cae81c2a87fd2125d19918073c5832171957b958c476fd2b95c9f80aef51b1e54cfbe05da123bd8f4517321b27e9905e4552364925dc5a308e6544cfb
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1685,7 +1700,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/json-schema@npm:^7.0.11": "@types/json-schema@npm:^7.0.12":
version: 7.0.12 version: 7.0.12
resolution: "@types/json-schema@npm:7.0.12" resolution: "@types/json-schema@npm:7.0.12"
checksum: 2c39946ae321fe42d085c61a85872a81bbee70f9b2054ad344e8811dfc478fdbaf1ebf5f2989bb87c895ba2dfc3b1dcba85db11e467bbcdc023708814207791c checksum: 2c39946ae321fe42d085c61a85872a81bbee70f9b2054ad344e8811dfc478fdbaf1ebf5f2989bb87c895ba2dfc3b1dcba85db11e467bbcdc023708814207791c
@@ -1813,29 +1828,28 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/semver@npm:^7.3.12": "@types/semver@npm:^7.5.0":
version: 7.5.0 version: 7.5.0
resolution: "@types/semver@npm:7.5.0" resolution: "@types/semver@npm:7.5.0"
checksum: ca4ba4642b5972b6e88e73c5bc02bbaceb8d76bce71748d86e3e95042d4e5a44603113a1dcd2cb9b73ad6f91f6e4ab73185eb41bbfc9c73b11f0ed3db3b7443a checksum: ca4ba4642b5972b6e88e73c5bc02bbaceb8d76bce71748d86e3e95042d4e5a44603113a1dcd2cb9b73ad6f91f6e4ab73185eb41bbfc9c73b11f0ed3db3b7443a
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/eslint-plugin@npm:^6.0.0": "@typescript-eslint/eslint-plugin@npm:^6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/eslint-plugin@npm:6.0.0" resolution: "@typescript-eslint/eslint-plugin@npm:6.1.0"
dependencies: dependencies:
"@eslint-community/regexpp": ^4.5.0 "@eslint-community/regexpp": ^4.5.1
"@typescript-eslint/scope-manager": 6.0.0 "@typescript-eslint/scope-manager": 6.1.0
"@typescript-eslint/type-utils": 6.0.0 "@typescript-eslint/type-utils": 6.1.0
"@typescript-eslint/utils": 6.0.0 "@typescript-eslint/utils": 6.1.0
"@typescript-eslint/visitor-keys": 6.0.0 "@typescript-eslint/visitor-keys": 6.1.0
debug: ^4.3.4 debug: ^4.3.4
grapheme-splitter: ^1.0.4
graphemer: ^1.4.0 graphemer: ^1.4.0
ignore: ^5.2.4 ignore: ^5.2.4
natural-compare: ^1.4.0 natural-compare: ^1.4.0
natural-compare-lite: ^1.4.0 natural-compare-lite: ^1.4.0
semver: ^7.5.0 semver: ^7.5.4
ts-api-utils: ^1.0.1 ts-api-utils: ^1.0.1
peerDependencies: peerDependencies:
"@typescript-eslint/parser": ^6.0.0 || ^6.0.0-alpha "@typescript-eslint/parser": ^6.0.0 || ^6.0.0-alpha
@@ -1843,44 +1857,44 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 0928778c40fe632b3b4672e7d724d0f624724da36fa3c37fe831fc6e7b6e3f80bb860fc5e46457bd2e61ed863af3122dec3d75f843e81b866fe7bd6f7b4cbf7d checksum: 32b59eb2fe4464e0e968c0a25cc02e8ef49aa5049287413a133414287cd4d020b273e2a7884b6b75530ab4f46ed868cefa42f2bb7dea80dac897f2800781122a
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/parser@npm:^6.0.0": "@typescript-eslint/parser@npm:^6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/parser@npm:6.0.0" resolution: "@typescript-eslint/parser@npm:6.1.0"
dependencies: dependencies:
"@typescript-eslint/scope-manager": 6.0.0 "@typescript-eslint/scope-manager": 6.1.0
"@typescript-eslint/types": 6.0.0 "@typescript-eslint/types": 6.1.0
"@typescript-eslint/typescript-estree": 6.0.0 "@typescript-eslint/typescript-estree": 6.1.0
"@typescript-eslint/visitor-keys": 6.0.0 "@typescript-eslint/visitor-keys": 6.1.0
debug: ^4.3.4 debug: ^4.3.4
peerDependencies: peerDependencies:
eslint: ^7.0.0 || ^8.0.0 eslint: ^7.0.0 || ^8.0.0
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: f4e4de103534378c7835bea95299282c2f997061c304a242f4fac7ccca3862f3b98b634ee0b3bb2627ac557f84fd012ab8478d6207849d6b4e6b389b02444efb checksum: 7735838979bff61f10e38b5e8dc4180fd80c7e4ba544b18e648c443c83452355879c0793b098f1d9eb917187b7fd08985e266c2c093b0fb251e7c6d3b9c29d25
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/scope-manager@npm:6.0.0": "@typescript-eslint/scope-manager@npm:6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/scope-manager@npm:6.0.0" resolution: "@typescript-eslint/scope-manager@npm:6.1.0"
dependencies: dependencies:
"@typescript-eslint/types": 6.0.0 "@typescript-eslint/types": 6.1.0
"@typescript-eslint/visitor-keys": 6.0.0 "@typescript-eslint/visitor-keys": 6.1.0
checksum: 0a4666f84775e335c985b1c118a15fd99b741316395d85e5d207ef2d6192f9aae91ed7771849f780b4c57772795868aecb60a2f1ace9f4f1202c183373a565a8 checksum: 6cb3ae7cfe6159f5ad3efb1ef9a75066dbcbf6df0ff590c3c59209d6b9f8f2b9b528535ec21d06df85296684ba7d9e0be0c7b8d416e98aee0b6aec6b10937c4b
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/type-utils@npm:6.0.0": "@typescript-eslint/type-utils@npm:6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/type-utils@npm:6.0.0" resolution: "@typescript-eslint/type-utils@npm:6.1.0"
dependencies: dependencies:
"@typescript-eslint/typescript-estree": 6.0.0 "@typescript-eslint/typescript-estree": 6.1.0
"@typescript-eslint/utils": 6.0.0 "@typescript-eslint/utils": 6.1.0
debug: ^4.3.4 debug: ^4.3.4
ts-api-utils: ^1.0.1 ts-api-utils: ^1.0.1
peerDependencies: peerDependencies:
@@ -1888,60 +1902,59 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: b655304feb7f1c8b641c312bec68e74243f408d24543af2e84bc591a14379814ed6c65f6fa061202b04dd39b02152f38c11cd50dd614967fa8027c5b831da3a5 checksum: 348e0adec7194e1abd8cf62ba31593a52fabc32ace88784ce7fce161544f36fd71e1d0429368744744f5904352878813dd17048c3f9d0865afd838160acbac84
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/types@npm:6.0.0": "@typescript-eslint/types@npm:6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/types@npm:6.0.0" resolution: "@typescript-eslint/types@npm:6.1.0"
checksum: 5183652b95cc8cabfb87e3e2acde9c0c72defc784419f8f45cbe650c4f7a17e3064696a9c35cda6819986da2793b054e027d59ab661862cb73beb58f62155b25 checksum: 6325c368a66c240e7f6f01debbfd097cd1e2405b4a06f8b0211b5f6edef710e3d7fb266582df90fbaf4960ea021576fb6f3a0ddfe20191b1ffac7bea1419b99a
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/typescript-estree@npm:6.0.0": "@typescript-eslint/typescript-estree@npm:6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/typescript-estree@npm:6.0.0" resolution: "@typescript-eslint/typescript-estree@npm:6.1.0"
dependencies: dependencies:
"@typescript-eslint/types": 6.0.0 "@typescript-eslint/types": 6.1.0
"@typescript-eslint/visitor-keys": 6.0.0 "@typescript-eslint/visitor-keys": 6.1.0
debug: ^4.3.4 debug: ^4.3.4
globby: ^11.1.0 globby: ^11.1.0
is-glob: ^4.0.3 is-glob: ^4.0.3
semver: ^7.5.0 semver: ^7.5.4
ts-api-utils: ^1.0.1 ts-api-utils: ^1.0.1
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 0845e6fd2d2dc4b7187b910b8ceda4bdb2d89090fbbcf294c8b8d36701ff5c81f1efc6424860db15c6a6367f4205d0f3c24a5293f1a6cc25a39ebbd52ef2b91d checksum: 0576b6751afd35f19e7b8e8a47b0813df20a549ac25778afade877af2692b84ce50235fd98d3441033f8ae72e2bab0f4b49481cd6d65e91669c8817fe50a8bbb
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/utils@npm:6.0.0": "@typescript-eslint/utils@npm:6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/utils@npm:6.0.0" resolution: "@typescript-eslint/utils@npm:6.1.0"
dependencies: dependencies:
"@eslint-community/eslint-utils": ^4.3.0 "@eslint-community/eslint-utils": ^4.4.0
"@types/json-schema": ^7.0.11 "@types/json-schema": ^7.0.12
"@types/semver": ^7.3.12 "@types/semver": ^7.5.0
"@typescript-eslint/scope-manager": 6.0.0 "@typescript-eslint/scope-manager": 6.1.0
"@typescript-eslint/types": 6.0.0 "@typescript-eslint/types": 6.1.0
"@typescript-eslint/typescript-estree": 6.0.0 "@typescript-eslint/typescript-estree": 6.1.0
eslint-scope: ^5.1.1 semver: ^7.5.4
semver: ^7.5.0
peerDependencies: peerDependencies:
eslint: ^7.0.0 || ^8.0.0 eslint: ^7.0.0 || ^8.0.0
checksum: 7027316300d337e0004b56db0de53bb74c71a06b508377d9ce3bce9a8698f33aaf9e4f1ddbaec2daf6f9bfcf2f6ee80dd9c35117858ab72e2ca17d7abfae9313 checksum: 768934347c12bb6a0ac1d8acad4f99f990e14d16c47547ad5d034c6a7d6559169c1c01b3c9835253f06bb710d34eb4825c1f01fbe55cb8030293b83d064de889
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/visitor-keys@npm:6.0.0": "@typescript-eslint/visitor-keys@npm:6.1.0":
version: 6.0.0 version: 6.1.0
resolution: "@typescript-eslint/visitor-keys@npm:6.0.0" resolution: "@typescript-eslint/visitor-keys@npm:6.1.0"
dependencies: dependencies:
"@typescript-eslint/types": 6.0.0 "@typescript-eslint/types": 6.1.0
eslint-visitor-keys: ^3.4.1 eslint-visitor-keys: ^3.4.1
checksum: 389eee2b479d47b1afbf6c344fa8601e6a47499cce069acd9e94fc57bd85bc16af1c8583bb301b704076e33589b0eec9ee71e6977709c18b59e345f45e3a9277 checksum: 4cdce09c72a187c3a3b9f9514b85a615ede0618f3138935cfee61d11232aa8fe31f753d04e7601a72631b9fb10318f9660ecb27089688f0cf602a23e7614901e
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1952,8 +1965,8 @@ __metadata:
"@alova/adapter-xhr": ^1.0.1 "@alova/adapter-xhr": ^1.0.1
"@emotion/react": ^11.11.1 "@emotion/react": ^11.11.1
"@emotion/styled": ^11.11.0 "@emotion/styled": ^11.11.0
"@mui/icons-material": ^5.14.0 "@mui/icons-material": ^5.14.1
"@mui/material": ^5.14.0 "@mui/material": ^5.14.1
"@preact/compat": ^17.1.2 "@preact/compat": ^17.1.2
"@preact/preset-vite": ^2.5.0 "@preact/preset-vite": ^2.5.0
"@table-library/react-table-library": 4.1.4 "@table-library/react-table-library": 4.1.4
@@ -1962,11 +1975,11 @@ __metadata:
"@types/react": ^18.2.15 "@types/react": ^18.2.15
"@types/react-dom": ^18.2.7 "@types/react-dom": ^18.2.7
"@types/react-router-dom": ^5.3.3 "@types/react-router-dom": ^5.3.3
"@typescript-eslint/eslint-plugin": ^6.0.0 "@typescript-eslint/eslint-plugin": ^6.1.0
"@typescript-eslint/parser": ^6.0.0 "@typescript-eslint/parser": ^6.1.0
alova: ^2.9.2 alova: ^2.9.3
async-validator: ^4.2.5 async-validator: ^4.2.5
cspell: ^6.31.1 cspell: ^6.31.2
eslint: ^8.45.0 eslint: ^8.45.0
eslint-config-airbnb: ^19.0.4 eslint-config-airbnb: ^19.0.4
eslint-config-airbnb-typescript: ^17.1.0 eslint-config-airbnb-typescript: ^17.1.0
@@ -1976,7 +1989,7 @@ __metadata:
eslint-plugin-import: ^2.27.5 eslint-plugin-import: ^2.27.5
eslint-plugin-jsx-a11y: ^6.7.1 eslint-plugin-jsx-a11y: ^6.7.1
eslint-plugin-prettier: alpha eslint-plugin-prettier: alpha
eslint-plugin-react: ^7.32.2 eslint-plugin-react: ^7.33.0
eslint-plugin-react-hooks: ^4.6.0 eslint-plugin-react-hooks: ^4.6.0
history: ^5.3.0 history: ^5.3.0
jwt-decode: ^3.1.2 jwt-decode: ^3.1.2
@@ -1990,14 +2003,14 @@ __metadata:
react-dom: latest react-dom: latest
react-dropzone: ^14.2.3 react-dropzone: ^14.2.3
react-icons: ^4.10.1 react-icons: ^4.10.1
react-router-dom: ^6.14.1 react-router-dom: ^6.14.2
react-toastify: ^9.1.3 react-toastify: ^9.1.3
rollup-plugin-visualizer: ^5.9.2 rollup-plugin-visualizer: ^5.9.2
sockette: ^2.0.6 sockette: ^2.0.6
terser: ^5.19.0 terser: ^5.19.1
typesafe-i18n: ^5.24.4 typesafe-i18n: ^5.25.1
typescript: ^5.1.6 typescript: ^5.1.6
vite: ^4.4.4 vite: ^4.4.6
vite-plugin-svgr: ^3.2.0 vite-plugin-svgr: ^3.2.0
vite-tsconfig-paths: ^4.2.0 vite-tsconfig-paths: ^4.2.0
languageName: unknown languageName: unknown
@@ -2070,10 +2083,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"alova@npm:^2.9.2": "alova@npm:^2.9.3":
version: 2.9.2 version: 2.9.3
resolution: "alova@npm:2.9.2" resolution: "alova@npm:2.9.3"
checksum: 9f2c462303bbf2a82b265c258be9a2c1f9cde4f1591c06b51a3994f50860e250d507b83bbf79ae2c26f79d82c2d1770aba707fa542c6a68df4ce6b93d5a402cf checksum: 1b63c2750e1ee027178c64c414c4fe720112f35ca7b13d7b24d3d9573c4ac4a7b17eae7cc06bed4f9f1bc29a45e337df0d638bdd92a92ad43cff0a19d9d77402
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2723,24 +2736,24 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cspell-gitignore@npm:6.31.1": "cspell-gitignore@npm:6.31.2":
version: 6.31.1 version: 6.31.2
resolution: "cspell-gitignore@npm:6.31.1" resolution: "cspell-gitignore@npm:6.31.2"
dependencies: dependencies:
cspell-glob: 6.31.1 cspell-glob: 6.31.2
find-up: ^5.0.0 find-up: ^5.0.0
bin: bin:
cspell-gitignore: bin.mjs cspell-gitignore: bin.mjs
checksum: f8eaaee8762bfb70ab442179b45ac4e80b740c8aaebfae2427595a0965c5b4e020d13de57bb0db706d63938c6bc08ff132eecd0f50545d8621c71e78fe1deebb checksum: 0772a6edd339a40d7b942b433739d0a9821fd0e1d6ad52c5ff8495f8b222bfe03064051987b80e58a5b67160129fa34dc8fbc198b3266880c52e2c34ffccfbbf
languageName: node languageName: node
linkType: hard linkType: hard
"cspell-glob@npm:6.31.1": "cspell-glob@npm:6.31.2":
version: 6.31.1 version: 6.31.2
resolution: "cspell-glob@npm:6.31.1" resolution: "cspell-glob@npm:6.31.2"
dependencies: dependencies:
micromatch: ^4.0.5 micromatch: ^4.0.5
checksum: 02648a20fca9ee79ea197d849e9a64f5f96753fd3823339928916b68e89c004edba0d2112a8b2b6984e29086892d3d48d911aae5bdaff1c5e54548309ab522e4 checksum: 6661d7e72dd0993e5d4037d0f52ee3bbef802823aace8b708dfb27c9ffd64bbd93c76755a7d88a7221de3a30a56cdd22ec4cb6b970a10f69c0307c378cde4ca5
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2756,21 +2769,21 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cspell-io@npm:6.31.1": "cspell-io@npm:6.31.2":
version: 6.31.1 version: 6.31.2
resolution: "cspell-io@npm:6.31.1" resolution: "cspell-io@npm:6.31.2"
dependencies: dependencies:
"@cspell/cspell-service-bus": 6.31.1 "@cspell/cspell-service-bus": 6.31.1
node-fetch: ^2.6.9 node-fetch: ^2.6.9
checksum: 00d2322d85d49fdf5d9d6a9ab9353b2366ff2834593b8920029376d31f198df5c73f7e15c683f24e95532fef50230819d78a6c7b00cd84a8f5d808550db83514 checksum: 50cb68c57de9a8a7b893f3c3abee8a989c115db4b4aef8227a7b96558408d85accc1fab23bbb67b6d525c091d2d8ba9b7985303ae8edf31fa6f6fa38c523e169
languageName: node languageName: node
linkType: hard linkType: hard
"cspell-lib@npm:6.31.1": "cspell-lib@npm:6.31.2":
version: 6.31.1 version: 6.31.2
resolution: "cspell-lib@npm:6.31.1" resolution: "cspell-lib@npm:6.31.2"
dependencies: dependencies:
"@cspell/cspell-bundled-dicts": 6.31.1 "@cspell/cspell-bundled-dicts": 6.31.2
"@cspell/cspell-pipe": 6.31.1 "@cspell/cspell-pipe": 6.31.1
"@cspell/cspell-types": 6.31.1 "@cspell/cspell-types": 6.31.1
"@cspell/strong-weak-map": 6.31.1 "@cspell/strong-weak-map": 6.31.1
@@ -2779,9 +2792,9 @@ __metadata:
configstore: ^5.0.1 configstore: ^5.0.1
cosmiconfig: 8.0.0 cosmiconfig: 8.0.0
cspell-dictionary: 6.31.1 cspell-dictionary: 6.31.1
cspell-glob: 6.31.1 cspell-glob: 6.31.2
cspell-grammar: 6.31.1 cspell-grammar: 6.31.1
cspell-io: 6.31.1 cspell-io: 6.31.2
cspell-trie-lib: 6.31.1 cspell-trie-lib: 6.31.1
fast-equals: ^4.0.3 fast-equals: ^4.0.3
find-up: ^5.0.0 find-up: ^5.0.0
@@ -2791,7 +2804,7 @@ __metadata:
resolve-global: ^1.0.0 resolve-global: ^1.0.0
vscode-languageserver-textdocument: ^1.0.8 vscode-languageserver-textdocument: ^1.0.8
vscode-uri: ^3.0.7 vscode-uri: ^3.0.7
checksum: 46b1d9411fa7ba98accbfb18a3a327446dfd206645309f9bc53178bc133d5fd9a4a107edb36fd2913c270faaf5847d3a48b4f7bcdbcb971de21a4fa90aea6aa8 checksum: 5003cc0bc33baffffed6031357877ad8696babbe5662e0ddf6aeeee48f6bb41df5c23be5ef04cf3b0f3511d3ef9e6c982992fdedfb084c332adec6ae7f5dec8d
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2806,18 +2819,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cspell@npm:^6.31.1": "cspell@npm:^6.31.2":
version: 6.31.1 version: 6.31.2
resolution: "cspell@npm:6.31.1" resolution: "cspell@npm:6.31.2"
dependencies: dependencies:
"@cspell/cspell-pipe": 6.31.1 "@cspell/cspell-pipe": 6.31.1
"@cspell/cspell-types": 6.31.1
"@cspell/dynamic-import": 6.31.1 "@cspell/dynamic-import": 6.31.1
chalk: ^4.1.2 chalk: ^4.1.2
commander: ^10.0.0 commander: ^10.0.0
cspell-gitignore: 6.31.1 cspell-gitignore: 6.31.2
cspell-glob: 6.31.1 cspell-glob: 6.31.2
cspell-io: 6.31.1 cspell-io: 6.31.2
cspell-lib: 6.31.1 cspell-lib: 6.31.2
fast-glob: ^3.2.12 fast-glob: ^3.2.12
fast-json-stable-stringify: ^2.1.0 fast-json-stable-stringify: ^2.1.0
file-entry-cache: ^6.0.1 file-entry-cache: ^6.0.1
@@ -2829,7 +2843,7 @@ __metadata:
bin: bin:
cspell: bin.js cspell: bin.js
cspell-esm: bin.mjs cspell-esm: bin.mjs
checksum: 81807ecfa28fa961d710b8a4d3336efd53d9162bd765ab1742bfb945c7969b2552e84741251036aa594175ca34a1555aec6d5a9a245ad073cb68b7aeabc1daea checksum: 26549166d95b0fadafcc35c06de3acc73893a499bdf1b6518494d238e4dbb55ec0a47fdcc0e53602e736f58d9e86bfe6096e110ba577328bc739dcb4ef4d7f0c
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3429,9 +3443,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-plugin-react@npm:^7.32.2": "eslint-plugin-react@npm:^7.33.0":
version: 7.32.2 version: 7.33.0
resolution: "eslint-plugin-react@npm:7.32.2" resolution: "eslint-plugin-react@npm:7.33.0"
dependencies: dependencies:
array-includes: ^3.1.6 array-includes: ^3.1.6
array.prototype.flatmap: ^1.3.1 array.prototype.flatmap: ^1.3.1
@@ -3446,11 +3460,11 @@ __metadata:
object.values: ^1.1.6 object.values: ^1.1.6
prop-types: ^15.8.1 prop-types: ^15.8.1
resolve: ^2.0.0-next.4 resolve: ^2.0.0-next.4
semver: ^6.3.0 semver: ^6.3.1
string.prototype.matchall: ^4.0.8 string.prototype.matchall: ^4.0.8
peerDependencies: peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
checksum: 9ddd5cfc508555a5cb3edbdcc9138dd472d269d3a45da0be3e267ea2b3fa1b5990823675208c0e11376c9c55e46aaad5b7a5f46c965eb4dcf6f1eebcebf174c3 checksum: 015aaaa133bacd99bd1f82b91852d6fcca7e2b6c11d1ef96ed3c0dae0b5fe89230f66990e12898f237f3f67296234650130e0337db669c32e30132ccae66a696
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3461,16 +3475,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-scope@npm:^5.1.1":
version: 5.1.1
resolution: "eslint-scope@npm:5.1.1"
dependencies:
esrecurse: ^4.3.0
estraverse: ^4.1.1
checksum: d30ef9dc1c1cbdece34db1539a4933fe3f9b14e1ffb27ecc85987902ee663ad7c9473bbd49a9a03195a373741e62e2f807c4938992e019b511993d163450e70a
languageName: node
linkType: hard
"eslint-scope@npm:^7.2.0": "eslint-scope@npm:^7.2.0":
version: 7.2.0 version: 7.2.0
resolution: "eslint-scope@npm:7.2.0" resolution: "eslint-scope@npm:7.2.0"
@@ -3574,13 +3578,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"estraverse@npm:^4.1.1":
version: 4.3.0
resolution: "estraverse@npm:4.3.0"
checksum: 9cb46463ef8a8a4905d3708a652d60122a0c20bb58dec7e0e12ab0e7235123d74214fc0141d743c381813e1b992767e2708194f6f6e0f9fd00c1b4e0887b8b6d
languageName: node
linkType: hard
"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0":
version: 5.3.0 version: 5.3.0
resolution: "estraverse@npm:5.3.0" resolution: "estraverse@npm:5.3.0"
@@ -4063,13 +4060,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"grapheme-splitter@npm:^1.0.4":
version: 1.0.4
resolution: "grapheme-splitter@npm:1.0.4"
checksum: 108415fb07ac913f17040dc336607772fcea68c7f495ef91887edddb0b0f5ff7bc1d1ab181b125ecb2f0505669ef12c9a178a3bbd2dd8e042d8c5f1d7c90331a
languageName: node
linkType: hard
"graphemer@npm:^1.4.0": "graphemer@npm:^1.4.0":
version: 1.4.0 version: 1.4.0
resolution: "graphemer@npm:1.4.0" resolution: "graphemer@npm:1.4.0"
@@ -5548,14 +5538,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"postcss@npm:^8.4.25": "postcss@npm:^8.4.26":
version: 8.4.25 version: 8.4.26
resolution: "postcss@npm:8.4.25" resolution: "postcss@npm:8.4.26"
dependencies: dependencies:
nanoid: ^3.3.6 nanoid: ^3.3.6
picocolors: ^1.0.0 picocolors: ^1.0.0
source-map-js: ^1.0.2 source-map-js: ^1.0.2
checksum: aa2143cb5ed6eef6cb1d38236f158c5fe11bfd1f338c930cf4901f09586874e05fa006e3fd329ca51c61202c7e90d0705379e6310251c9311116e65cb6a08c18 checksum: 29c603d6b30b2f94bf971bc430600f271da76fa3ae38d4c6b255e957213051b8eeb02829e128ec4e9fa2a7bb710ba7992ebaf1997e3a9ace48caf49b48a10f6b
languageName: node languageName: node
linkType: hard linkType: hard
@@ -5681,27 +5671,27 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-router-dom@npm:^6.14.1": "react-router-dom@npm:^6.14.2":
version: 6.14.1 version: 6.14.2
resolution: "react-router-dom@npm:6.14.1" resolution: "react-router-dom@npm:6.14.2"
dependencies: dependencies:
"@remix-run/router": 1.7.1 "@remix-run/router": 1.7.2
react-router: 6.14.1 react-router: 6.14.2
peerDependencies: peerDependencies:
react: ">=16.8" react: ">=16.8"
react-dom: ">=16.8" react-dom: ">=16.8"
checksum: 9d3a00263125668a9b703ddc908f98218598c216bc77d99931d0cdf7d6a0f7f9d57649f4261e429a5a1c0c51f5203379a6d8e5181e24d0af6c7623fdd966843c checksum: c2025a8d2ddd97438acdee55cdcc6349ad006e17f363c2ea03c2c8f4f82556fb390de287bda7d28f422952d6ab6c91cb058363f214343c26707b194f2eee438b
languageName: node languageName: node
linkType: hard linkType: hard
"react-router@npm:6.14.1": "react-router@npm:6.14.2":
version: 6.14.1 version: 6.14.2
resolution: "react-router@npm:6.14.1" resolution: "react-router@npm:6.14.2"
dependencies: dependencies:
"@remix-run/router": 1.7.1 "@remix-run/router": 1.7.2
peerDependencies: peerDependencies:
react: ">=16.8" react: ">=16.8"
checksum: da870d0739038bb9630a9b3268ec79224bf47aa9f1015e30820cb29a29eabe0bee723991df5cbcb12473d82b7a2e49598e9d539a6f63fa3f2d64f5cc9cc4db64 checksum: cd978b947b4df493128e79d0aeebbea58839beee7bbf5ebaa5fb98ead21da5b69d09344c4ee8803a870fff9a99902b1700706d6639f03e637d956b278af0a47d
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6028,7 +6018,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"semver@npm:^6.0.0": "semver@npm:^6.0.0, semver@npm:^6.3.1":
version: 6.3.1 version: 6.3.1
resolution: "semver@npm:6.3.1" resolution: "semver@npm:6.3.1"
bin: bin:
@@ -6046,7 +6036,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.0, semver@npm:^7.5.3": "semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4":
version: 7.5.4 version: 7.5.4
resolution: "semver@npm:7.5.4" resolution: "semver@npm:7.5.4"
dependencies: dependencies:
@@ -6481,9 +6471,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"terser@npm:^5.19.0": "terser@npm:^5.19.1":
version: 5.19.0 version: 5.19.1
resolution: "terser@npm:5.19.0" resolution: "terser@npm:5.19.1"
dependencies: dependencies:
"@jridgewell/source-map": ^0.3.3 "@jridgewell/source-map": ^0.3.3
acorn: ^8.8.2 acorn: ^8.8.2
@@ -6491,7 +6481,7 @@ __metadata:
source-map-support: ~0.5.20 source-map-support: ~0.5.20
bin: bin:
terser: bin/terser terser: bin/terser
checksum: f12e94091d488b0700d1c519d5805fb46eee2ef7de147b6899b4b9b609895dddd5aabbc53f6a6c76e5ce9154ed7a9c7496b82fefe713a29c75ced45c4623d106 checksum: 32f81b877240140312921c6333671ad31258dd7f1c123847f98fc31ba8f72dda7843d24bf6536501ecdfe2a619f7eb87fc56a68134f6f38d482cbe7b1aafedd3
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6621,14 +6611,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"typesafe-i18n@npm:^5.24.4": "typesafe-i18n@npm:^5.25.1":
version: 5.24.4 version: 5.25.1
resolution: "typesafe-i18n@npm:5.24.4" resolution: "typesafe-i18n@npm:5.25.1"
peerDependencies: peerDependencies:
typescript: ">=3.5.1" typescript: ">=3.5.1"
bin: bin:
typesafe-i18n: cli/typesafe-i18n.mjs typesafe-i18n: cli/typesafe-i18n.mjs
checksum: d464ddc2b6f1f53e840d0e69a2e5c48bfa487180ce1cff4cd6ca489b016c861ef77242b49d05e2ddc35fc41d0d8d2c9816799dde0f4910ca0159c2f1f1499a2a checksum: 1e83383f0141e84a33dc0ad502387372bb0e062c1ce5e24548849f85223ab2be06a2375cfefd919fa9ea27900f37a7b0d9f42c30784d9a561b123543f11ad614
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6774,13 +6764,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vite@npm:^4.4.4": "vite@npm:^4.4.6":
version: 4.4.4 version: 4.4.6
resolution: "vite@npm:4.4.4" resolution: "vite@npm:4.4.6"
dependencies: dependencies:
esbuild: ^0.18.10 esbuild: ^0.18.10
fsevents: ~2.3.2 fsevents: ~2.3.2
postcss: ^8.4.25 postcss: ^8.4.26
rollup: ^3.25.2 rollup: ^3.25.2
peerDependencies: peerDependencies:
"@types/node": ">= 14" "@types/node": ">= 14"
@@ -6810,7 +6800,7 @@ __metadata:
optional: true optional: true
bin: bin:
vite: bin/vite.js vite: bin/vite.js
checksum: 7030c008595eecaf03800292ca6ac626941b7d90b9c18e3ca0de62f8127cb6f7624c2c5e4e5528260fff807996e56e099a6d3bd069a7644eedc13c7df081d818 checksum: 121144e8e9f95a3ec159dde072fefddc076cbf516bcc2078032c63b4f5b9babe760cf0cbc0c4808e02e568e8e7b1d74b742fcf4546fe2e148c4a84fb42a9089a
languageName: node languageName: node
linkType: hard linkType: hard

View File

@@ -1,4 +1,5 @@
#include <UploadFileService.h> #include <UploadFileService.h>
#include <esp_ota_ops.h>
using namespace std::placeholders; // for `_1` etc using namespace std::placeholders; // for `_1` etc
@@ -70,7 +71,7 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri
} }
#endif #endif
// it's firmware - initialize the ArduinoOTA updater // it's firmware - initialize the ArduinoOTA updater
if (Update.begin()) { if (Update.begin(fsize - sizeof(esp_image_header_t))) {
if (strlen(md5) == 32) { if (strlen(md5) == 32) {
Update.setMD5(md5); Update.setMD5(md5);
md5[0] = '\0'; md5[0] = '\0';
@@ -88,7 +89,9 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri
if (!is_firmware) { if (!is_firmware) {
if (len) { if (len) {
request->_tempFile.write(data, len); // stream the incoming chunk to the opened file if (len != request->_tempFile.write(data, len)) { // stream the incoming chunk to the opened file
handleError(request, 507); // 507-Insufficient Storage
}
} }
} else { } else {
// if we haven't delt with an error, continue with the firmware update // if we haven't delt with an error, continue with the firmware update

View File

@@ -563,6 +563,17 @@ void AnalogSensor::publish_values(const bool force) {
// config["step"] = sensor.factor(); // config["step"] = sensor.factor();
} else if (sensor.type() == AnalogType::DIGITAL_IN) { } else if (sensor.type() == AnalogType::DIGITAL_IN) {
snprintf(topic, sizeof(topic), "binary_sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio()); snprintf(topic, sizeof(topic), "binary_sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
config["pl_on"] = true;
config["pl_off"] = false;
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
config["pl_on"] = 1;
config["pl_off"] = 0;
} else {
char result[12];
config["pl_on"] = Helpers::render_boolean(result, true);
config["pl_off"] = Helpers::render_boolean(result, false);
}
} else { } else {
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio()); snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
config["stat_cla"] = "measurement"; config["stat_cla"] = "measurement";
@@ -575,9 +586,7 @@ void AnalogSensor::publish_values(const bool force) {
// add "availability" section // add "availability" section
Mqtt::add_avty_to_doc(stat_t, config.as<JsonObject>(), val_cond); Mqtt::add_avty_to_doc(stat_t, config.as<JsonObject>(), val_cond);
Mqtt::queue_ha(topic, config.as<JsonObject>()); sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
sensor.ha_registered = true;
} }
} }
} }

View File

@@ -410,14 +410,16 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
if (arguments.size() == 4) { if (arguments.size() == 4) {
uint16_t offset = Helpers::hextoint(arguments[2].c_str()); uint16_t offset = Helpers::hextoint(arguments[2].c_str());
uint8_t length = Helpers::hextoint(arguments.back().c_str()); uint8_t length = Helpers::hextoint(arguments.back().c_str());
to_app(shell).send_read_request(type_id, device_id, offset, length); to_app(shell).send_read_request(type_id, device_id, offset, length, true);
} else if (arguments.size() == 3) { } else if (arguments.size() == 3) {
uint16_t offset = Helpers::hextoint(arguments.back().c_str()); uint16_t offset = Helpers::hextoint(arguments.back().c_str());
to_app(shell).send_read_request(type_id, device_id, offset, EMS_MAX_TELEGRAM_LENGTH); to_app(shell).send_read_request(type_id, device_id, offset, EMS_MAX_TELEGRAM_LENGTH, true);
} else { } else {
// send with length to send immediately and trigger publish read_id // send with length to send immediately and trigger publish read_id
to_app(shell).send_read_request(type_id, device_id, 0, EMS_MAX_TELEGRAM_LENGTH); to_app(shell).send_read_request(type_id, device_id, 0, EMS_MAX_TELEGRAM_LENGTH, true);
} }
to_app(shell).set_read_id(type_id);
}); });
commands->add_command(ShellContext::MAIN, commands->add_command(ShellContext::MAIN,

View File

@@ -1645,7 +1645,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
Helpers::translated_word(FL_(minutes))); Helpers::translated_word(FL_(minutes)));
json[name] = time_s; json[name] = time_s;
} else { } else {
json[name] = serialized(Helpers::render_value(val, time_value, 1)); json[name] = serialized(Helpers::render_value(val, time_value, 0));
} }
} }

View File

@@ -76,6 +76,7 @@ uint8_t EMSESP::watch_ = 0; // trace off
uint16_t EMSESP::read_id_ = WATCH_ID_NONE; uint16_t EMSESP::read_id_ = WATCH_ID_NONE;
bool EMSESP::read_next_ = false; bool EMSESP::read_next_ = false;
uint16_t EMSESP::publish_id_ = 0; uint16_t EMSESP::publish_id_ = 0;
uint16_t EMSESP::response_id_ = 0;
bool EMSESP::tap_water_active_ = false; // for when Boiler states we having running warm water. used in Shower() bool EMSESP::tap_water_active_ = false; // for when Boiler states we having running warm water. used in Shower()
uint32_t EMSESP::last_fetch_ = 0; uint32_t EMSESP::last_fetch_ = 0;
uint8_t EMSESP::publish_all_idx_ = 0; uint8_t EMSESP::publish_all_idx_ = 0;
@@ -624,25 +625,36 @@ void EMSESP::publish_sensor_values(const bool time, const bool force) {
// MQTT publish a telegram as raw data to the topic 'response' // MQTT publish a telegram as raw data to the topic 'response'
void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) { void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
StaticJsonDocument<EMSESP_JSON_SIZE_SMALL> doc; static char * buffer = nullptr;
static uint8_t offset;
if (buffer == nullptr) {
offset = telegram->offset; // store offset from first part
buffer = new char[768]; // max 256 hex-codes, 255 spaces, 1 termination
buffer[0] = '\0';
}
strlcat(buffer, Helpers::data_to_hex(telegram->message_data, telegram->message_length).c_str(), 768);
if (response_id_ != 0) {
strlcat(buffer, " ", 768);
return;
}
DynamicJsonDocument doc(EMSESP_JSON_SIZE_LARGE);
char s[10];
doc["src"] = Helpers::hextoa(s, telegram->src);
doc["dest"] = Helpers::hextoa(s, telegram->dest);
doc["type"] = Helpers::hextoa(s, telegram->type_id);
doc["offset"] = Helpers::hextoa(s, offset);
doc["data"] = buffer;
char buffer[100]; if (telegram->message_length <= 4 && strlen(buffer) <= 11) {
doc["src"] = Helpers::hextoa(buffer, telegram->src);
doc["dest"] = Helpers::hextoa(buffer, telegram->dest);
doc["type"] = Helpers::hextoa(buffer, telegram->type_id);
doc["offset"] = Helpers::hextoa(buffer, telegram->offset);
strlcpy(buffer, Helpers::data_to_hex(telegram->message_data, telegram->message_length).c_str(), sizeof(buffer)); // telegram is without crc
doc["data"] = buffer;
if (telegram->message_length <= 4) {
uint32_t value = 0; uint32_t value = 0;
for (uint8_t i = 0; i < telegram->message_length; i++) { for (uint8_t i = 0; i < telegram->message_length; i++) {
value = (value << 8) + telegram->message_data[i]; value = (value << 8) + telegram->message_data[i];
} }
doc["value"] = value; doc["value"] = value;
} }
Mqtt::queue_publish("response", doc.as<JsonObject>()); Mqtt::queue_publish("response", doc.as<JsonObject>());
delete[] buffer;
buffer = nullptr;
} }
// builds json with the detail of each value, for a specific EMS device type or the temperature sensor // builds json with the detail of each value, for a specific EMS device type or the temperature sensor
@@ -847,12 +859,16 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
// returns false if there are none found // returns false if there are none found
bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) { bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
// if watching or reading... // if watching or reading...
if ((telegram->type_id == read_id_) && (telegram->dest == txservice_.ems_bus_id())) { if ((telegram->type_id == read_id_ || telegram->type_id == response_id_) && (telegram->dest == txservice_.ems_bus_id())) {
LOG_INFO("%s", pretty_telegram(telegram).c_str()); // show log for read and response
if (Mqtt::send_response()) { LOG_NOTICE("%s", pretty_telegram(telegram).c_str());
if (telegram->type_id == response_id_) {
if (!read_next_) {
response_id_ = 0;
}
publish_response(telegram); publish_response(telegram);
} }
// check if read is finished or gives more parts
if (!read_next_) { if (!read_next_) {
read_id_ = WATCH_ID_NONE; read_id_ = WATCH_ID_NONE;
} }
@@ -1233,8 +1249,8 @@ bool EMSESP::command_info(uint8_t device_type, JsonObject & output, const int8_t
} }
// send a read request, passing it into to the Tx Service, with optional offset and length // send a read request, passing it into to the Tx Service, with optional offset and length
void EMSESP::send_read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length) { void EMSESP::send_read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length, const bool front) {
txservice_.read_request(type_id, dest, offset, length); txservice_.read_request(type_id, dest, offset, length, front);
} }
// sends write request // sends write request
@@ -1313,7 +1329,8 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
tx_successful = true; tx_successful = true;
// if telegram is longer read next part with offset +25 for ems+ or +27 for ems1.0 // if telegram is longer read next part with offset +25 for ems+ or +27 for ems1.0
if ((length >= 31) && (txservice_.read_next_tx(data[3], length) == read_id_)) { // not for response to raw send commands
if ((response_id_ == 0 || read_id_ > 0) && (length >= 31) && (txservice_.read_next_tx(data[3], length) == read_id_)) {
read_next_ = true; read_next_ = true;
} }
} }

View File

@@ -117,7 +117,7 @@ class EMSESP {
static bool process_telegram(std::shared_ptr<const Telegram> telegram); static bool process_telegram(std::shared_ptr<const Telegram> telegram);
static std::string pretty_telegram(std::shared_ptr<const Telegram> telegram); static std::string pretty_telegram(std::shared_ptr<const Telegram> telegram);
static void send_read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0, const uint8_t length = 0); static void send_read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0, const uint8_t length = 0, const bool front = false);
static void send_write_request(const uint16_t type_id, static void send_write_request(const uint16_t type_id,
const uint8_t dest, const uint8_t dest,
const uint8_t offset, const uint8_t offset,
@@ -176,6 +176,10 @@ class EMSESP {
read_id_ = id; read_id_ = id;
} }
static void set_response_id(uint16_t id) {
response_id_ = id;
}
static bool wait_validate() { static bool wait_validate() {
return (wait_validate_ != 0); return (wait_validate_ != 0);
} }
@@ -259,6 +263,7 @@ class EMSESP {
static uint16_t read_id_; static uint16_t read_id_;
static bool read_next_; static bool read_next_;
static uint16_t publish_id_; static uint16_t publish_id_;
static uint16_t response_id_;
static bool tap_water_active_; static bool tap_water_active_;
static uint8_t publish_all_idx_; static uint8_t publish_all_idx_;
static uint8_t unique_id_count_; static uint8_t unique_id_count_;

View File

@@ -69,6 +69,7 @@ MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "",
MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema") // TODO translate MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema") // TODO translate
MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "", "", "aktywuj wybrany harmonogram", "", "", "", "abilitare l'elemento programmato") // TODO translate MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "", "", "aktywuj wybrany harmonogram", "", "", "", "abilitare l'elemento programmato") // TODO translate
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "", "", "wyślij własną wartość na EMS", "", "", "", "imposta valori personalizzati su EMS") // TODO translate MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "", "", "wyślij własną wartość na EMS", "", "", "", "imposta valori personalizzati su EMS") // TODO translate
MAKE_WORD_TRANSLATION(commands_response, "get response") // TODO translate
// tags // tags
MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw") MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw")

View File

@@ -58,8 +58,9 @@ uint8_t Mqtt::connectcount_ = 0;
uint32_t Mqtt::mqtt_message_id_ = 0; uint32_t Mqtt::mqtt_message_id_ = 0;
char will_topic_[Mqtt::MQTT_TOPIC_MAX_SIZE]; // because MQTT library keeps only char pointer char will_topic_[Mqtt::MQTT_TOPIC_MAX_SIZE]; // because MQTT library keeps only char pointer
std::string Mqtt::lasttopic_ = ""; std::string Mqtt::lasttopic_ = "";
std::string Mqtt::lastpayload_ = ""; std::string Mqtt::lastpayload_ = "";
std::string Mqtt::lastresponse_ = "";
// Home Assistant specific // Home Assistant specific
// icons from https://materialdesignicons.com used with the UOMs (unit of measurements) // icons from https://materialdesignicons.com used with the UOMs (unit of measurements)
@@ -289,14 +290,10 @@ void Mqtt::on_message(const char * topic, const char * message, size_t len) cons
snprintf(error, sizeof(error), "Call failed with error code (%s)", Command::return_code_string(return_code).c_str()); snprintf(error, sizeof(error), "Call failed with error code (%s)", Command::return_code_string(return_code).c_str());
} }
LOG_ERROR(error); LOG_ERROR(error);
if (send_response_) { Mqtt::queue_publish("response", error);
Mqtt::queue_publish("response", error);
}
} else { } else {
// all good, send back json output from call // all good, send back json output from call
if (send_response_) { Mqtt::queue_publish("response", output);
Mqtt::queue_publish("response", output);
}
} }
} }
@@ -478,7 +475,7 @@ void Mqtt::on_disconnect(espMqttClientTypes::DisconnectReason reason) {
} }
} }
// MQTT onConnect - when an MQTT connect is established // MQTT on_connect - when an MQTT connect is established
void Mqtt::on_connect() { void Mqtt::on_connect() {
if (connecting_) { if (connecting_) {
return; // prevent duplicated connections return; // prevent duplicated connections
@@ -587,6 +584,12 @@ void Mqtt::ha_status() {
// add sub or pub task to the queue. // add sub or pub task to the queue.
// the base is not included in the topic // the base is not included in the topic
bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, const std::string & payload, const bool retain) { bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, const std::string & payload, const bool retain) {
if (topic == "response" && operation == Operation::PUBLISH) {
lastresponse_ = payload;
if (!send_response_) {
return true;
}
}
if (!mqtt_enabled_ || topic.empty()) { if (!mqtt_enabled_ || topic.empty()) {
return false; // quit, not using MQTT return false; // quit, not using MQTT
} }
@@ -621,9 +624,6 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con
// add MQTT message to queue, payload is a string // add MQTT message to queue, payload is a string
bool Mqtt::queue_publish_message(const std::string & topic, const std::string & payload, const bool retain) { bool Mqtt::queue_publish_message(const std::string & topic, const std::string & payload, const bool retain) {
if (!enabled()) {
return false;
};
return queue_message(Operation::PUBLISH, topic, payload, retain); return queue_message(Operation::PUBLISH, topic, payload, retain);
} }
@@ -672,8 +672,9 @@ bool Mqtt::queue_publish_retain(const std::string & topic, const JsonObject & pa
} }
bool Mqtt::queue_publish_retain(const char * topic, const JsonObject & payload, const bool retain) { bool Mqtt::queue_publish_retain(const char * topic, const JsonObject & payload, const bool retain) {
if (enabled() && payload.size()) { if (payload.size()) {
std::string payload_text; std::string payload_text;
payload_text.reserve(measureJson(payload) + 1);
serializeJson(payload, payload_text); // convert json to string serializeJson(payload, payload_text); // convert json to string
return queue_publish_message(topic, payload_text, retain); return queue_publish_message(topic, payload_text, retain);
} }
@@ -682,10 +683,6 @@ bool Mqtt::queue_publish_retain(const char * topic, const JsonObject & payload,
// publish empty payload to remove the topic // publish empty payload to remove the topic
bool Mqtt::queue_remove_topic(const char * topic) { bool Mqtt::queue_remove_topic(const char * topic) {
if (!enabled()) {
return false;
}
if (ha_enabled_) { if (ha_enabled_) {
return queue_publish_message(Mqtt::discovery_prefix() + topic, "", true); // publish with retain to remove from broker return queue_publish_message(Mqtt::discovery_prefix() + topic, "", true); // publish with retain to remove from broker
} else { } else {

View File

@@ -201,12 +201,8 @@ class Mqtt {
ha_climate_reset_ = reset; ha_climate_reset_ = reset;
} }
static bool send_response() { static std::string get_response() {
return send_response_; return lastresponse_;
}
static void send_response(bool send_response) {
send_response_ = send_response;
} }
void set_qos(uint8_t mqtt_qos) const { void set_qos(uint8_t mqtt_qos) const {
@@ -270,6 +266,7 @@ class Mqtt {
static std::string lasttopic_; static std::string lasttopic_;
static std::string lastpayload_; static std::string lastpayload_;
static std::string lastresponse_;
// settings, copied over // settings, copied over
static std::string mqtt_base_; static std::string mqtt_base_;

View File

@@ -148,8 +148,6 @@ void Shower::set_shower_state(bool state, bool force) {
// send out HA MQTT Discovery config topic // send out HA MQTT Discovery config topic
if ((Mqtt::ha_enabled()) && (!ha_configdone_ || force)) { if ((Mqtt::ha_enabled()) && (!ha_configdone_ || force)) {
ha_configdone_ = true;
StaticJsonDocument<EMSESP_JSON_SIZE_LARGE> doc; StaticJsonDocument<EMSESP_JSON_SIZE_LARGE> doc;
doc["name"] = "Shower Active"; doc["name"] = "Shower Active";
@@ -189,7 +187,7 @@ void Shower::set_shower_state(bool state, bool force) {
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
snprintf(topic, sizeof(topic), "binary_sensor/%s/shower_active/config", Mqtt::basename().c_str()); snprintf(topic, sizeof(topic), "binary_sensor/%s/shower_active/config", Mqtt::basename().c_str());
Mqtt::queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag ha_configdone_ = Mqtt::queue_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
} }
} }

View File

@@ -98,6 +98,18 @@ bool System::command_send(const char * value, const int8_t id) {
return EMSESP::txservice_.send_raw(value); // ignore id return EMSESP::txservice_.send_raw(value); // ignore id
} }
bool System::command_response(const char * value, const int8_t id, JsonObject & output) {
DynamicJsonDocument doc(EMSESP_JSON_SIZE_LARGE);
if (DeserializationError::Ok == deserializeJson(doc, Mqtt::get_response())) {
for (JsonPair p : doc.as<JsonObject>()) {
output[p.key()] = p.value();
}
} else {
output["response"] = Mqtt::get_response();
}
return true;
}
// fetch device values // fetch device values
bool System::command_fetch(const char * value, const int8_t id) { bool System::command_fetch(const char * value, const int8_t id) {
std::string value_s; std::string value_s;
@@ -753,6 +765,7 @@ void System::commands_init() {
// these commands will return data in JSON format // these commands will return data in JSON format
Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, FL_(system_info_cmd)); Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, FL_(system_info_cmd));
Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, FL_(commands_cmd)); Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, FL_(commands_cmd));
Command::add(EMSdevice::DeviceType::SYSTEM, F("response"), System::command_response, FL_(commands_response));
// MQTT subscribe "ems-esp/system/#" // MQTT subscribe "ems-esp/system/#"
Mqtt::subscribe(EMSdevice::DeviceType::SYSTEM, "system/#", nullptr); // use empty function callback Mqtt::subscribe(EMSdevice::DeviceType::SYSTEM, "system/#", nullptr); // use empty function callback
@@ -1437,6 +1450,8 @@ bool System::load_board_profile(std::vector<int8_t> & data, const std::string &
data = {15, 7, 11, 12, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin S2 Mini data = {15, 7, 11, 12, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Lolin S2 Mini
} else if (board_profile == "S3MINI") { } else if (board_profile == "S3MINI") {
data = {17, 18, 8, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Liligo S3 data = {17, 18, 8, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // Liligo S3
} else if (board_profile == "S32S3") {
data = {2, 18, 5, 17, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0}; // BBQKees Gateway S3
} else if (board_profile == "CUSTOM") { } else if (board_profile == "CUSTOM") {
// send back current values // send back current values
data = {(int8_t)EMSESP::system_.led_gpio_, data = {(int8_t)EMSESP::system_.led_gpio_,

View File

@@ -59,6 +59,7 @@ class System {
static bool command_watch(const char * value, const int8_t id); static bool command_watch(const char * value, const int8_t id);
static bool command_info(const char * value, const int8_t id, JsonObject & output); static bool command_info(const char * value, const int8_t id, JsonObject & output);
static bool command_commands(const char * value, const int8_t id, JsonObject & output); static bool command_commands(const char * value, const int8_t id, JsonObject & output);
static bool command_response(const char * value, const int8_t id, JsonObject & output);
#if defined(EMSESP_TEST) #if defined(EMSESP_TEST)
static bool command_test(const char * value, const int8_t id); static bool command_test(const char * value, const int8_t id);
#endif #endif

View File

@@ -512,11 +512,16 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
operation = Telegram::Operation::NONE; // do not check reply/ack for other ids operation = Telegram::Operation::NONE; // do not check reply/ack for other ids
} else if (dest & 0x80) { } else if (dest & 0x80) {
operation = Telegram::Operation::TX_READ; operation = Telegram::Operation::TX_READ;
EMSESP::set_response_id(type_id);
// trigger read of all parts of telegram if requested length is more than 32
// compatibility to earlier versions
if (message_data[0] >= 32) {
EMSESP::set_read_id(type_id);
}
} else { } else {
operation = Telegram::Operation::TX_WRITE; operation = Telegram::Operation::TX_WRITE;
validate_id = type_id; validate_id = type_id;
} }
EMSESP::set_read_id(type_id);
} }
auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length); // operation is TX_WRITE or TX_READ auto telegram = std::make_shared<Telegram>(operation, src, dest, type_id, offset, message_data, message_length); // operation is TX_WRITE or TX_READ
@@ -546,16 +551,14 @@ void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t lengt
} }
// send a Tx telegram to request data from an EMS device // send a Tx telegram to request data from an EMS device
void TxService::read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length) { void TxService::read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length, const bool front) {
LOG_DEBUG("Tx read request to device 0x%02X for type ID 0x%02X", dest, type_id); LOG_DEBUG("Tx read request to device 0x%02X for type ID 0x%02X", dest, type_id);
uint8_t message_data = (type_id > 0xFF) ? (EMS_MAX_TELEGRAM_MESSAGE_LENGTH - 2) : EMS_MAX_TELEGRAM_MESSAGE_LENGTH; uint8_t message_data = (type_id > 0xFF) ? (EMS_MAX_TELEGRAM_MESSAGE_LENGTH - 2) : EMS_MAX_TELEGRAM_MESSAGE_LENGTH;
// if length set, publish result and set telegram to front if (length > 0 && length < message_data) {
if (length) {
message_data = length; message_data = length;
EMSESP::set_read_id(type_id);
} }
add(Telegram::Operation::TX_READ, dest, type_id, offset, &message_data, 1, 0, length != 0); add(Telegram::Operation::TX_READ, dest, type_id, offset, &message_data, 1, 0, front);
} }
// Send a raw telegram to the bus, telegram is a text string of hex values // Send a raw telegram to the bus, telegram is a text string of hex values
@@ -566,32 +569,16 @@ bool TxService::send_raw(const char * telegram_data) {
// since the telegram data is a const, make a copy. add 1 to grab the \0 EOS // since the telegram data is a const, make a copy. add 1 to grab the \0 EOS
char telegram[EMS_MAX_TELEGRAM_LENGTH * 3]; char telegram[EMS_MAX_TELEGRAM_LENGTH * 3];
for (uint8_t i = 0; i < strlen(telegram_data); i++) { strlcpy(telegram, telegram_data, sizeof(telegram));
telegram[i] = telegram_data[i];
}
telegram[strlen(telegram_data)] = '\0'; // make sure its terminated
uint8_t count = 0; uint8_t count = 0;
char * p;
char value[10] = {0};
uint8_t data[EMS_MAX_TELEGRAM_LENGTH]; uint8_t data[EMS_MAX_TELEGRAM_LENGTH];
// get first value, which should be the src // get values
if ((p = strtok(telegram, " ,"))) { // delimiter char * p = strtok(telegram, " ,"); // delimiter
strlcpy(value, p, sizeof(value)); while (p != nullptr) {
data[0] = (uint8_t)strtol(value, 0, 16); data[count++] = (uint8_t)strtol(p, 0, 16);
} else { p = strtok(nullptr, " ,");
return false;
}
// and iterate until end
while (p != 0) {
if ((p = strtok(nullptr, " ,"))) {
strlcpy(value, p, sizeof(value));
auto val = (uint8_t)strtol(value, 0, 16);
data[++count] = val;
}
} }
// check valid length // check valid length
@@ -599,7 +586,7 @@ bool TxService::send_raw(const char * telegram_data) {
return false; return false;
} }
add(Telegram::Operation::TX_RAW, data, count + 1, 0, true); // add to top/front of Tx queue add(Telegram::Operation::TX_RAW, data, count, 0, true); // add to top/front of Tx queue
return true; return true;
} }

View File

@@ -317,7 +317,7 @@ class TxService : public EMSbus {
const uint16_t validateid, const uint16_t validateid,
const bool front = false); const bool front = false);
void add(const uint8_t operation, const uint8_t * data, const uint8_t length, const uint16_t validateid, const bool front = false); void add(const uint8_t operation, const uint8_t * data, const uint8_t length, const uint16_t validateid, const bool front = false);
void read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0, const uint8_t length = 0); void read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0, const uint8_t length = 0, const bool readId = false);
bool send_raw(const char * telegram_data); bool send_raw(const char * telegram_data);
void send_poll() const; void send_poll() const;
void retry_tx(const uint8_t operation, const uint8_t * data, const uint8_t length); void retry_tx(const uint8_t operation, const uint8_t * data, const uint8_t length);

View File

@@ -555,9 +555,7 @@ void TemperatureSensor::publish_values(const bool force) {
snprintf(topic, sizeof(topic), "sensor/%s/temperaturesensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str()); snprintf(topic, sizeof(topic), "sensor/%s/temperaturesensor_%s/config", Mqtt::basename().c_str(), sensorid.c_str());
Mqtt::queue_ha(topic, config.as<JsonObject>()); sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
sensor.ha_registered = true;
} }
} }
} }

View File

@@ -90,7 +90,6 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) {
entityItem.factor = 1; entityItem.factor = 1;
} }
webEntity.entityItems.push_back(entityItem); // add to list webEntity.entityItems.push_back(entityItem); // add to list
if (entityItem.writeable) { if (entityItem.writeable) {
Command::add( Command::add(
EMSdevice::DeviceType::CUSTOM, EMSdevice::DeviceType::CUSTOM,
@@ -111,7 +110,21 @@ bool WebEntityService::command_setvalue(const char * value, const std::string na
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
for (EntityItem & entityItem : *entityItems) { for (EntityItem & entityItem : *entityItems) {
if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) { if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) {
if (entityItem.value_type == DeviceValueType::BOOL) { if (entityItem.value_type == DeviceValueType::STRING) {
char telegram[84];
strlcpy(telegram, value, sizeof(telegram));
uint8_t data[EMS_MAX_TELEGRAM_LENGTH];
uint8_t count = 0;
char * p = strtok(telegram, " ,"); // delimiter
while (p != nullptr) {
data[count++] = (uint8_t)strtol(p, 0, 16);
p = strtok(nullptr, " ,");
}
if (count == 0) {
return false;
}
EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, data, count, 0);
} else if (entityItem.value_type == DeviceValueType::BOOL) {
bool v; bool v;
if (!Helpers::value2bool(value, v)) { if (!Helpers::value2bool(value, v)) {
return false; return false;
@@ -188,6 +201,11 @@ void WebEntityService::render_value(JsonObject & output, EntityItem entity, cons
output[name] = serialized(Helpers::render_value(payload, entity.factor * entity.value, 2)); output[name] = serialized(Helpers::render_value(payload, entity.factor * entity.value, 2));
} }
break; break;
case DeviceValueType::STRING:
if (entity.data.length() > 0) {
output[name] = entity.data;
}
break;
default: default:
// EMSESP::logger().warning("unknown value type"); // EMSESP::logger().warning("unknown value type");
break; break;
@@ -226,12 +244,22 @@ bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) {
} }
for (const auto & entity : *entityItems) { for (const auto & entity : *entityItems) {
if (Helpers::toLower(entity.name) == Helpers::toLower(command_s)) { if (Helpers::toLower(entity.name) == Helpers::toLower(command_s)) {
output["name"] = entity.name; output["name"] = entity.name;
output["uom"] = EMSdevice::uom_to_string(entity.uom); if (entity.uom > 0) {
output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : F_(number); output["uom"] = EMSdevice::uom_to_string(entity.uom);
}
output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : entity.value_type == DeviceValueType::STRING ? "string" : F_(number);
output["readable"] = true; output["readable"] = true;
output["writeable"] = entity.writeable; output["writeable"] = entity.writeable;
output["visible"] = true; output["visible"] = true;
output["device_id"] = Helpers::hextoa(entity.device_id);
output["type_id"] = Helpers::hextoa(entity.type_id);
output["offset"] = entity.offset;
if (entity.value_type != DeviceValueType::BOOL && entity.value_type != DeviceValueType::STRING) {
output["factor"] = entity.factor;
} else if (entity.value_type == DeviceValueType::STRING) {
output["bytes"] = (uint8_t)entity.factor;
}
render_value(output, entity, true); render_value(output, entity, true);
if (attribute_s) { if (attribute_s) {
if (output.containsKey(attribute_s)) { if (output.containsKey(attribute_s)) {
@@ -317,6 +345,8 @@ void WebEntityService::publish(const bool force) {
if (entityItem.writeable) { if (entityItem.writeable) {
if (entityItem.value_type == DeviceValueType::BOOL) { if (entityItem.value_type == DeviceValueType::BOOL) {
snprintf(topic, sizeof(topic), "switch/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); snprintf(topic, sizeof(topic), "switch/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str());
} else if (entityItem.value_type == DeviceValueType::STRING) {
snprintf(topic, sizeof(topic), "sensor/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str());
} else if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT) { } else if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT) {
snprintf(topic, sizeof(topic), "number/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); snprintf(topic, sizeof(topic), "number/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str());
} else { } else {
@@ -402,7 +432,7 @@ void WebEntityService::generate_value_web(JsonObject & output) {
obj["u"] = entity.uom; obj["u"] = entity.uom;
if (entity.writeable) { if (entity.writeable) {
obj["c"] = entity.name; obj["c"] = entity.name;
if (entity.value_type != DeviceValueType::BOOL) { if (entity.value_type != DeviceValueType::BOOL && entity.value_type != DeviceValueType::STRING) {
char s[10]; char s[10];
obj["s"] = Helpers::render_value(s, entity.factor, 1); obj["s"] = Helpers::render_value(s, entity.factor, 1);
} }
@@ -443,9 +473,15 @@ void WebEntityService::generate_value_web(JsonObject & output) {
obj["v"] = Helpers::transformNumFloat(entity.factor * entity.value, 0); obj["v"] = Helpers::transformNumFloat(entity.factor * entity.value, 0);
} }
break; break;
case DeviceValueType::STRING:
if (entity.data.length() > 0) {
obj["v"] = entity.data;
}
break;
default: default:
break; break;
} }
// show only entities with value or command
if (!obj.containsKey("v") && !obj.containsKey("c")) { if (!obj.containsKey("v") && !obj.containsKey("c")) {
data.remove(index); data.remove(index);
} else { } else {
@@ -457,8 +493,12 @@ void WebEntityService::generate_value_web(JsonObject & output) {
// fetch telegram, called from emsesp::fetch // fetch telegram, called from emsesp::fetch
void WebEntityService::fetch() { void WebEntityService::fetch() {
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
for (auto & entity : *entityItems) { for (auto & entity : *entityItems) {
EMSESP::send_read_request(entity.type_id, entity.device_id, entity.offset); EMSESP::send_read_request(entity.type_id,
entity.device_id,
entity.offset,
entity.value_type == DeviceValueType::STRING ? (uint8_t)entity.factor : len[entity.value_type]);
} }
// EMSESP::logger().debug("fetch custom entities"); // EMSESP::logger().debug("fetch custom entities");
} }
@@ -470,8 +510,20 @@ bool WebEntityService::get_value(std::shared_ptr<const Telegram> telegram) {
// read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME // read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
for (auto & entity : *entityItems) { for (auto & entity : *entityItems) {
if (telegram->type_id == entity.type_id && telegram->src == entity.device_id && telegram->offset <= entity.offset if (entity.value_type == DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id
&& (telegram->offset + telegram->message_length) >= (entity.offset + len[entity.value_type])) { && telegram->offset == entity.offset) {
auto data = Helpers::data_to_hex(telegram->message_data, telegram->message_length);
if (entity.data != data) {
entity.data = data;
if (Mqtt::publish_single()) {
publish_single(entity);
} else if (EMSESP::mqtt_.get_publish_onchange(0)) {
has_change = true;
}
}
}
if (entity.value_type != DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id
&& telegram->offset <= entity.offset && (telegram->offset + telegram->message_length) >= (entity.offset + len[entity.value_type])) {
uint32_t value = 0; uint32_t value = 0;
for (uint8_t i = 0; i < len[entity.value_type]; i++) { for (uint8_t i = 0; i < len[entity.value_type]; i++) {
value = (value << 8) + telegram->message_data[i + entity.offset - telegram->offset]; value = (value << 8) + telegram->message_data[i + entity.offset - telegram->offset];
@@ -485,7 +537,6 @@ bool WebEntityService::get_value(std::shared_ptr<const Telegram> telegram) {
} }
} }
// EMSESP::logger().debug("custom entity %s received with value %d", entity.name.c_str(), (int)entity.val); // EMSESP::logger().debug("custom entity %s received with value %d", entity.name.c_str(), (int)entity.val);
break;
} }
} }
if (has_change) { if (has_change) {

View File

@@ -37,6 +37,7 @@ class EntityItem {
double factor; double factor;
bool writeable; bool writeable;
uint32_t value; uint32_t value;
std::string data;
}; };
class WebEntity { class WebEntity {

View File

@@ -172,18 +172,25 @@ bool WebSchedulerService::get_value_info(JsonObject & output, const char * cmd)
JsonVariant data; JsonVariant data;
for (const ScheduleItem & scheduleItem : *scheduleItems) { for (const ScheduleItem & scheduleItem : *scheduleItems) {
if (Helpers::toLower(scheduleItem.name) == Helpers::toLower(command_s)) { if (Helpers::toLower(scheduleItem.name) == Helpers::toLower(command_s)) {
output["name"] = scheduleItem.name;
output["type"] = "boolean";
if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) { if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) {
output[scheduleItem.name] = scheduleItem.active; output["value"] = scheduleItem.active;
} else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) { } else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) {
output[scheduleItem.name] = scheduleItem.active ? 1 : 0; output["value"] = scheduleItem.active ? 1 : 0;
} else { } else {
char result[12]; char result[12];
output[scheduleItem.name] = Helpers::render_boolean(result, scheduleItem.active); output["value"] = Helpers::render_boolean(result, scheduleItem.active);
} }
data = output[scheduleItem.name]; output["command"] = scheduleItem.cmd;
output["cmd_data"] = scheduleItem.value;
output["readable"] = true;
output["writeable"] = true;
output["visible"] = true;
} }
} }
if (attribute_s && !strcmp(attribute_s, "value")) { if (attribute_s && output.containsKey(attribute_s)) {
data = output[attribute_s];
output.clear(); output.clear();
output["api_data"] = data; output["api_data"] = data;
} }
@@ -316,7 +323,7 @@ bool WebSchedulerService::command(const char * cmd, const char * data) {
if (return_code == CommandRet::OK) { if (return_code == CommandRet::OK) {
EMSESP::logger().debug("Scheduled command %s with data %s successfully", cmd, data); EMSESP::logger().debug("Scheduled command %s with data %s successfully", cmd, data);
if (strlen(data) == 0 && Mqtt::enabled() && Mqtt::send_response() && output.size()) { if (strlen(data) == 0 && output.size()) {
Mqtt::queue_publish("response", output); Mqtt::queue_publish("response", output);
} }
return true; return true;

View File

@@ -91,7 +91,8 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
#elif CONFIG_IDF_TARGET_ESP32S2 #elif CONFIG_IDF_TARGET_ESP32S2
settings.board_profile = root["board_profile"] | "S2MINI"; settings.board_profile = root["board_profile"] | "S2MINI";
#elif CONFIG_IDF_TARGET_ESP32S3 #elif CONFIG_IDF_TARGET_ESP32S3
settings.board_profile = root["board_profile"] | "S3MINI"; // settings.board_profile = root["board_profile"] | "S3MINI";
settings.board_profile = root["board_profile"] | "S32S3"; // BBQKees Gateway S3
#elif CONFIG_IDF_TARGET_ESP32 #elif CONFIG_IDF_TARGET_ESP32
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE; settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
#endif #endif