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)
- 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)
- 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
@@ -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)
- 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)
- Allowed gpios for S3
## 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)
- 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)
- 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
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, , 0x2000,
app1, app, ota_1, , 0x140000,
app0, app, ota_0, , 0x2A0000,
app1, app, ota_1, , 0x140000,
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",
"baseLocale": "pl",
"$schema": "https://unpkg.com/typesafe-i18n@5.24.4/schema/typesafe-i18n.json"
}
"adapter": "react",
"baseLocale": "pl",
"$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",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.0",
"@mui/material": "^5.14.0",
"@mui/icons-material": "^5.14.1",
"@mui/material": "^5.14.1",
"@preact/compat": "^17.1.2",
"@table-library/react-table-library": "4.1.4",
"@types/lodash-es": "^4.17.8",
@@ -31,7 +31,7 @@
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/react-router-dom": "^5.3.3",
"alova": "^2.9.2",
"alova": "^2.9.3",
"async-validator": "^4.2.5",
"history": "^5.3.0",
"jwt-decode": "^3.1.2",
@@ -42,17 +42,17 @@
"react-dom": "latest",
"react-dropzone": "^14.2.3",
"react-icons": "^4.10.1",
"react-router-dom": "^6.14.1",
"react-router-dom": "^6.14.2",
"react-toastify": "^9.1.3",
"sockette": "^2.0.6",
"typesafe-i18n": "^5.24.4",
"typesafe-i18n": "^5.25.1",
"typescript": "^5.1.6"
},
"devDependencies": {
"@preact/preset-vite": "^2.5.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"cspell": "^6.31.1",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.1.0",
"cspell": "^6.31.2",
"eslint": "^8.45.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.1.0",
@@ -62,14 +62,14 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "alpha",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react": "^7.33.0",
"eslint-plugin-react-hooks": "^4.6.0",
"nodemon": "^3.0.1",
"npm-run-all": "^4.1.5",
"prettier": "^3.0.0",
"rollup-plugin-visualizer": "^5.9.2",
"terser": "^5.19.0",
"vite": "^4.4.4",
"terser": "^5.19.1",
"vite": "^4.4.6",
"vite-plugin-svgr": "^3.2.0",
"vite-tsconfig-paths": "^4.2.0"
},

View File

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

View File

