mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
Change name of entity within WebUI #612
This commit is contained in:
28
interface/package-lock.json
generated
28
interface/package-lock.json
generated
@@ -15,7 +15,7 @@
|
|||||||
"@mui/material": "^5.10.4",
|
"@mui/material": "^5.10.4",
|
||||||
"@table-library/react-table-library": "4.0.18",
|
"@table-library/react-table-library": "4.0.18",
|
||||||
"@types/lodash": "^4.14.184",
|
"@types/lodash": "^4.14.184",
|
||||||
"@types/node": "^18.7.15",
|
"@types/node": "^18.7.16",
|
||||||
"@types/react": "^18.0.18",
|
"@types/react": "^18.0.18",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"sockette": "^2.0.6",
|
"sockette": "^2.0.6",
|
||||||
"typesafe-i18n": "^5.12.0",
|
"typesafe-i18n": "^5.12.0",
|
||||||
"typescript": "^4.8.2"
|
"typescript": "^4.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^2.0.19",
|
"nodemon": "^2.0.19",
|
||||||
@@ -4013,9 +4013,9 @@
|
|||||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "18.7.15",
|
"version": "18.7.16",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz",
|
||||||
"integrity": "sha512-XnjpaI8Bgc3eBag2Aw4t2Uj/49lLBSStHWfqKvIuXD7FIrZyMLWp8KuAFHAqxMZYTF9l08N1ctUn9YNybZJVmQ=="
|
"integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/parse-json": {
|
"node_modules/@types/parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
@@ -16418,9 +16418,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.8.2",
|
"version": "4.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz",
|
||||||
"integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==",
|
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -20201,9 +20201,9 @@
|
|||||||
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "18.7.15",
|
"version": "18.7.16",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.15.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz",
|
||||||
"integrity": "sha512-XnjpaI8Bgc3eBag2Aw4t2Uj/49lLBSStHWfqKvIuXD7FIrZyMLWp8KuAFHAqxMZYTF9l08N1ctUn9YNybZJVmQ=="
|
"integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg=="
|
||||||
},
|
},
|
||||||
"@types/parse-json": {
|
"@types/parse-json": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
@@ -29076,9 +29076,9 @@
|
|||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.8.2",
|
"version": "4.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz",
|
||||||
"integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw=="
|
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig=="
|
||||||
},
|
},
|
||||||
"unbox-primitive": {
|
"unbox-primitive": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"@mui/material": "^5.10.4",
|
"@mui/material": "^5.10.4",
|
||||||
"@table-library/react-table-library": "4.0.18",
|
"@table-library/react-table-library": "4.0.18",
|
||||||
"@types/lodash": "^4.14.184",
|
"@types/lodash": "^4.14.184",
|
||||||
"@types/node": "^18.7.15",
|
"@types/node": "^18.7.16",
|
||||||
"@types/react": "^18.0.18",
|
"@types/react": "^18.0.18",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"sockette": "^2.0.6",
|
"sockette": "^2.0.6",
|
||||||
"typesafe-i18n": "^5.12.0",
|
"typesafe-i18n": "^5.12.0",
|
||||||
"typescript": "^4.8.2"
|
"typescript": "^4.8.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-app-rewired start",
|
"start": "react-app-rewired start",
|
||||||
|
|||||||
@@ -45,15 +45,19 @@ const de: Translation = {
|
|||||||
PROBLEM_UPDATING: 'Problem beim Aktualisieren',
|
PROBLEM_UPDATING: 'Problem beim Aktualisieren',
|
||||||
PROBLEM_LOADING: 'Problem beim Laden',
|
PROBLEM_LOADING: 'Problem beim Laden',
|
||||||
ACCESS_DENIED: 'Zugriff abgelehnt',
|
ACCESS_DENIED: 'Zugriff abgelehnt',
|
||||||
ANALOG_SENSOR: 'Analogsensor{post}',
|
ANALOG_SENSOR: 'Analogsensor',
|
||||||
ANALOG_SENSORS: 'Analogsensoren',
|
ANALOG_SENSORS: 'Analogsensoren',
|
||||||
|
UPDATED: 'DE_Updated',
|
||||||
|
UPDATE: 'DE_Update',
|
||||||
|
REMOVED: 'DE_Removed',
|
||||||
|
DELETION: 'DE_Deletion',
|
||||||
OFFSET: 'Addition',
|
OFFSET: 'Addition',
|
||||||
FACTOR: 'Faktor',
|
FACTOR: 'Faktor',
|
||||||
FREQ: 'Frequenz',
|
FREQ: 'Frequenz',
|
||||||
STARTVALUE: 'Startwert',
|
STARTVALUE: 'Startwert',
|
||||||
WARN_GPIO: 'Warnung: Vorsicht bei der korrekten Wahl des GPIO!',
|
WARN_GPIO: 'Warnung: Vorsicht bei der korrekten Wahl des GPIO!',
|
||||||
EDIT: 'Editiere',
|
EDIT: 'Editiere',
|
||||||
TEMP_SENSOR: 'Temperatursensor{post}',
|
TEMP_SENSOR: 'Temperatursensor',
|
||||||
TEMP_SENSORS: 'Temperatursensoren',
|
TEMP_SENSORS: 'Temperatursensoren',
|
||||||
WRITE_COMMAND: 'Befehl schreiben {cmd}',
|
WRITE_COMMAND: 'Befehl schreiben {cmd}',
|
||||||
EMS_BUS_WARNING:
|
EMS_BUS_WARNING:
|
||||||
@@ -128,7 +132,7 @@ const de: Translation = {
|
|||||||
RESTART_TEXT: 'EMS-ESP muss neu gestartet werden, um geänderte Systemeinstellungen zu übernehmen',
|
RESTART_TEXT: 'EMS-ESP muss neu gestartet werden, um geänderte Systemeinstellungen zu übernehmen',
|
||||||
COMMAND: 'Befehl',
|
COMMAND: 'Befehl',
|
||||||
CUSTOMIZATIONS_RESTART: 'Alle Anpassungen wurden entfernt. Neustart...',
|
CUSTOMIZATIONS_RESTART: 'Alle Anpassungen wurden entfernt. Neustart...',
|
||||||
CUSTOMIZATIONS_FULL: 'Ausgewählte Entitäten haben das Limit von 60 überschritten. Bitte stapelweise speichern',
|
CUSTOMIZATIONS_FULL: 'Ausgewählte Entitäten haben das Limit überschritten. Bitte stapelweise speichern',
|
||||||
CUSTOMIZATIONS_SAVED: 'Anpassungen gespeichert',
|
CUSTOMIZATIONS_SAVED: 'Anpassungen gespeichert',
|
||||||
CUSTOMIZATIONS_HELP_1: 'Wählen Sie ein Gerät aus und passen Sie die Entitäten mithilfe der Optionen an',
|
CUSTOMIZATIONS_HELP_1: 'Wählen Sie ein Gerät aus und passen Sie die Entitäten mithilfe der Optionen an',
|
||||||
CUSTOMIZATIONS_HELP_2: 'als Favorit markieren',
|
CUSTOMIZATIONS_HELP_2: 'als Favorit markieren',
|
||||||
@@ -253,7 +257,9 @@ const de: Translation = {
|
|||||||
NETWORK_ENABLE_IPV6: 'Aktiviere IPv6 Unterstützung',
|
NETWORK_ENABLE_IPV6: 'Aktiviere IPv6 Unterstützung',
|
||||||
NETWORK_FIXED_IP: 'Feste IP Addresse',
|
NETWORK_FIXED_IP: 'Feste IP Addresse',
|
||||||
ADMIN: 'Administrator',
|
ADMIN: 'Administrator',
|
||||||
GUEST: 'Gast'
|
GUEST: 'Gast',
|
||||||
|
NEW: 'Neu',
|
||||||
|
RENAME: 'DE_Rename'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default de;
|
export default de;
|
||||||
|
|||||||
@@ -45,15 +45,19 @@ const en: BaseTranslation = {
|
|||||||
PROBLEM_UPDATING: 'Problem updating',
|
PROBLEM_UPDATING: 'Problem updating',
|
||||||
PROBLEM_LOADING: 'Problem loading',
|
PROBLEM_LOADING: 'Problem loading',
|
||||||
ACCESS_DENIED: 'Access Denied',
|
ACCESS_DENIED: 'Access Denied',
|
||||||
ANALOG_SENSOR: 'Analog Sensor{post}',
|
ANALOG_SENSOR: 'Analog Sensor',
|
||||||
ANALOG_SENSORS: 'Analog Sensors',
|
ANALOG_SENSORS: 'Analog Sensors',
|
||||||
|
UPDATED: 'Updated',
|
||||||
|
UPDATE: 'Update',
|
||||||
|
REMOVED: 'Removed',
|
||||||
|
DELETION: 'Deletion',
|
||||||
OFFSET: 'Offset',
|
OFFSET: 'Offset',
|
||||||
FACTOR: 'Factor',
|
FACTOR: 'Factor',
|
||||||
FREQ: 'Frequency',
|
FREQ: 'Frequency',
|
||||||
STARTVALUE: 'Start value',
|
STARTVALUE: 'Start value',
|
||||||
WARN_GPIO: 'Warning: be careful when assigning a GPIO!',
|
WARN_GPIO: 'Warning: be careful when assigning a GPIO!',
|
||||||
EDIT: 'Edit',
|
EDIT: 'Edit',
|
||||||
TEMP_SENSOR: 'Temperature Sensor{post}',
|
TEMP_SENSOR: 'Temperature Sensor',
|
||||||
TEMP_SENSORS: 'Temperature Sensors',
|
TEMP_SENSORS: 'Temperature Sensors',
|
||||||
WRITE_COMMAND: 'Write command {cmd}',
|
WRITE_COMMAND: 'Write command {cmd}',
|
||||||
EMS_BUS_WARNING:
|
EMS_BUS_WARNING:
|
||||||
@@ -128,7 +132,7 @@ const en: BaseTranslation = {
|
|||||||
RESTART_TEXT: 'EMS-ESP needs to be restarted to apply changed system settings',
|
RESTART_TEXT: 'EMS-ESP needs to be restarted to apply changed system settings',
|
||||||
COMMAND: 'Command',
|
COMMAND: 'Command',
|
||||||
CUSTOMIZATIONS_RESTART: 'All customizations have been removed. Restarting...',
|
CUSTOMIZATIONS_RESTART: 'All customizations have been removed. Restarting...',
|
||||||
CUSTOMIZATIONS_FULL: 'Selected entities exceeded limit of 60. Please Save in batches',
|
CUSTOMIZATIONS_FULL: 'Selected entities exceeded limit. Please save in batches',
|
||||||
CUSTOMIZATIONS_SAVED: 'Customizations saved',
|
CUSTOMIZATIONS_SAVED: 'Customizations saved',
|
||||||
CUSTOMIZATIONS_HELP_1: 'Select a device and customize the entities using the options',
|
CUSTOMIZATIONS_HELP_1: 'Select a device and customize the entities using the options',
|
||||||
CUSTOMIZATIONS_HELP_2: 'mark as favorite',
|
CUSTOMIZATIONS_HELP_2: 'mark as favorite',
|
||||||
@@ -254,7 +258,8 @@ const en: BaseTranslation = {
|
|||||||
NETWORK_FIXED_IP: 'Use Fixed IP address',
|
NETWORK_FIXED_IP: 'Use Fixed IP address',
|
||||||
ADMIN: 'Admin',
|
ADMIN: 'Admin',
|
||||||
GUEST: 'Guest',
|
GUEST: 'Guest',
|
||||||
NEW: 'New'
|
NEW: 'New',
|
||||||
|
RENAME: 'Rename'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default en;
|
export default en;
|
||||||
|
|||||||
@@ -193,14 +193,29 @@ type RootTranslation = {
|
|||||||
*/
|
*/
|
||||||
ACCESS_DENIED: string
|
ACCESS_DENIED: string
|
||||||
/**
|
/**
|
||||||
* Analog Sensor{post}
|
* Analog Sensor
|
||||||
* @param {unknown} post
|
|
||||||
*/
|
*/
|
||||||
ANALOG_SENSOR: RequiredParams<'post'>
|
ANALOG_SENSOR: string
|
||||||
/**
|
/**
|
||||||
* Analog Sensors
|
* Analog Sensors
|
||||||
*/
|
*/
|
||||||
ANALOG_SENSORS: string
|
ANALOG_SENSORS: string
|
||||||
|
/**
|
||||||
|
* Updated
|
||||||
|
*/
|
||||||
|
UPDATED: string
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
*/
|
||||||
|
UPDATE: string
|
||||||
|
/**
|
||||||
|
* Removed
|
||||||
|
*/
|
||||||
|
REMOVED: string
|
||||||
|
/**
|
||||||
|
* Deletion
|
||||||
|
*/
|
||||||
|
DELETION: string
|
||||||
/**
|
/**
|
||||||
* Offset
|
* Offset
|
||||||
*/
|
*/
|
||||||
@@ -226,10 +241,9 @@ type RootTranslation = {
|
|||||||
*/
|
*/
|
||||||
EDIT: string
|
EDIT: string
|
||||||
/**
|
/**
|
||||||
* Temperature Sensor{post}
|
* Temperature Sensor
|
||||||
* @param {unknown} post
|
|
||||||
*/
|
*/
|
||||||
TEMP_SENSOR: RequiredParams<'post'>
|
TEMP_SENSOR: string
|
||||||
/**
|
/**
|
||||||
* Temperature Sensors
|
* Temperature Sensors
|
||||||
*/
|
*/
|
||||||
@@ -521,7 +535,7 @@ type RootTranslation = {
|
|||||||
*/
|
*/
|
||||||
CUSTOMIZATIONS_RESTART: string
|
CUSTOMIZATIONS_RESTART: string
|
||||||
/**
|
/**
|
||||||
* Selected entities exceeded limit of 60. Please Save in batches
|
* Selected entities exceeded limit. Please save in batches
|
||||||
*/
|
*/
|
||||||
CUSTOMIZATIONS_FULL: string
|
CUSTOMIZATIONS_FULL: string
|
||||||
/**
|
/**
|
||||||
@@ -1008,6 +1022,10 @@ type RootTranslation = {
|
|||||||
* New
|
* New
|
||||||
*/
|
*/
|
||||||
NEW: string
|
NEW: string
|
||||||
|
/**
|
||||||
|
* Rename
|
||||||
|
*/
|
||||||
|
RENAME: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TranslationFunctions = {
|
export type TranslationFunctions = {
|
||||||
@@ -1188,13 +1206,29 @@ export type TranslationFunctions = {
|
|||||||
*/
|
*/
|
||||||
ACCESS_DENIED: () => LocalizedString
|
ACCESS_DENIED: () => LocalizedString
|
||||||
/**
|
/**
|
||||||
* Analog Sensor{post}
|
* Analog Sensor
|
||||||
*/
|
*/
|
||||||
ANALOG_SENSOR: (arg: { post: unknown }) => LocalizedString
|
ANALOG_SENSOR: () => LocalizedString
|
||||||
/**
|
/**
|
||||||
* Analog Sensors
|
* Analog Sensors
|
||||||
*/
|
*/
|
||||||
ANALOG_SENSORS: () => LocalizedString
|
ANALOG_SENSORS: () => LocalizedString
|
||||||
|
/**
|
||||||
|
* Updated
|
||||||
|
*/
|
||||||
|
UPDATED: () => LocalizedString
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
*/
|
||||||
|
UPDATE: () => LocalizedString
|
||||||
|
/**
|
||||||
|
* Removed
|
||||||
|
*/
|
||||||
|
REMOVED: () => LocalizedString
|
||||||
|
/**
|
||||||
|
* Deletion
|
||||||
|
*/
|
||||||
|
DELETION: () => LocalizedString
|
||||||
/**
|
/**
|
||||||
* Offset
|
* Offset
|
||||||
*/
|
*/
|
||||||
@@ -1220,9 +1254,9 @@ export type TranslationFunctions = {
|
|||||||
*/
|
*/
|
||||||
EDIT: () => LocalizedString
|
EDIT: () => LocalizedString
|
||||||
/**
|
/**
|
||||||
* Temperature Sensor{post}
|
* Temperature Sensor
|
||||||
*/
|
*/
|
||||||
TEMP_SENSOR: (arg: { post: unknown }) => LocalizedString
|
TEMP_SENSOR: () => LocalizedString
|
||||||
/**
|
/**
|
||||||
* Temperature Sensors
|
* Temperature Sensors
|
||||||
*/
|
*/
|
||||||
@@ -1506,7 +1540,7 @@ export type TranslationFunctions = {
|
|||||||
*/
|
*/
|
||||||
CUSTOMIZATIONS_RESTART: () => LocalizedString
|
CUSTOMIZATIONS_RESTART: () => LocalizedString
|
||||||
/**
|
/**
|
||||||
* Selected entities exceeded limit of 60. Please Save in batches
|
* Selected entities exceeded limit. Please save in batches
|
||||||
*/
|
*/
|
||||||
CUSTOMIZATIONS_FULL: () => LocalizedString
|
CUSTOMIZATIONS_FULL: () => LocalizedString
|
||||||
/**
|
/**
|
||||||
@@ -1993,6 +2027,10 @@ export type TranslationFunctions = {
|
|||||||
* New
|
* New
|
||||||
*/
|
*/
|
||||||
NEW: () => LocalizedString
|
NEW: () => LocalizedString
|
||||||
|
/**
|
||||||
|
* Rename
|
||||||
|
*/
|
||||||
|
RENAME: () => LocalizedString
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Formatters = {}
|
export type Formatters = {}
|
||||||
|
|||||||
@@ -44,15 +44,19 @@ const nl: BaseTranslation = {
|
|||||||
PROBLEM_UPDATING: 'Probleem met updaten',
|
PROBLEM_UPDATING: 'Probleem met updaten',
|
||||||
PROBLEM_LOADING: 'Probleem met laden',
|
PROBLEM_LOADING: 'Probleem met laden',
|
||||||
ACCESS_DENIED: 'Toegang geweigerd',
|
ACCESS_DENIED: 'Toegang geweigerd',
|
||||||
ANALOG_SENSOR: 'Analoge sensor{post}',
|
ANALOG_SENSOR: 'Analoge sensor',
|
||||||
ANALOG_SENSORS: 'Analoge Sensoren',
|
ANALOG_SENSORS: 'Analoge Sensoren',
|
||||||
|
UPDATED: 'Bijgewerkt',
|
||||||
|
UPDATE: 'Bijwerken',
|
||||||
|
REMOVED: 'Verwijderd',
|
||||||
|
DELETION: 'Verwijder',
|
||||||
OFFSET: 'Offset',
|
OFFSET: 'Offset',
|
||||||
FACTOR: 'Factor',
|
FACTOR: 'Factor',
|
||||||
FREQ: 'Frequentie',
|
FREQ: 'Frequentie',
|
||||||
STARTVALUE: 'Startwaarde',
|
STARTVALUE: 'Startwaarde',
|
||||||
WARN_GPIO: 'Waarschuwing: let op met het koppelen van de juiste GPIO pin!',
|
WARN_GPIO: 'Waarschuwing: let op met het koppelen van de juiste GPIO pin!',
|
||||||
EDIT: 'Wijzigen',
|
EDIT: 'Wijzigen',
|
||||||
TEMP_SENSOR: 'Temperatuur sensor{post}',
|
TEMP_SENSOR: 'Temperatuur sensor',
|
||||||
TEMP_SENSORS: 'Temperatuur Sensoren',
|
TEMP_SENSORS: 'Temperatuur Sensoren',
|
||||||
WRITE_COMMAND: 'Schrijf commando {cmd}',
|
WRITE_COMMAND: 'Schrijf commando {cmd}',
|
||||||
EMS_BUS_WARNING:
|
EMS_BUS_WARNING:
|
||||||
@@ -127,7 +131,7 @@ const nl: BaseTranslation = {
|
|||||||
RESTART_TEXT: 'EMS-ESP dient opnieuw gestart te worden om de wijzingen toe te passen',
|
RESTART_TEXT: 'EMS-ESP dient opnieuw gestart te worden om de wijzingen toe te passen',
|
||||||
COMMAND: 'Commando',
|
COMMAND: 'Commando',
|
||||||
CUSTOMIZATIONS_RESTART: 'Alle custom profielen worden verwijderd. Herstarten...',
|
CUSTOMIZATIONS_RESTART: 'Alle custom profielen worden verwijderd. Herstarten...',
|
||||||
CUSTOMIZATIONS_FULL: 'Meer dan 60 entiteiten geselecteerd. Sla op in delen aub',
|
CUSTOMIZATIONS_FULL: 'Te veel entiteiten geselecteerd. Sla op in delen aub',
|
||||||
CUSTOMIZATIONS_SAVED: 'Custom aanpassingen opgeslagen',
|
CUSTOMIZATIONS_SAVED: 'Custom aanpassingen opgeslagen',
|
||||||
CUSTOMIZATIONS_HELP_1: 'Selecteer een apparaat en pas de entiteiten aan door middel van de opties',
|
CUSTOMIZATIONS_HELP_1: 'Selecteer een apparaat en pas de entiteiten aan door middel van de opties',
|
||||||
CUSTOMIZATIONS_HELP_2: 'Markeer as favoriet',
|
CUSTOMIZATIONS_HELP_2: 'Markeer as favoriet',
|
||||||
@@ -254,7 +258,8 @@ const nl: BaseTranslation = {
|
|||||||
NETWORK_FIXED_IP: 'Gebruik vast IP addres',
|
NETWORK_FIXED_IP: 'Gebruik vast IP addres',
|
||||||
ADMIN: 'Admin',
|
ADMIN: 'Admin',
|
||||||
GUEST: 'Gast',
|
GUEST: 'Gast',
|
||||||
NEW: 'Nieuwe'
|
NEW: 'Nieuwe',
|
||||||
|
RENAME: 'Hernoem'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nl;
|
export default nl;
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ const DashboardData: FC = () => {
|
|||||||
active_sensors: 0,
|
active_sensors: 0,
|
||||||
analog_enabled: false
|
analog_enabled: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const [deviceData, setDeviceData] = useState<DeviceData>({ label: '', data: [] });
|
const [deviceData, setDeviceData] = useState<DeviceData>({ label: '', data: [] });
|
||||||
const [sensorData, setSensorData] = useState<SensorData>({ sensors: [], analogs: [] });
|
const [sensorData, setSensorData] = useState<SensorData>({ sensors: [], analogs: [] });
|
||||||
const [deviceValue, setDeviceValue] = useState<DeviceValue>();
|
const [deviceValue, setDeviceValue] = useState<DeviceValue>();
|
||||||
@@ -558,11 +559,11 @@ const DashboardData: FC = () => {
|
|||||||
offset: sensor.o
|
offset: sensor.o
|
||||||
});
|
});
|
||||||
if (response.status === 204) {
|
if (response.status === 204) {
|
||||||
enqueueSnackbar(LL.TEMP_SENSOR({ post: ' change failed' }), { variant: 'error' });
|
enqueueSnackbar(LL.TEMP_SENSOR() + ' ' + LL.UPLOAD_TEXT() + ' ' + LL.FAILED(), { variant: 'error' });
|
||||||
} else if (response.status === 403) {
|
} else if (response.status === 403) {
|
||||||
enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
|
enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
|
||||||
} else {
|
} else {
|
||||||
enqueueSnackbar(LL.TEMP_SENSOR({ post: ' removed' }), { variant: 'success' });
|
enqueueSnackbar(LL.TEMP_SENSOR() + ' ' + LL.UPDATED(), { variant: 'success' });
|
||||||
}
|
}
|
||||||
setSensor(undefined);
|
setSensor(undefined);
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -578,7 +579,9 @@ const DashboardData: FC = () => {
|
|||||||
if (sensor) {
|
if (sensor) {
|
||||||
return (
|
return (
|
||||||
<Dialog open={sensor !== undefined} onClose={() => setSensor(undefined)}>
|
<Dialog open={sensor !== undefined} onClose={() => setSensor(undefined)}>
|
||||||
<DialogTitle>{LL.EDIT()} {LL.TEMP_SENSORS()}</DialogTitle>
|
<DialogTitle>
|
||||||
|
{LL.EDIT()} {LL.TEMP_SENSORS()}
|
||||||
|
</DialogTitle>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
||||||
<Typography variant="body2">Sensor ID {sensor.id}</Typography>
|
<Typography variant="body2">Sensor ID {sensor.id}</Typography>
|
||||||
@@ -983,11 +986,11 @@ const DashboardData: FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 204) {
|
if (response.status === 204) {
|
||||||
enqueueSnackbar(LL.ANALOG_SENSOR({ post: ' deletion failed' }), { variant: 'error' });
|
enqueueSnackbar(LL.ANALOG_SENSOR() + ' ' + LL.DELETION() + ' ' + LL.FAILED(), { variant: 'error' });
|
||||||
} else if (response.status === 403) {
|
} else if (response.status === 403) {
|
||||||
enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
|
enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
|
||||||
} else {
|
} else {
|
||||||
enqueueSnackbar(LL.ANALOG_SENSOR({ post: ' removed' }), { variant: 'success' });
|
enqueueSnackbar(LL.ANALOG_SENSOR() + ' ' + LL.REMOVED(), { variant: 'success' });
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
|
enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
|
||||||
@@ -1011,11 +1014,11 @@ const DashboardData: FC = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 204) {
|
if (response.status === 204) {
|
||||||
enqueueSnackbar(LL.ANALOG_SENSOR({ post: ' update failed' }), { variant: 'error' });
|
enqueueSnackbar(LL.ANALOG_SENSOR() + ' ' + LL.UPDATE() + ' ' + LL.FAILED(), { variant: 'error' });
|
||||||
} else if (response.status === 403) {
|
} else if (response.status === 403) {
|
||||||
enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
|
enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
|
||||||
} else {
|
} else {
|
||||||
enqueueSnackbar(LL.ANALOG_SENSOR({ post: ' updated' }), { variant: 'success' });
|
enqueueSnackbar(LL.ANALOG_SENSOR() + ' ' + LL.UPDATED(), { variant: 'success' });
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
|
enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
|
||||||
@@ -1030,7 +1033,9 @@ const DashboardData: FC = () => {
|
|||||||
if (analog) {
|
if (analog) {
|
||||||
return (
|
return (
|
||||||
<Dialog open={analog !== undefined} onClose={() => setAnalog(undefined)}>
|
<Dialog open={analog !== undefined} onClose={() => setAnalog(undefined)}>
|
||||||
<DialogTitle>{LL.EDIT()} {LL.ANALOG_SENSORS()}</DialogTitle>
|
<DialogTitle>
|
||||||
|
{LL.EDIT()} {LL.ANALOG_SENSORS()}
|
||||||
|
</DialogTitle>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
@@ -1055,7 +1060,13 @@ const DashboardData: FC = () => {
|
|||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<ValidatedTextField name="t" label={LL.TYPE()} value={analog.t} select onChange={updateValue(setAnalog)}>
|
<ValidatedTextField
|
||||||
|
name="t"
|
||||||
|
label={LL.TYPE()}
|
||||||
|
value={analog.t}
|
||||||
|
select
|
||||||
|
onChange={updateValue(setAnalog)}
|
||||||
|
>
|
||||||
{AnalogTypeNames.map((val, i) => (
|
{AnalogTypeNames.map((val, i) => (
|
||||||
<MenuItem key={i} value={i}>
|
<MenuItem key={i} value={i}>
|
||||||
{val}
|
{val}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import {
|
|||||||
|
|
||||||
import { Table } from '@table-library/react-table-library/table';
|
import { Table } from '@table-library/react-table-library/table';
|
||||||
import { useTheme } from '@table-library/react-table-library/theme';
|
import { useTheme } from '@table-library/react-table-library/theme';
|
||||||
import { useSort, SortToggleType } from '@table-library/react-table-library/sort';
|
|
||||||
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
|
|
||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
@@ -28,9 +27,6 @@ import SaveIcon from '@mui/icons-material/Save';
|
|||||||
import CancelIcon from '@mui/icons-material/Cancel';
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
|
|
||||||
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
|
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
|
||||||
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
|
|
||||||
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
|
|
||||||
import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
|
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
import FilterListIcon from '@mui/icons-material/FilterList';
|
import FilterListIcon from '@mui/icons-material/FilterList';
|
||||||
|
|
||||||
@@ -53,17 +49,18 @@ const SettingsCustomization: FC = () => {
|
|||||||
|
|
||||||
const { enqueueSnackbar } = useSnackbar();
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
|
||||||
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([{ id: '', v: 0, n: '', m: 0, w: false }]);
|
const emptyDeviceEntity = { id: '', v: 0, n: '', cn: '', m: 0, w: false };
|
||||||
|
|
||||||
|
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([emptyDeviceEntity]);
|
||||||
const [devices, setDevices] = useState<Devices>();
|
const [devices, setDevices] = useState<Devices>();
|
||||||
const [errorMessage, setErrorMessage] = useState<string>();
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
const [selectedDevice, setSelectedDevice] = useState<number>(-1);
|
const [selectedDevice, setSelectedDevice] = useState<number>(-1);
|
||||||
|
|
||||||
const [selectedEntity, setSelectedEntity] = useState<DeviceEntity>();
|
|
||||||
|
|
||||||
const [confirmReset, setConfirmReset] = useState<boolean>(false);
|
const [confirmReset, setConfirmReset] = useState<boolean>(false);
|
||||||
const [selectedFilters, setSelectedFilters] = useState<number>(0);
|
const [selectedFilters, setSelectedFilters] = useState<number>(0);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
|
|
||||||
|
const [deviceEntity, setDeviceEntity] = useState<DeviceEntity>();
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const [masks, setMasks] = useState(() => ['']);
|
const [masks, setMasks] = useState(() => ['']);
|
||||||
|
|
||||||
@@ -131,32 +128,6 @@ const SettingsCustomization: FC = () => {
|
|||||||
`
|
`
|
||||||
});
|
});
|
||||||
|
|
||||||
const getSortIcon = (state: any, sortKey: any) => {
|
|
||||||
if (state.sortKey === sortKey && state.reverse) {
|
|
||||||
return <KeyboardArrowDownOutlinedIcon />;
|
|
||||||
}
|
|
||||||
if (state.sortKey === sortKey && !state.reverse) {
|
|
||||||
return <KeyboardArrowUpOutlinedIcon />;
|
|
||||||
}
|
|
||||||
return <UnfoldMoreOutlinedIcon />;
|
|
||||||
};
|
|
||||||
|
|
||||||
const entity_sort = useSort(
|
|
||||||
{ nodes: deviceEntities },
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
sortIcon: {
|
|
||||||
iconDefault: <UnfoldMoreOutlinedIcon />,
|
|
||||||
iconUp: <KeyboardArrowUpOutlinedIcon />,
|
|
||||||
iconDown: <KeyboardArrowDownOutlinedIcon />
|
|
||||||
},
|
|
||||||
sortToggleType: SortToggleType.AlternateWithReset,
|
|
||||||
sortFns: {
|
|
||||||
NAME: (array) => array.sort((a, b) => a.id.localeCompare(b.id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const fetchDevices = useCallback(async () => {
|
const fetchDevices = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
setDevices((await EMSESP.readDevices()).data);
|
setDevices((await EMSESP.readDevices()).data);
|
||||||
@@ -166,13 +137,13 @@ const SettingsCustomization: FC = () => {
|
|||||||
}, [LL]);
|
}, [LL]);
|
||||||
|
|
||||||
const setInitialMask = (data: DeviceEntity[]) => {
|
const setInitialMask = (data: DeviceEntity[]) => {
|
||||||
setDeviceEntities(data.map((de) => ({ ...de, om: de.m })));
|
setDeviceEntities(data.map((de) => ({ ...de, o_m: de.m, o_cn: de.cn })));
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchDeviceEntities = async (unique_id: number) => {
|
const fetchDeviceEntities = async (unique_id: number) => {
|
||||||
try {
|
try {
|
||||||
const data = (await EMSESP.readDeviceEntities({ id: unique_id })).data;
|
const new_deviceEntities = (await EMSESP.readDeviceEntities({ id: unique_id })).data;
|
||||||
setInitialMask(data);
|
setInitialMask(new_deviceEntities);
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
setErrorMessage(extractErrorMessage(error, LL.PROBLEM_LOADING()));
|
setErrorMessage(extractErrorMessage(error, LL.PROBLEM_LOADING()));
|
||||||
}
|
}
|
||||||
@@ -196,12 +167,16 @@ const SettingsCustomization: FC = () => {
|
|||||||
function formatName(de: DeviceEntity) {
|
function formatName(de: DeviceEntity) {
|
||||||
if (de.n === undefined || de.n === de.id) {
|
if (de.n === undefined || de.n === de.id) {
|
||||||
return de.id;
|
return de.id;
|
||||||
} else if (de.n === '') {
|
}
|
||||||
|
|
||||||
|
if (de.n === '') {
|
||||||
return LL.COMMAND() + ': ' + de.id;
|
return LL.COMMAND() + ': ' + de.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{de.n} (
|
{de.cn !== undefined && de.cn !== '' ? de.cn : de.n}
|
||||||
|
(
|
||||||
<Link target="_blank" href={APIURL + devices?.devices[selectedDevice].t + '/' + de.id}>
|
<Link target="_blank" href={APIURL + devices?.devices[selectedDevice].t + '/' + de.id}>
|
||||||
{de.id}
|
{de.id}
|
||||||
</Link>
|
</Link>
|
||||||
@@ -274,10 +249,12 @@ const SettingsCustomization: FC = () => {
|
|||||||
const saveCustomization = async () => {
|
const saveCustomization = async () => {
|
||||||
if (devices && deviceEntities && selectedDevice !== -1) {
|
if (devices && deviceEntities && selectedDevice !== -1) {
|
||||||
const masked_entities = deviceEntities
|
const masked_entities = deviceEntities
|
||||||
.filter((de) => de.m !== de.om)
|
.filter((de) => de.m !== de.o_m || de.cn !== de.o_cn)
|
||||||
.map((new_de) => new_de.m.toString(16).padStart(2, '0') + new_de.id);
|
.map((new_de) => new_de.m.toString(16).padStart(2, '0') + new_de.id + (new_de.cn ? '|' + new_de.cn : ''));
|
||||||
|
|
||||||
if (masked_entities.length > 60) {
|
// check size in bytes to match buffer in CPP, which is 4096
|
||||||
|
const bytes = new TextEncoder().encode(JSON.stringify(masked_entities)).length;
|
||||||
|
if (bytes > 4000) {
|
||||||
enqueueSnackbar(LL.CUSTOMIZATIONS_FULL(), { variant: 'warning' });
|
enqueueSnackbar(LL.CUSTOMIZATIONS_FULL(), { variant: 'warning' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -339,16 +316,26 @@ const SettingsCustomization: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const editEntity = (de: DeviceEntity) => {
|
const editEntity = (de: DeviceEntity) => {
|
||||||
if (de.n) {
|
if (de.cn === undefined) {
|
||||||
setSelectedEntity(de);
|
de.cn = '';
|
||||||
console.log(de.n); // TODO
|
|
||||||
}
|
}
|
||||||
|
setDeviceEntity(de);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateEntity = () => {
|
const updateEntity = () => {
|
||||||
if (selectedEntity) {
|
if (deviceEntity) {
|
||||||
setSelectedEntity(undefined); // TODO
|
setDeviceEntities((prevState) => {
|
||||||
|
const newState = prevState.map((obj) => {
|
||||||
|
if (obj.id === deviceEntity.id) {
|
||||||
|
return { ...obj, cn: deviceEntity.cn };
|
||||||
}
|
}
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
|
return newState;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setDeviceEntity(undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderDeviceData = () => {
|
const renderDeviceData = () => {
|
||||||
@@ -445,19 +432,14 @@ const SettingsCustomization: FC = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Table data={{ nodes: shown_data }} theme={entities_theme} sort={entity_sort} layout={{ custom: true }}>
|
<Table data={{ nodes: shown_data }} theme={entities_theme} layout={{ custom: true }}>
|
||||||
{(tableList: any) => (
|
{(tableList: any) => (
|
||||||
<>
|
<>
|
||||||
<Header>
|
<Header>
|
||||||
<HeaderRow>
|
<HeaderRow>
|
||||||
<HeaderCell stiff>{LL.OPTIONS()}</HeaderCell>
|
<HeaderCell stiff>{LL.OPTIONS()}</HeaderCell>
|
||||||
<HeaderCell resize>
|
<HeaderCell resize>
|
||||||
<Button
|
<Button fullWidth style={{ fontSize: '14px', justifyContent: 'flex-start' }}>
|
||||||
fullWidth
|
|
||||||
style={{ fontSize: '14px', justifyContent: 'flex-start' }}
|
|
||||||
endIcon={getSortIcon(entity_sort.state, 'NAME')}
|
|
||||||
onClick={() => entity_sort.fns.onToggleSort({ sortKey: 'NAME' })}
|
|
||||||
>
|
|
||||||
{LL.NAME()}
|
{LL.NAME()}
|
||||||
</Button>
|
</Button>
|
||||||
</HeaderCell>
|
</HeaderCell>
|
||||||
@@ -576,24 +558,24 @@ const SettingsCustomization: FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderEditEntity = () => {
|
const renderEditEntity = () => (
|
||||||
if (selectedEntity) {
|
<Dialog open={!!deviceEntity} onClose={() => setDeviceEntity(undefined)}>
|
||||||
return (
|
{deviceEntity && (
|
||||||
<Dialog open={selectedEntity !== undefined} onClose={() => setSelectedEntity(undefined)}>
|
<>
|
||||||
<DialogTitle>Rename Entity</DialogTitle>
|
<DialogTitle>{LL.RENAME() + ' ' + LL.ENTITY_NAME()}</DialogTitle>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
|
||||||
<Typography variant="body2">{selectedEntity.n}</Typography>
|
<Typography variant="body2">{deviceEntity.n}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Grid container spacing={1}>
|
<Grid container spacing={1}>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<ValidatedTextField
|
<TextField
|
||||||
name="cn"
|
name="cn"
|
||||||
label={LL.NEW() + ' ' + LL.ENTITY_NAME()}
|
label={LL.NEW() + ' ' + LL.ENTITY_NAME()}
|
||||||
value={selectedEntity.cn}
|
value={deviceEntity.cn}
|
||||||
autoFocus
|
autoFocus
|
||||||
sx={{ width: '30ch' }}
|
sx={{ width: '30ch' }}
|
||||||
onChange={updateValue(setSelectedEntity)}
|
onChange={updateValue(setDeviceEntity)}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -602,7 +584,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={() => setSelectedEntity(undefined)}
|
onClick={() => setDeviceEntity(undefined)}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
>
|
>
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
@@ -617,10 +599,10 @@ const SettingsCustomization: FC = () => {
|
|||||||
{LL.SAVE()}
|
{LL.SAVE()}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContent title={LL.USER_CUSTOMIZATION()} titleGutter>
|
<SectionContent title={LL.USER_CUSTOMIZATION()} titleGutter>
|
||||||
|
|||||||
@@ -139,7 +139,8 @@ export interface DeviceEntity {
|
|||||||
n?: string; // fullname, optional
|
n?: string; // fullname, optional
|
||||||
cn?: string; // custom fullname, optional
|
cn?: string; // custom fullname, optional
|
||||||
m: number; // mask
|
m: number; // mask
|
||||||
om?: number; // original mask before edits
|
o_m?: number; // original mask before edits
|
||||||
|
o_cn?: string; // original cn before edits
|
||||||
w: boolean; // writeable
|
w: boolean; // writeable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ class FSPersistence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void readFromFS() {
|
void readFromFS() {
|
||||||
|
Serial.print("Fake reading file ");
|
||||||
|
Serial.println(_filePath);
|
||||||
applyDefaults();
|
applyDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ const emsesp_devicedata_1 = {
|
|||||||
{
|
{
|
||||||
v: '(0)',
|
v: '(0)',
|
||||||
u: 0,
|
u: 0,
|
||||||
id: '00error code',
|
id: '08error code',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
v: '14:54:39 06/06/2021',
|
v: '14:54:39 06/06/2021',
|
||||||
@@ -580,8 +580,9 @@ const emsesp_deviceentities_1 = [
|
|||||||
{
|
{
|
||||||
v: '(0)',
|
v: '(0)',
|
||||||
n: 'error code',
|
n: 'error code',
|
||||||
|
cn: 'my custom error code',
|
||||||
id: 'errorcode',
|
id: 'errorcode',
|
||||||
m: 0,
|
m: 8,
|
||||||
w: false,
|
w: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -922,22 +923,55 @@ rest_server.post(EMSESP_DEVICEENTITIES_ENDPOINT, (req, res) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function updateMask(entity, de, dd) {
|
function updateMask(entity, de, dd) {
|
||||||
const shortname = entity.slice(2)
|
new_mask = parseInt(entity.slice(0, 2), 16)
|
||||||
const new_mask = parseInt(entity.slice(0, 2), 16)
|
const shortname_with_customname = entity.slice(2)
|
||||||
|
const shortname = shortname_with_customname.split('|')[0]
|
||||||
|
const new_custom_name = shortname_with_customname.split('|')[1]
|
||||||
|
|
||||||
objIndex = de.findIndex((obj) => obj.id == shortname)
|
// find in de
|
||||||
if (objIndex !== -1) {
|
de_objIndex = de.findIndex((obj) => obj.id == shortname)
|
||||||
de[objIndex].m = new_mask
|
if (de_objIndex !== -1) {
|
||||||
const fullname = de[objIndex].n
|
// find in dd, either looking for fullname or custom name
|
||||||
objIndex = dd.data.findIndex((obj) => obj.id.slice(2) == fullname)
|
if (de[de_objIndex].cn) {
|
||||||
if (objIndex !== -1) {
|
fullname = de[de_objIndex].cn
|
||||||
// see if the mask has changed
|
} else {
|
||||||
const old_mask = parseInt(dd.data[objIndex].id.slice(0, 2), 16)
|
fullname = de[de_objIndex].n
|
||||||
if (old_mask !== new_mask) {
|
|
||||||
const mask_hex = entity.slice(0, 2)
|
|
||||||
console.log('Updating ' + dd.data[objIndex].id + ' -> ' + mask_hex + fullname)
|
|
||||||
dd.data[objIndex].id = mask_hex + fullname
|
|
||||||
}
|
}
|
||||||
|
dd_objIndex = dd.data.findIndex((obj) => obj.id.slice(2) == fullname)
|
||||||
|
if (dd_objIndex !== -1) {
|
||||||
|
let changed = new Boolean(false)
|
||||||
|
|
||||||
|
// see if the mask has changed
|
||||||
|
const old_mask = parseInt(dd.data[dd_objIndex].id.slice(0, 2), 16)
|
||||||
|
if (old_mask !== new_mask) {
|
||||||
|
console.log('mask has changed')
|
||||||
|
new_mask = entity.slice(0, 2)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if the custom name has changed
|
||||||
|
const old_custom_name = dd.data[dd_objIndex].cn
|
||||||
|
if (old_custom_name !== new_custom_name) {
|
||||||
|
console.log('name has changed')
|
||||||
|
changed = true
|
||||||
|
new_fullname = new_custom_name
|
||||||
|
} else {
|
||||||
|
new_fullname = fullname
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
console.log('Updating ' + dd.data[dd_objIndex].id + ' -> ' + new_mask + new_fullname)
|
||||||
|
de[de_objIndex].m = new_mask
|
||||||
|
de[de_objIndex].cn = new_fullname
|
||||||
|
dd.data[dd_objIndex].id = new_mask + new_fullname
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('dd:')
|
||||||
|
console.log(dd.data[dd_objIndex])
|
||||||
|
console.log('de:')
|
||||||
|
console.log(de[de_objIndex])
|
||||||
|
} else {
|
||||||
|
console.log('error, not found')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("can't locate record for name " + shortname)
|
console.log("can't locate record for name " + shortname)
|
||||||
|
|||||||
@@ -259,8 +259,8 @@ bool EMSdevice::has_tag(const uint8_t tag) const {
|
|||||||
// called from the command 'entities'
|
// called from the command 'entities'
|
||||||
void EMSdevice::list_device_entries(JsonObject & output) const {
|
void EMSdevice::list_device_entries(JsonObject & output) const {
|
||||||
for (const auto & dv : devicevalues_) {
|
for (const auto & dv : devicevalues_) {
|
||||||
auto fullname = Helpers::translated_fword(dv.fullname);
|
std::string fullname = dv.get_fullname();
|
||||||
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.type != DeviceValueType::CMD && fullname) {
|
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.type != DeviceValueType::CMD && !fullname.empty()) {
|
||||||
// if we have a tag prefix it
|
// if we have a tag prefix it
|
||||||
char key[50];
|
char key[50];
|
||||||
if (!EMSdevice::tag_to_mqtt(dv.tag).empty()) {
|
if (!EMSdevice::tag_to_mqtt(dv.tag).empty()) {
|
||||||
@@ -433,15 +433,51 @@ void EMSdevice::add_device_value(uint8_t tag,
|
|||||||
// determine state
|
// determine state
|
||||||
uint8_t state = DeviceValueState::DV_DEFAULT;
|
uint8_t state = DeviceValueState::DV_DEFAULT;
|
||||||
|
|
||||||
|
// custom fullname
|
||||||
|
std::string custom_fullname = std::string("");
|
||||||
|
|
||||||
// scan through customizations to see if it's on the exclusion list by matching the productID and deviceID
|
// scan through customizations to see if it's on the exclusion list by matching the productID and deviceID
|
||||||
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
|
EMSESP::webCustomizationService.read([&](WebCustomization & settings) {
|
||||||
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
|
for (EntityCustomization entityCustomization : settings.entityCustomizations) {
|
||||||
if ((entityCustomization.product_id == product_id()) && (entityCustomization.device_id == device_id())) {
|
if ((entityCustomization.product_id == product_id()) && (entityCustomization.device_id == device_id())) {
|
||||||
std::string entity = tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(short_name) : tag_to_string(tag) + "/" + read_flash_string(short_name);
|
std::string entity = tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(short_name) : tag_to_string(tag) + "/" + read_flash_string(short_name);
|
||||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||||
if (entity_id.substr(2) == entity) {
|
// if there is an appended custom name, strip it to get the true entity name
|
||||||
|
// and extract the new custom name
|
||||||
|
std::string matched_entity;
|
||||||
|
auto custom_name_pos = entity_id.find('|');
|
||||||
|
bool has_custom_name = (custom_name_pos != std::string::npos);
|
||||||
|
if (has_custom_name) {
|
||||||
|
matched_entity = entity_id.substr(2, custom_name_pos - 2);
|
||||||
|
} else {
|
||||||
|
matched_entity = entity_id.substr(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print(COLOR_BRIGHT_GREEN);
|
||||||
|
Serial.print(" entity name=");
|
||||||
|
Serial.print(entity_id.c_str());
|
||||||
|
Serial.print(" ,matched name=");
|
||||||
|
Serial.print(matched_entity.c_str());
|
||||||
|
Serial.print(" ,matched pos=");
|
||||||
|
Serial.println(custom_name_pos);
|
||||||
|
Serial.print(COLOR_RESET);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// we found the device entity
|
||||||
|
if (matched_entity == entity) {
|
||||||
|
// get Mask
|
||||||
uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str());
|
uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str());
|
||||||
state = mask << 4; // set state high bits to flag, turn off active and ha flags
|
state = mask << 4; // set state high bits to flag, turn off active and ha flags
|
||||||
|
// see if there is a custom name in the entity string
|
||||||
|
if (has_custom_name) {
|
||||||
|
/*
|
||||||
|
Serial.print(COLOR_BRIGHT_MAGENTA);
|
||||||
|
Serial.println(entity_id.substr(custom_name_pos + 1).c_str());
|
||||||
|
Serial.print(COLOR_RESET);
|
||||||
|
*/
|
||||||
|
custom_fullname = entity_id.substr(custom_name_pos + 1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -449,11 +485,6 @@ void EMSdevice::add_device_value(uint8_t tag,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO
|
|
||||||
const __FlashStringHelper * custom_fullname;
|
|
||||||
|
|
||||||
custom_fullname = nullptr;
|
|
||||||
|
|
||||||
// add the device entity
|
// add the device entity
|
||||||
devicevalues_.emplace_back(
|
devicevalues_.emplace_back(
|
||||||
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
|
device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, custom_fullname, uom, has_cmd, min, max, state);
|
||||||
@@ -475,6 +506,7 @@ void EMSdevice::add_device_value(uint8_t tag,
|
|||||||
|
|
||||||
// add the command to our library
|
// add the command to our library
|
||||||
// cmd is the short_name and the description is the fullname
|
// cmd is the short_name and the description is the fullname
|
||||||
|
// TODO this needs adapting to take the custom fullname since its not a FPTR()
|
||||||
Command::add(device_type_, short_name, f, Helpers::translated_fword(fullname), flags);
|
Command::add(device_type_, short_name, f, Helpers::translated_fword(fullname), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,6 +732,8 @@ void EMSdevice::publish_value(void * value_p) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// looks up the UOM for a given key from the device value table
|
// looks up the UOM for a given key from the device value table
|
||||||
|
// key is the fullname
|
||||||
|
// TODO really should be using the shortname as the identifier
|
||||||
std::string EMSdevice::get_value_uom(const char * key) const {
|
std::string EMSdevice::get_value_uom(const char * key) const {
|
||||||
// the key may have a TAG string prefixed at the beginning. If so, remove it
|
// the key may have a TAG string prefixed at the beginning. If so, remove it
|
||||||
char new_key[80];
|
char new_key[80];
|
||||||
@@ -719,8 +753,8 @@ std::string EMSdevice::get_value_uom(const char * key) const {
|
|||||||
|
|
||||||
// look up key in our device value list
|
// look up key in our device value list
|
||||||
for (const auto & dv : devicevalues_) {
|
for (const auto & dv : devicevalues_) {
|
||||||
auto fullname = Helpers::translated_fword(dv.fullname);
|
auto fullname = dv.get_fullname();
|
||||||
if ((!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && fullname) && (read_flash_string(fullname) == key_p)) {
|
if ((!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && !fullname.empty()) && (fullname == key_p)) {
|
||||||
// ignore TIME since "minutes" is already added to the string value
|
// ignore TIME since "minutes" is already added to the string value
|
||||||
if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) {
|
if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) {
|
||||||
break;
|
break;
|
||||||
@@ -741,13 +775,13 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
|||||||
JsonArray data = output.createNestedArray("data");
|
JsonArray data = output.createNestedArray("data");
|
||||||
|
|
||||||
for (auto & dv : devicevalues_) {
|
for (auto & dv : devicevalues_) {
|
||||||
auto fullname = Helpers::translated_fword(dv.fullname);
|
auto fullname = dv.get_fullname();
|
||||||
|
|
||||||
// check conditions:
|
// check conditions:
|
||||||
// 1. fullname cannot be empty
|
// 1. fullname cannot be empty
|
||||||
// 2. it must have a valid value, if it is not a command like 'reset'
|
// 2. it must have a valid value, if it is not a command like 'reset'
|
||||||
// 3. show favorites first
|
// 3. show favorites first
|
||||||
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && fullname && (dv.hasValue() || (dv.type == DeviceValueType::CMD))) {
|
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && !fullname.empty() && (dv.hasValue() || (dv.type == DeviceValueType::CMD))) {
|
||||||
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value
|
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value
|
||||||
uint8_t fahrenheit = 0;
|
uint8_t fahrenheit = 0;
|
||||||
|
|
||||||
@@ -797,9 +831,9 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
|||||||
|
|
||||||
// add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique
|
// add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique
|
||||||
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
|
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
|
||||||
obj["id"] = mask + Helpers::translated_word(dv.fullname);
|
obj["id"] = mask + dv.get_fullname();
|
||||||
} else {
|
} else {
|
||||||
obj["id"] = mask + tag_to_string(dv.tag) + " " + Helpers::translated_word(dv.fullname);
|
obj["id"] = mask + tag_to_string(dv.tag) + " " + dv.get_fullname();
|
||||||
}
|
}
|
||||||
|
|
||||||
// add commands and options
|
// add commands and options
|
||||||
@@ -928,14 +962,14 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
|||||||
|
|
||||||
// n is the fullname, and can be optional
|
// n is the fullname, and can be optional
|
||||||
// don't add the fullname if its a command
|
// don't add the fullname if its a command
|
||||||
auto translated_full_name = Helpers::translated_fword(dv.fullname);
|
auto fullname = dv.get_fullname();
|
||||||
if (dv.type != DeviceValueType::CMD) {
|
if (dv.type != DeviceValueType::CMD) {
|
||||||
if (translated_full_name) {
|
if (!fullname.empty()) {
|
||||||
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
|
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
|
||||||
obj["n"] = read_flash_string(translated_full_name);
|
obj["n"] = fullname;
|
||||||
} else {
|
} else {
|
||||||
char name[50];
|
char name[50];
|
||||||
snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(translated_full_name).c_str());
|
snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), fullname.c_str());
|
||||||
obj["n"] = name;
|
obj["n"] = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -943,6 +977,11 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
|||||||
obj["n"] = "";
|
obj["n"] = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the custom name, is optional
|
||||||
|
if (!dv.custom_fullname.empty()) {
|
||||||
|
obj["cn"] = dv.custom_fullname;
|
||||||
|
}
|
||||||
|
|
||||||
obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble
|
obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble
|
||||||
obj["w"] = dv.has_cmd; // if writable
|
obj["w"] = dv.has_cmd; // if writable
|
||||||
}
|
}
|
||||||
@@ -1018,12 +1057,12 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
|
|||||||
|
|
||||||
json["name"] = dv.short_name;
|
json["name"] = dv.short_name;
|
||||||
|
|
||||||
auto fullname = Helpers::translated_fword(dv.fullname);
|
auto fullname = dv.get_fullname();
|
||||||
if (fullname != nullptr) {
|
if (!fullname.empty()) {
|
||||||
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
|
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
|
||||||
json["fullname"] = fullname;
|
json["fullname"] = fullname;
|
||||||
} else {
|
} else {
|
||||||
json["fullname"] = tag_to_string(dv.tag) + " " + read_flash_string(fullname);
|
json["fullname"] = tag_to_string(dv.tag) + " " + fullname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1202,14 +1241,14 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
|||||||
dv.remove_state(DeviceValueState::DV_ACTIVE);
|
dv.remove_state(DeviceValueState::DV_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fullname = Helpers::translated_fword(dv.fullname);
|
auto fullname = dv.get_fullname();
|
||||||
|
|
||||||
// check conditions:
|
// check conditions:
|
||||||
// 1. it must have a valid value (state is active)
|
// 1. it must have a valid value (state is active)
|
||||||
// 2. it must have a visible flag
|
// 2. it must have a visible flag
|
||||||
// 3. it must match the given tag filter or have an empty tag
|
// 3. it must match the given tag filter or have an empty tag
|
||||||
// 4. it must not have the exclude flag set or outputs to console
|
// 4. it must not have the exclude flag set or outputs to console
|
||||||
if (dv.has_state(DeviceValueState::DV_ACTIVE) && fullname && (tag_filter == DeviceValueTAG::TAG_NONE || tag_filter == dv.tag)
|
if (dv.has_state(DeviceValueState::DV_ACTIVE) && !fullname.empty() && (tag_filter == DeviceValueTAG::TAG_NONE || tag_filter == dv.tag)
|
||||||
&& (output_target == OUTPUT_TARGET::CONSOLE || !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE))) {
|
&& (output_target == OUTPUT_TARGET::CONSOLE || !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE))) {
|
||||||
has_values = true; // flagged if we actually have data
|
has_values = true; // flagged if we actually have data
|
||||||
|
|
||||||
@@ -1221,9 +1260,9 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
|
|||||||
|
|
||||||
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
|
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
|
||||||
if (have_tag) {
|
if (have_tag) {
|
||||||
snprintf(name, 80, "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(fullname).c_str()); // prefix the tag
|
snprintf(name, 80, "%s %s", tag_to_string(dv.tag).c_str(), fullname.c_str()); // prefix the tag
|
||||||
} else {
|
} else {
|
||||||
strlcpy(name, read_flash_string(fullname).c_str(), sizeof(name)); // use full name
|
strlcpy(name, fullname.c_str(), sizeof(name)); // use full name
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strlcpy(name, read_flash_string(dv.short_name).c_str(), sizeof(name)); // use short name
|
strlcpy(name, read_flash_string(dv.short_name).c_str(), sizeof(name)); // use short name
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
|||||||
int8_t numeric_operator,
|
int8_t numeric_operator,
|
||||||
const __FlashStringHelper * const short_name,
|
const __FlashStringHelper * const short_name,
|
||||||
const __FlashStringHelper * const * fullname,
|
const __FlashStringHelper * const * fullname,
|
||||||
const __FlashStringHelper * const custom_fullname,
|
const std::string & custom_fullname,
|
||||||
uint8_t uom,
|
uint8_t uom,
|
||||||
bool has_cmd,
|
bool has_cmd,
|
||||||
int16_t min,
|
int16_t min,
|
||||||
@@ -65,8 +65,13 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
|||||||
Serial.print("registering entity: ");
|
Serial.print("registering entity: ");
|
||||||
Serial.print(read_flash_string(short_name).c_str());
|
Serial.print(read_flash_string(short_name).c_str());
|
||||||
Serial.print("/");
|
Serial.print("/");
|
||||||
auto trans_fullname = Helpers::translated_word(fullname);
|
if (!custom_fullname.empty()) {
|
||||||
Serial.print(trans_fullname.c_str());
|
Serial.print(COLOR_BRIGHT_CYAN);
|
||||||
|
Serial.print(custom_fullname.c_str());
|
||||||
|
Serial.print(COLOR_RESET);
|
||||||
|
} else {
|
||||||
|
Serial.print(Helpers::translated_word(fullname).c_str());
|
||||||
|
}
|
||||||
Serial.print(" (#options=");
|
Serial.print(" (#options=");
|
||||||
Serial.print(options_size);
|
Serial.print(options_size);
|
||||||
Serial.print(",numop=");
|
Serial.print(",numop=");
|
||||||
@@ -321,4 +326,13 @@ bool DeviceValue::get_min_max(int16_t & dv_set_min, int16_t & dv_set_max) {
|
|||||||
return false; // nothing changed, not supported
|
return false; // nothing changed, not supported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns the translated fullname or the custom fullname (if provided)
|
||||||
|
// always returns a std::string
|
||||||
|
std::string DeviceValue::get_fullname() const {
|
||||||
|
if (custom_fullname.empty()) {
|
||||||
|
return Helpers::translated_word(fullname);
|
||||||
|
}
|
||||||
|
return custom_fullname;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ class DeviceValue {
|
|||||||
uint8_t options_size; // number of options in the char array, calculated
|
uint8_t options_size; // number of options in the char array, calculated
|
||||||
const __FlashStringHelper * const short_name; // used in MQTT and API
|
const __FlashStringHelper * const short_name; // used in MQTT and API
|
||||||
const __FlashStringHelper * const * fullname; // used in Web and Console, is translated
|
const __FlashStringHelper * const * fullname; // used in Web and Console, is translated
|
||||||
const __FlashStringHelper * const custom_fullname; // optional, from customization
|
const std::string custom_fullname; // optional, from customization
|
||||||
uint8_t uom; // DeviceValueUOM::*
|
uint8_t uom; // DeviceValueUOM::*
|
||||||
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
||||||
int16_t min; // min range
|
int16_t min; // min range
|
||||||
@@ -169,7 +169,7 @@ class DeviceValue {
|
|||||||
int8_t numeric_operator,
|
int8_t numeric_operator,
|
||||||
const __FlashStringHelper * const short_name,
|
const __FlashStringHelper * const short_name,
|
||||||
const __FlashStringHelper * const * fullname,
|
const __FlashStringHelper * const * fullname,
|
||||||
const __FlashStringHelper * const custom_fullname,
|
const std::string & custom_fullname,
|
||||||
uint8_t uom,
|
uint8_t uom,
|
||||||
bool has_cmd,
|
bool has_cmd,
|
||||||
int16_t min,
|
int16_t min,
|
||||||
@@ -179,6 +179,8 @@ class DeviceValue {
|
|||||||
bool hasValue() const;
|
bool hasValue() const;
|
||||||
bool get_min_max(int16_t & dv_set_min, int16_t & dv_set_max);
|
bool get_min_max(int16_t & dv_set_min, int16_t & dv_set_max);
|
||||||
|
|
||||||
|
std::string get_fullname() const;
|
||||||
|
|
||||||
// dv state flags
|
// dv state flags
|
||||||
void add_state(uint8_t s) {
|
void add_state(uint8_t s) {
|
||||||
state |= s;
|
state |= s;
|
||||||
|
|||||||
14
src/mqtt.cpp
14
src/mqtt.cpp
@@ -937,7 +937,7 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
|
|||||||
|
|
||||||
publish_ha_sensor_config(dv.type,
|
publish_ha_sensor_config(dv.type,
|
||||||
dv.tag,
|
dv.tag,
|
||||||
Helpers::translated_fword(dv.fullname),
|
dv.get_fullname(),
|
||||||
dv.device_type,
|
dv.device_type,
|
||||||
dv.short_name,
|
dv.short_name,
|
||||||
dv.uom,
|
dv.uom,
|
||||||
@@ -958,7 +958,9 @@ void Mqtt::publish_system_ha_sensor_config(uint8_t type, const __FlashStringHelp
|
|||||||
JsonArray ids = dev_json.createNestedArray("ids");
|
JsonArray ids = dev_json.createNestedArray("ids");
|
||||||
ids.add("ems-esp");
|
ids.add("ems-esp");
|
||||||
|
|
||||||
publish_ha_sensor_config(type, DeviceValueTAG::TAG_HEARTBEAT, name, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, dev_json);
|
auto fullname = read_flash_string(name); // TODO make sure it works, it may need a std::move()?
|
||||||
|
|
||||||
|
publish_ha_sensor_config(type, DeviceValueTAG::TAG_HEARTBEAT, fullname, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, dev_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MQTT discovery configs
|
// MQTT discovery configs
|
||||||
@@ -966,7 +968,7 @@ void Mqtt::publish_system_ha_sensor_config(uint8_t type, const __FlashStringHelp
|
|||||||
// note: some extra string copying done here, it looks messy but does help with heap fragmentation issues
|
// note: some extra string copying done here, it looks messy but does help with heap fragmentation issues
|
||||||
void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice::DeviceValueType
|
void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice::DeviceValueType
|
||||||
uint8_t tag, // EMSdevice::DeviceValueTAG
|
uint8_t tag, // EMSdevice::DeviceValueTAG
|
||||||
const __FlashStringHelper * const fullname, // fullname, already translated
|
const std::string & fullname, // fullname, already translated
|
||||||
const uint8_t device_type, // EMSdevice::DeviceType
|
const uint8_t device_type, // EMSdevice::DeviceType
|
||||||
const __FlashStringHelper * const entity, // same as shortname
|
const __FlashStringHelper * const entity, // same as shortname
|
||||||
const uint8_t uom, // EMSdevice::DeviceValueUOM (0=NONE)
|
const uint8_t uom, // EMSdevice::DeviceValueUOM (0=NONE)
|
||||||
@@ -978,7 +980,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
|||||||
const int16_t dv_set_max,
|
const int16_t dv_set_max,
|
||||||
const JsonObject & dev_json) {
|
const JsonObject & dev_json) {
|
||||||
// ignore if name (fullname) is empty
|
// ignore if name (fullname) is empty
|
||||||
if (fullname == nullptr) {
|
if (fullname.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1114,9 +1116,9 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
|
|||||||
// friendly name = <tag> <name>
|
// friendly name = <tag> <name>
|
||||||
char ha_name[70];
|
char ha_name[70];
|
||||||
if (have_tag) {
|
if (have_tag) {
|
||||||
snprintf(ha_name, sizeof(ha_name), "%s %s", EMSdevice::tag_to_string(tag).c_str(), read_flash_string(fullname).c_str());
|
snprintf(ha_name, sizeof(ha_name), "%s %s", EMSdevice::tag_to_string(tag).c_str(), fullname.c_str());
|
||||||
} else {
|
} else {
|
||||||
snprintf(ha_name, sizeof(ha_name), "%s", read_flash_string(fullname).c_str());
|
snprintf(ha_name, sizeof(ha_name), "%s", fullname.c_str());
|
||||||
}
|
}
|
||||||
ha_name[0] = toupper(ha_name[0]); // capitalize first letter
|
ha_name[0] = toupper(ha_name[0]); // capitalize first letter
|
||||||
doc["name"] = ha_name;
|
doc["name"] = ha_name;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class Mqtt {
|
|||||||
publish_ha_sensor_config(DeviceValue & dv, const std::string & model, const std::string & brand, const bool remove, const bool create_device_config = false);
|
publish_ha_sensor_config(DeviceValue & dv, const std::string & model, const std::string & brand, const bool remove, const bool create_device_config = false);
|
||||||
static void publish_ha_sensor_config(uint8_t type,
|
static void publish_ha_sensor_config(uint8_t type,
|
||||||
uint8_t tag,
|
uint8_t tag,
|
||||||
const __FlashStringHelper * const fullname,
|
const std::string & fullname,
|
||||||
const uint8_t device_type,
|
const uint8_t device_type,
|
||||||
const __FlashStringHelper * const entity,
|
const __FlashStringHelper * const entity,
|
||||||
const uint8_t uom,
|
const uint8_t uom,
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
|
|
||||||
#if defined(EMSESP_STANDALONE)
|
#if defined(EMSESP_STANDALONE)
|
||||||
|
|
||||||
DynamicJsonDocument doc(8000); // some absurb high number
|
DynamicJsonDocument doc(8000); // some absurd high number
|
||||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||||
if (emsdevice) {
|
if (emsdevice) {
|
||||||
doc.clear();
|
doc.clear();
|
||||||
|
|||||||
@@ -95,11 +95,27 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
|||||||
// call on initialization and also when the page is saved via web UI
|
// call on initialization and also when the page is saved via web UI
|
||||||
// this loads the data into the internal class
|
// this loads the data into the internal class
|
||||||
StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & settings) {
|
StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & settings) {
|
||||||
|
#ifdef EMSESP_STANDALONE
|
||||||
|
// invoke some fake data for testing
|
||||||
|
// using https://arduinojson.org/v5/assistant/
|
||||||
|
const char * json =
|
||||||
|
"{\"sensors\":[],\"analogs\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom name for heating active\",\"08tapwateractive\"]}]}";
|
||||||
|
|
||||||
|
StaticJsonDocument<500> doc;
|
||||||
|
deserializeJson(doc, json);
|
||||||
|
root = doc.as<JsonObject>();
|
||||||
|
|
||||||
|
Serial.println(COLOR_BRIGHT_MAGENTA);
|
||||||
|
Serial.print("Using custom file: ");
|
||||||
|
serializeJson(root, Serial);
|
||||||
|
Serial.println(COLOR_RESET);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Dallas Sensor customization
|
// Dallas Sensor customization
|
||||||
settings.sensorCustomizations.clear();
|
settings.sensorCustomizations.clear();
|
||||||
if (root["sensors"].is<JsonArray>()) {
|
if (root["sensors"].is<JsonArray>()) {
|
||||||
for (const JsonObject sensorJson : root["sensors"].as<JsonArray>()) {
|
for (const JsonObject sensorJson : root["sensors"].as<JsonArray>()) {
|
||||||
// create each of the sensor, overwritting any previous settings
|
// create each of the sensor, overwriting any previous settings
|
||||||
auto sensor = SensorCustomization();
|
auto sensor = SensorCustomization();
|
||||||
sensor.id = sensorJson["id"].as<std::string>();
|
sensor.id = sensorJson["id"].as<std::string>();
|
||||||
sensor.name = sensorJson["name"].as<std::string>();
|
sensor.name = sensorJson["name"].as<std::string>();
|
||||||
@@ -112,7 +128,7 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
|||||||
settings.analogCustomizations.clear();
|
settings.analogCustomizations.clear();
|
||||||
if (root["analogs"].is<JsonArray>()) {
|
if (root["analogs"].is<JsonArray>()) {
|
||||||
for (const JsonObject analogJson : root["analogs"].as<JsonArray>()) {
|
for (const JsonObject analogJson : root["analogs"].as<JsonArray>()) {
|
||||||
// create each of the sensor, overwritting any previous settings
|
// create each of the sensor, overwriting any previous settings
|
||||||
auto sensor = AnalogCustomization();
|
auto sensor = AnalogCustomization();
|
||||||
sensor.gpio = analogJson["gpio"];
|
sensor.gpio = analogJson["gpio"];
|
||||||
sensor.name = analogJson["name"].as<std::string>();
|
sensor.name = analogJson["name"].as<std::string>();
|
||||||
@@ -160,7 +176,7 @@ void WebCustomizationService::reset_customization(AsyncWebServerRequest * reques
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// send back a list of devices used to the customization web page
|
// send back a list of devices used in the customization web page
|
||||||
void WebCustomizationService::devices(AsyncWebServerRequest * request) {
|
void WebCustomizationService::devices(AsyncWebServerRequest * request) {
|
||||||
auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_LARGE_DYN);
|
auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_LARGE_DYN);
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
@@ -173,18 +189,6 @@ void WebCustomizationService::devices(AsyncWebServerRequest * request) {
|
|||||||
JsonObject obj = devices.createNestedObject();
|
JsonObject obj = devices.createNestedObject();
|
||||||
obj["i"] = emsdevice->unique_id(); // its unique id
|
obj["i"] = emsdevice->unique_id(); // its unique id
|
||||||
obj["s"] = emsdevice->device_type_name() + " (" + emsdevice->name() + ")"; // shortname
|
obj["s"] = emsdevice->device_type_name() + " (" + emsdevice->name() + ")"; // shortname
|
||||||
|
|
||||||
// device type name. We may have one than one (e.g. multiple thermostats) so postfix name with index
|
|
||||||
// code block not needed - see https://github.com/emsesp/EMS-ESP32/pull/586#issuecomment-1193779668
|
|
||||||
/*
|
|
||||||
uint8_t device_index = EMSESP::device_index(emsdevice->device_type(), emsdevice->unique_id());
|
|
||||||
if (device_index) {
|
|
||||||
char s[10];
|
|
||||||
obj["t"] = Helpers::toLower(emsdevice->device_type_name()) + Helpers::smallitoa(s, device_index);
|
|
||||||
} else {
|
|
||||||
obj["t"] = Helpers::toLower(emsdevice->device_type_name());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
obj["t"] = Helpers::toLower(emsdevice->device_type_name());
|
obj["t"] = Helpers::toLower(emsdevice->device_type_name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user