@@ -17,7 +17,7 @@ import {
} from '@mui/material';
import { useEffect, useState } from 'react';
import { DeviceValueUOM_s } from './types';
import { DeviceValueUOM_s, DeviceValueType } from './types';
import type { EntityItem } from './types';
import type Schema from 'async-validator';
import type { ValidateFieldsError } from 'async-validator';
@@ -166,17 +166,18 @@ const SettingsEntitiesDialog = ({
fullWidth
select
>
<MenuItem value={0}>BOOL</MenuItem>
<MenuItem value={1}>INT</MenuItem>
<MenuItem value={2}>UINT</MenuItem>
<MenuItem value={3}>SHORT</MenuItem>
<MenuItem value={4}>USHORT</MenuItem>
<MenuItem value={5}>ULONG</MenuItem>
<MenuItem value={6}>TIME</MenuItem>
<MenuItem value={DeviceValueType.BOOL}>BOOL</MenuItem>
<MenuItem value={DeviceValueType.INT}>INT</MenuItem>
<MenuItem value={DeviceValueType.UINT}>UINT</MenuItem>
<MenuItem value={DeviceValueType.SHORT}>SHORT</MenuItem>
<MenuItem value={DeviceValueType.USHORT}>USHORT</MenuItem>
<MenuItem value={DeviceValueType.ULONG}>ULONG</MenuItem>
<MenuItem value={DeviceValueType.TIME}>TIME</MenuItem>
<MenuItem value={DeviceValueType.STRING}>RAW</MenuItem>
</TextField>
</Grid>
{editItem.value_type !== 0 && (
{editItem.value_type !== DeviceValueType.BOOL && editItem.value_type !== DeviceValueType.STRING && (
<>
<Grid item xs={4}>
<TextField
@@ -210,6 +211,21 @@ const SettingsEntitiesDialog = ({
</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>
</DialogContent>

View File

@@ -243,7 +243,8 @@ export const BOARD_PROFILES: BoardProfiles = {
OLIMEXPOE: 'Olimex ESP32-POE',
C3MINI: 'Wemos C3 Mini',
S2MINI: 'Wemos S2 Mini',
S3MINI: 'Liligo S3'
S3MINI: 'Liligo S3',
S32S3: 'BBQKees Gateway S3'
};
export interface BoardProfile {
@@ -364,3 +365,17 @@ export const enum DeviceType {
CUSTOM,
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 (
value &&
(value === 1 ||
(value >= 10 && value <= 12) ||
(value >= 6 && value <= 12) ||
(value >= 14 && value <= 15) ||
value === 20 ||
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) =>
new Schema({
...(settings.board_profile === 'CUSTOM' &&
@@ -69,6 +86,14 @@ export const createSettingsValidator = (settings: Settings) =>
tx_gpio: [{ required: true, message: 'Tx 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 && {
syslog_host: [{ required: true, message: 'Host is required' }, IP_OR_HOSTNAME_VALIDATOR],
syslog_port: [

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
#include <UploadFileService.h>
#include <esp_ota_ops.h>
using namespace std::placeholders; // for `_1` etc
@@ -70,7 +71,7 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri
}
#endif
// it's firmware - initialize the ArduinoOTA updater
if (Update.begin()) {
if (Update.begin(fsize - sizeof(esp_image_header_t))) {
if (strlen(md5) == 32) {
Update.setMD5(md5);
md5[0] = '\0';
@@ -88,7 +89,9 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri
if (!is_firmware) {
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 {
// 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();
} else if (sensor.type() == AnalogType::DIGITAL_IN) {
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 {
snprintf(topic, sizeof(topic), "sensor/%s/analogsensor_%02d/config", Mqtt::basename().c_str(), sensor.gpio());
config["stat_cla"] = "measurement";
@@ -575,9 +586,7 @@ void AnalogSensor::publish_values(const bool force) {
// add "availability" section
Mqtt::add_avty_to_doc(stat_t, config.as<JsonObject>(), val_cond);
Mqtt::queue_ha(topic, config.as<JsonObject>());
sensor.ha_registered = true;
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
}
}
}

View File

@@ -410,14 +410,16 @@ static void setup_commands(std::shared_ptr<Commands> & commands) {
if (arguments.size() == 4) {
uint16_t offset = Helpers::hextoint(arguments[2].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) {
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 {
// 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,

View File

@@ -1645,7 +1645,7 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
Helpers::translated_word(FL_(minutes)));
json[name] = time_s;
} 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;
bool EMSESP::read_next_ = false;
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()
uint32_t EMSESP::last_fetch_ = 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'
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];
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) {
if (telegram->message_length <= 4 && strlen(buffer) <= 11) {
uint32_t value = 0;
for (uint8_t i = 0; i < telegram->message_length; i++) {
value = (value << 8) + telegram->message_data[i];
}
doc["value"] = value;
}
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
@@ -847,12 +859,16 @@ void EMSESP::process_version(std::shared_ptr<const Telegram> telegram) {
// returns false if there are none found
bool EMSESP::process_telegram(std::shared_ptr<const Telegram> telegram) {
// if watching or reading...
if ((telegram->type_id == read_id_) && (telegram->dest == txservice_.ems_bus_id())) {
LOG_INFO("%s", pretty_telegram(telegram).c_str());
if (Mqtt::send_response()) {
if ((telegram->type_id == read_id_ || telegram->type_id == response_id_) && (telegram->dest == txservice_.ems_bus_id())) {
// show log for read and response
LOG_NOTICE("%s", pretty_telegram(telegram).c_str());
if (telegram->type_id == response_id_) {
if (!read_next_) {
response_id_ = 0;
}
publish_response(telegram);
}
// check if read is finished or gives more parts
if (!read_next_) {
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
void EMSESP::send_read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t length) {
txservice_.read_request(type_id, dest, offset, 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, front);
}
// sends write request
@@ -1313,7 +1329,8 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
tx_successful = true;
// 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;
}
}

View File

@@ -117,7 +117,7 @@ class EMSESP {
static bool process_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,
const uint8_t dest,
const uint8_t offset,
@@ -176,6 +176,10 @@ class EMSESP {
read_id_ = id;
}
static void set_response_id(uint16_t id) {
response_id_ = id;
}
static bool wait_validate() {
return (wait_validate_ != 0);
}
@@ -259,6 +263,7 @@ class EMSESP {
static uint16_t read_id_;
static bool read_next_;
static uint16_t publish_id_;
static uint16_t response_id_;
static bool tap_water_active_;
static uint8_t publish_all_idx_;
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(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(commands_response, "get response") // TODO translate
// tags
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;
char will_topic_[Mqtt::MQTT_TOPIC_MAX_SIZE]; // because MQTT library keeps only char pointer
std::string Mqtt::lasttopic_ = "";
std::string Mqtt::lastpayload_ = "";
std::string Mqtt::lasttopic_ = "";
std::string Mqtt::lastpayload_ = "";
std::string Mqtt::lastresponse_ = "";
// Home Assistant specific
// 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());
}
LOG_ERROR(error);
if (send_response_) {
Mqtt::queue_publish("response", error);
}
Mqtt::queue_publish("response", error);
} else {
// 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() {
if (connecting_) {
return; // prevent duplicated connections
@@ -587,6 +584,12 @@ void Mqtt::ha_status() {
// add sub or pub task to the queue.
// 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) {
if (topic == "response" && operation == Operation::PUBLISH) {
lastresponse_ = payload;
if (!send_response_) {
return true;
}
}
if (!mqtt_enabled_ || topic.empty()) {
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
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);
}
@@ -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) {
if (enabled() && payload.size()) {
if (payload.size()) {
std::string payload_text;
payload_text.reserve(measureJson(payload) + 1);
serializeJson(payload, payload_text); // convert json to string
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
bool Mqtt::queue_remove_topic(const char * topic) {
if (!enabled()) {
return false;
}
if (ha_enabled_) {
return queue_publish_message(Mqtt::discovery_prefix() + topic, "", true); // publish with retain to remove from broker
} else {

View File

@@ -201,12 +201,8 @@ class Mqtt {
ha_climate_reset_ = reset;
}
static bool send_response() {
return send_response_;
}
static void send_response(bool send_response) {
send_response_ = send_response;
static std::string get_response() {
return lastresponse_;
}
void set_qos(uint8_t mqtt_qos) const {
@@ -270,6 +266,7 @@ class Mqtt {
static std::string lasttopic_;
static std::string lastpayload_;
static std::string lastresponse_;
// settings, copied over
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
if ((Mqtt::ha_enabled()) && (!ha_configdone_ || force)) {
ha_configdone_ = true;
StaticJsonDocument<EMSESP_JSON_SIZE_LARGE> doc;
doc["name"] = "Shower Active";
@@ -189,7 +187,7 @@ void Shower::set_shower_state(bool state, bool force) {
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
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
}
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
bool System::command_fetch(const char * value, const int8_t id) {
std::string value_s;
@@ -753,6 +765,7 @@ void System::commands_init() {
// 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_(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(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
} else if (board_profile == "S3MINI") {
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") {
// send back current values
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_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_response(const char * value, const int8_t id, JsonObject & output);
#if defined(EMSESP_TEST)
static bool command_test(const char * value, const int8_t id);
#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
} else if (dest & 0x80) {
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 {
operation = Telegram::Operation::TX_WRITE;
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
@@ -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
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);
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) {
if (length > 0 && length < message_data) {
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
@@ -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
char telegram[EMS_MAX_TELEGRAM_LENGTH * 3];
for (uint8_t i = 0; i < strlen(telegram_data); i++) {
telegram[i] = telegram_data[i];
}
telegram[strlen(telegram_data)] = '\0'; // make sure its terminated
strlcpy(telegram, telegram_data, sizeof(telegram));
uint8_t count = 0;
char * p;
char value[10] = {0};
uint8_t data[EMS_MAX_TELEGRAM_LENGTH];
// get first value, which should be the src
if ((p = strtok(telegram, " ,"))) { // delimiter
strlcpy(value, p, sizeof(value));
data[0] = (uint8_t)strtol(value, 0, 16);
} else {
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;
}
// get values
char * p = strtok(telegram, " ,"); // delimiter
while (p != nullptr) {
data[count++] = (uint8_t)strtol(p, 0, 16);
p = strtok(nullptr, " ,");
}
// check valid length
@@ -599,7 +586,7 @@ bool TxService::send_raw(const char * telegram_data) {
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;
}

View File

@@ -317,7 +317,7 @@ class TxService : public EMSbus {
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);
void send_poll() const;
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());
Mqtt::queue_ha(topic, config.as<JsonObject>());
sensor.ha_registered = true;
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
}
}
}

View File

@@ -90,7 +90,6 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) {
entityItem.factor = 1;
}
webEntity.entityItems.push_back(entityItem); // add to list
if (entityItem.writeable) {
Command::add(
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; });
for (EntityItem & entityItem : *entityItems) {
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;
if (!Helpers::value2bool(value, v)) {
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));
}
break;
case DeviceValueType::STRING:
if (entity.data.length() > 0) {
output[name] = entity.data;
}
break;
default:
// EMSESP::logger().warning("unknown value type");
break;
@@ -226,12 +244,22 @@ bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) {
}
for (const auto & entity : *entityItems) {
if (Helpers::toLower(entity.name) == Helpers::toLower(command_s)) {
output["name"] = entity.name;
output["uom"] = EMSdevice::uom_to_string(entity.uom);
output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : F_(number);
output["name"] = entity.name;
if (entity.uom > 0) {
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["writeable"] = entity.writeable;
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);
if (attribute_s) {
if (output.containsKey(attribute_s)) {
@@ -317,6 +345,8 @@ void WebEntityService::publish(const bool force) {
if (entityItem.writeable) {
if (entityItem.value_type == DeviceValueType::BOOL) {
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) {
snprintf(topic, sizeof(topic), "number/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str());
} else {
@@ -402,7 +432,7 @@ void WebEntityService::generate_value_web(JsonObject & output) {
obj["u"] = entity.uom;
if (entity.writeable) {
obj["c"] = entity.name;
if (entity.value_type != DeviceValueType::BOOL) {
if (entity.value_type != DeviceValueType::BOOL && entity.value_type != DeviceValueType::STRING) {
char s[10];
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);
}
break;
case DeviceValueType::STRING:
if (entity.data.length() > 0) {
obj["v"] = entity.data;
}
break;
default:
break;
}
// show only entities with value or command
if (!obj.containsKey("v") && !obj.containsKey("c")) {
data.remove(index);
} else {
@@ -457,8 +493,12 @@ void WebEntityService::generate_value_web(JsonObject & output) {
// fetch telegram, called from emsesp::fetch
void WebEntityService::fetch() {
EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; });
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
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");
}
@@ -470,8 +510,20 @@ bool WebEntityService::get_value(std::shared_ptr<const Telegram> telegram) {
// read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME
const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3};
for (auto & entity : *entityItems) {
if (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])) {
if (entity.value_type == DeviceValueType::STRING && telegram->type_id == entity.type_id && telegram->src == entity.device_id
&& 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;
for (uint8_t i = 0; i < len[entity.value_type]; i++) {
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);
break;
}
}
if (has_change) {

View File

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

View File

@@ -172,18 +172,25 @@ bool WebSchedulerService::get_value_info(JsonObject & output, const char * cmd)
JsonVariant data;
for (const ScheduleItem & scheduleItem : *scheduleItems) {
if (Helpers::toLower(scheduleItem.name) == Helpers::toLower(command_s)) {
output["name"] = scheduleItem.name;
output["type"] = "boolean";
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) {
output[scheduleItem.name] = scheduleItem.active ? 1 : 0;
output["value"] = scheduleItem.active ? 1 : 0;
} else {
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["api_data"] = data;
}
@@ -316,7 +323,7 @@ bool WebSchedulerService::command(const char * cmd, const char * data) {
if (return_code == CommandRet::OK) {
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);
}
return true;

View File

@@ -91,7 +91,8 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
#elif CONFIG_IDF_TARGET_ESP32S2
settings.board_profile = root["board_profile"] | "S2MINI";
#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
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
#endif