Add "duplicate" option to Custom Entities #2266

This commit is contained in:
MichaelDvP
2024-12-05 18:41:41 +01:00
parent 5f42709eab
commit a218c7a781
20 changed files with 213 additions and 173 deletions

View File

@@ -9,6 +9,8 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
- change enum_heatingtype for remote control [#2268](https://github.com/emsesp/EMS-ESP32/issues/2268)
- system service commands [#2182](https://github.com/emsesp/EMS-ESP32/issues/2282)
- read 0x02A5 for thermostat CT200 [#2277](https://github.com/emsesp/EMS-ESP32/issues/2277)
- Add "duplicate" option to Custom Entities [#2266](https://github.com/emsesp/EMS-ESP32/discussion/2266)
- Mask bits for bool custom entities
## Fixed

View File

@@ -32,8 +32,8 @@
"jwt-decode": "^4.0.0",
"mime-types": "^2.1.35",
"preact": "^10.25.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-icons": "^5.4.0",
"react-router": "^7.0.2",
"react-toastify": "^10.0.6",
@@ -45,7 +45,7 @@
"@eslint/js": "^9.16.0",
"@preact/compat": "^18.3.1",
"@preact/preset-vite": "^2.9.2",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@trivago/prettier-plugin-sort-imports": "^5.0.1",
"@types/formidable": "^3",
"@types/node": "^22.10.1",
"@types/react": "^18.3.13",
@@ -56,9 +56,9 @@
"formidable": "^3.5.2",
"prettier": "^3.4.2",
"rollup-plugin-visualizer": "^5.12.0",
"terser": "^5.36.0",
"terser": "^5.37.0",
"typescript-eslint": "8.17.0",
"vite": "^6.0.2",
"vite": "^6.0.3",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.1.3"
},

View File

@@ -83,7 +83,7 @@ const CustomEntities = () => {
const entity_theme = useTheme({
Table: `
--data-table-library_grid-template-columns: repeat(1, minmax(60px, 1fr)) minmax(80px, auto) 80px 80px 80px 90px;
--data-table-library_grid-template-columns: repeat(1, minmax(60px, 1fr)) minmax(80px, auto) 80px 80px 80px 120px;
`,
BaseRow: `
font-size: 14px;
@@ -195,6 +195,25 @@ const CustomEntities = () => {
});
};
const onDialogDup = (item: EntityItem) => {
setCreating(true);
setSelectedEntityItem({
id: Math.floor(Math.random() * (Math.floor(200) - 100) + 100),
name: item.name + '_',
ram: item.ram,
device_id: item.device_id,
type_id: item.type_id,
offset: item.offset,
factor: item.factor,
uom: item.uom,
value_type: item.value_type,
writeable: item.writeable,
deleted: false,
value: item.value
});
setDialogOpen(true);
};
const addEntityItem = () => {
setCreating(true);
setSelectedEntityItem({
@@ -220,7 +239,7 @@ const CustomEntities = () => {
: typeof value === 'number'
? new Intl.NumberFormat().format(value) +
(uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom])
: (value as string);
: (value as string) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]);
}
function showHex(value: number, digit: number) {
@@ -296,6 +315,7 @@ const CustomEntities = () => {
creating={creating}
onClose={onDialogClose}
onSave={onDialogSave}
onDup={onDialogDup}
selectedItem={selectedEntityItem}
validator={entityItemValidation(entities, selectedEntityItem)}
/>

View File

@@ -34,6 +34,7 @@ interface CustomEntitiesDialogProps {
creating: boolean;
onClose: () => void;
onSave: (ei: EntityItem) => void;
onDup: (ei: EntityItem) => void;
selectedItem: EntityItem;
validator: Schema;
}
@@ -43,6 +44,7 @@ const CustomEntitiesDialog = ({
creating,
onClose,
onSave,
onDup,
selectedItem,
validator
}: CustomEntitiesDialogProps) => {
@@ -91,6 +93,10 @@ const CustomEntitiesDialog = ({
onSave(editItem);
};
const dup = () => {
onDup(editItem);
};
return (
<Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle>
@@ -128,6 +134,7 @@ const CustomEntitiesDialog = ({
</TextField>
</Grid>
{editItem.ram === 1 && (
<>
<Grid>
<TextField
name="value"
@@ -140,6 +147,23 @@ const CustomEntitiesDialog = ({
margin="normal"
/>
</Grid>
<Grid>
<TextField
name="uom"
label={LL.UNIT()}
value={editItem.uom}
margin="normal"
onChange={updateFormValue}
select
>
{DeviceValueUOM_s.map((val, i) => (
<MenuItem key={val} value={i}>
{val}
</MenuItem>
))}
</TextField>
</Grid>
</>
)}
{editItem.ram === 0 && (
<>
@@ -255,7 +279,7 @@ const CustomEntitiesDialog = ({
<TextField
name="factor"
label={LL.FACTOR()}
value={numberValue(editItem.factor)}
value={numberValue(editItem.factor as number)}
variant="outlined"
onChange={updateFormValue}
sx={{ width: '11ch' }}
@@ -292,12 +316,38 @@ const CustomEntitiesDialog = ({
fieldErrors={fieldErrors}
name="factor"
label="Bytes"
value={numberValue(editItem.factor)}
value={numberValue(editItem.factor as number)}
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
margin="normal"
type="number"
slotProps={{
htmlInput: { step: '1', min: '1', max: '255' }
}}
/>
</Grid>
)}
{editItem.value_type === DeviceValueType.BOOL && (
<Grid>
<ValidatedTextField
fieldErrors={fieldErrors}
name="factor"
label="Mask"
value={editItem.factor as string}
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
margin="normal"
type="string"
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">0x</InputAdornment>
)
},
htmlInput: { style: { textTransform: 'uppercase' } }
}}
/>
</Grid>
)}
@@ -316,6 +366,15 @@ const CustomEntitiesDialog = ({
>
{LL.REMOVE()}
</Button>
<Button
sx={{ ml: 1 }}
startIcon={<AddIcon />}
variant="outlined"
color="primary"
onClick={dup}
>
{LL.DUPLICATE()}
</Button>
</Box>
)}
<Button

View File

@@ -34,7 +34,7 @@ export function formatValue(
if (value === undefined || typeof value === 'boolean') {
return '';
}
return value as string;
return (value as string) + (uom === undefined || uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]);
}
switch (uom) {

View File

@@ -368,7 +368,7 @@ export interface EntityItem {
device_id: number | string;
type_id: number | string;
offset: number;
factor: number;
factor: number | string;
uom: number;
value_type: number;
value?: unknown;
@@ -380,7 +380,7 @@ export interface EntityItem {
o_device_id?: number | string;
o_type_id?: number | string;
o_offset?: number;
o_factor?: number;
o_factor?: number | string;
o_uom?: number;
o_value_type?: number;
o_deleted?: boolean;

View File

@@ -383,8 +383,7 @@ export const entityItemValidation = (entity: EntityItem[], entityItem: EntityIte
{ type: 'number', min: 0, max: 255, message: 'Must be between 0 and 255' }
],
factor: [
{ required: true, message: 'is required' },
{ type: 'number', message: 'Must be a number' }
{ required: true, message: 'is required' }
]
});

View File

@@ -343,6 +343,7 @@ const cz: Translation = {
NO_DATA: 'Žádná data nejsou k dispozici',
DASHBOARD_1: 'Přizpůsobte si dashboard označením EMS entit jako Oblíbené pomocí modulu Přizpůsobení',
DEVELOPER_MODE: 'Režim vývojáře',
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,7 +343,8 @@ const de: Translation = {
NO_DATA: 'Keine Daten verfügbar',
DASHBOARD_1: 'Passen Sie Ihr Dashboard an, indem Sie EMS-Entitäten mithilfe des Moduls „Anpassungen“ als Favorit markieren',
DEVELOPER_MODE: 'Entwicklermodus',
UPGRADE: 'Upgrade' // TODO translate
DUPLICATE: 'Kopieren',
UPGRADE: 'Aktualisieren'
};
export default de;

View File

@@ -343,6 +343,7 @@ const en: Translation = {
NO_DATA: 'No data available',
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module',
DEVELOPER_MODE: 'Developer Mode',
DUPLICATE: 'Duplicate',
UPGRADE: 'Upgrade'
};

View File

@@ -343,6 +343,7 @@ const fr: Translation = {
NO_DATA: 'No data available', // TODO translate
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,6 +343,7 @@ const it: Translation = {
NO_DATA: 'No data available', // TODO translate
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,6 +343,7 @@ const nl: Translation = {
NO_DATA: 'No data available', // TODO translate
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,6 +343,7 @@ const no: Translation = {
NO_DATA: 'No data available', // TODO translate
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,6 +343,7 @@ const pl: BaseTranslation = {
NO_DATA: 'No data available', // TODO translate
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,6 +343,7 @@ const sk: Translation = {
NO_DATA: 'Nie sú k dispozícii žiadne údaje',
DASHBOARD_1: 'Prispôsobte si svoj informačný panel tak, že označíte entity EMS ako Obľúbené pomocou modulu Prispôsobenia',
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,6 +343,7 @@ const sv: Translation = {
NO_DATA: 'No data available', // TODO translate
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -343,6 +343,7 @@ const tr: Translation = {
NO_DATA: 'No data available', // TODO translate
DASHBOARD_1: 'Customize your dashboard by marking EMS entities as Favorite using the Customizations module', // TODO translate
DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate
};

View File

@@ -74,18 +74,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/generator@npm:7.17.7":
version: 7.17.7
resolution: "@babel/generator@npm:7.17.7"
dependencies:
"@babel/types": "npm:^7.17.0"
jsesc: "npm:^2.5.1"
source-map: "npm:^0.5.0"
checksum: 10c0/8088453c4418e0ee6528506fbd5847bbdfd56327a0025ca9496a259261e162c594ffd08be0d63e74c32feced795616772f38acc5f5e493a86a45fd439fd9feb0
languageName: node
linkType: hard
"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.25.9, @babel/generator@npm:^7.26.0":
"@babel/generator@npm:^7.25.9, @babel/generator@npm:^7.26.0":
version: 7.26.2
resolution: "@babel/generator@npm:7.26.2"
dependencies:
@@ -98,6 +87,19 @@ __metadata:
languageName: node
linkType: hard
"@babel/generator@npm:^7.26.2":
version: 7.26.3
resolution: "@babel/generator@npm:7.26.3"
dependencies:
"@babel/parser": "npm:^7.26.3"
"@babel/types": "npm:^7.26.3"
"@jridgewell/gen-mapping": "npm:^0.3.5"
"@jridgewell/trace-mapping": "npm:^0.3.25"
jsesc: "npm:^3.0.2"
checksum: 10c0/54f260558e3e4ec8942da3cde607c35349bb983c3a7c5121243f96893fba3e8cd62e1f1773b2051f936f8c8a10987b758d5c7d76dbf2784e95bb63ab4843fa00
languageName: node
linkType: hard
"@babel/helper-annotate-as-pure@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/helper-annotate-as-pure@npm:7.25.9"
@@ -120,34 +122,6 @@ __metadata:
languageName: node
linkType: hard
"@babel/helper-environment-visitor@npm:^7.22.20":
version: 7.24.7
resolution: "@babel/helper-environment-visitor@npm:7.24.7"
dependencies:
"@babel/types": "npm:^7.24.7"
checksum: 10c0/36ece78882b5960e2d26abf13cf15ff5689bf7c325b10a2895a74a499e712de0d305f8d78bb382dd3c05cfba7e47ec98fe28aab5674243e0625cd38438dd0b2d
languageName: node
linkType: hard
"@babel/helper-function-name@npm:^7.23.0":
version: 7.24.7
resolution: "@babel/helper-function-name@npm:7.24.7"
dependencies:
"@babel/template": "npm:^7.24.7"
"@babel/types": "npm:^7.24.7"
checksum: 10c0/e5e41e6cf86bd0f8bf272cbb6e7c5ee0f3e9660414174435a46653efba4f2479ce03ce04abff2aa2ef9359cf057c79c06cb7b134a565ad9c0e8a50dcdc3b43c4
languageName: node
linkType: hard
"@babel/helper-hoist-variables@npm:^7.22.5":
version: 7.24.7
resolution: "@babel/helper-hoist-variables@npm:7.24.7"
dependencies:
"@babel/types": "npm:^7.24.7"
checksum: 10c0/19ee37563bbd1219f9d98991ad0e9abef77803ee5945fd85aa7aa62a67c69efca9a801696a1b58dda27f211e878b3327789e6fd2a6f6c725ccefe36774b5ce95
languageName: node
linkType: hard
"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/helper-module-imports@npm:7.25.9"
@@ -178,15 +152,6 @@ __metadata:
languageName: node
linkType: hard
"@babel/helper-split-export-declaration@npm:^7.22.6":
version: 7.24.7
resolution: "@babel/helper-split-export-declaration@npm:7.24.7"
dependencies:
"@babel/types": "npm:^7.24.7"
checksum: 10c0/0254577d7086bf09b01bbde98f731d4fcf4b7c3fa9634fdb87929801307c1f6202a1352e3faa5492450fa8da4420542d44de604daf540704ff349594a78184f6
languageName: node
linkType: hard
"@babel/helper-string-parser@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/helper-string-parser@npm:7.25.9"
@@ -194,7 +159,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/helper-validator-identifier@npm:^7.16.7, @babel/helper-validator-identifier@npm:^7.25.9":
"@babel/helper-validator-identifier@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/helper-validator-identifier@npm:7.25.9"
checksum: 10c0/4fc6f830177b7b7e887ad3277ddb3b91d81e6c4a24151540d9d1023e8dc6b1c0505f0f0628ae653601eb4388a8db45c1c14b2c07a9173837aef7e4116456259d
@@ -218,7 +183,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/parser@npm:^7.20.5, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.2":
"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.2":
version: 7.26.2
resolution: "@babel/parser@npm:7.26.2"
dependencies:
@@ -229,6 +194,17 @@ __metadata:
languageName: node
linkType: hard
"@babel/parser@npm:^7.26.3":
version: 7.26.3
resolution: "@babel/parser@npm:7.26.3"
dependencies:
"@babel/types": "npm:^7.26.3"
bin:
parser: ./bin/babel-parser.js
checksum: 10c0/48f736374e61cfd10ddbf7b80678514ae1f16d0e88bc793d2b505d73d9b987ea786fc8c2f7ee8f8b8c467df062030eb07fd0eb2168f0f541ca1f542775852cad
languageName: node
linkType: hard
"@babel/plugin-syntax-jsx@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/plugin-syntax-jsx@npm:7.25.9"
@@ -275,7 +251,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.9":
"@babel/template@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/template@npm:7.25.9"
dependencies:
@@ -286,24 +262,6 @@ __metadata:
languageName: node
linkType: hard
"@babel/traverse@npm:7.23.2":
version: 7.23.2
resolution: "@babel/traverse@npm:7.23.2"
dependencies:
"@babel/code-frame": "npm:^7.22.13"
"@babel/generator": "npm:^7.23.0"
"@babel/helper-environment-visitor": "npm:^7.22.20"
"@babel/helper-function-name": "npm:^7.23.0"
"@babel/helper-hoist-variables": "npm:^7.22.5"
"@babel/helper-split-export-declaration": "npm:^7.22.6"
"@babel/parser": "npm:^7.23.0"
"@babel/types": "npm:^7.23.0"
debug: "npm:^4.1.0"
globals: "npm:^11.1.0"
checksum: 10c0/d096c7c4bab9262a2f658298a3c630ae4a15a10755bb257ae91d5ab3e3b2877438934859c8d34018b7727379fe6b26c4fa2efc81cf4c462a7fe00caf79fa02ff
languageName: node
linkType: hard
"@babel/traverse@npm:^7.25.9":
version: 7.25.9
resolution: "@babel/traverse@npm:7.25.9"
@@ -319,17 +277,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/types@npm:7.17.0":
version: 7.17.0
resolution: "@babel/types@npm:7.17.0"
dependencies:
"@babel/helper-validator-identifier": "npm:^7.16.7"
to-fast-properties: "npm:^2.0.0"
checksum: 10c0/ad09224272b40fedb00b262677d12b6838f5b5df5c47d67059ba1181bd4805439993393a8de32459dae137b536d60ebfcaf39ae84d8b3873f1e81cc75f5aeae8
languageName: node
linkType: hard
"@babel/types@npm:^7.17.0, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0":
"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0":
version: 7.26.0
resolution: "@babel/types@npm:7.26.0"
dependencies:
@@ -339,6 +287,16 @@ __metadata:
languageName: node
linkType: hard
"@babel/types@npm:^7.26.3":
version: 7.26.3
resolution: "@babel/types@npm:7.26.3"
dependencies:
"@babel/helper-string-parser": "npm:^7.25.9"
"@babel/helper-validator-identifier": "npm:^7.25.9"
checksum: 10c0/966c5242c5e55c8704bf7a7418e7be2703a0afa4d19a8480999d5a4ef13d095dd60686615fe5983cb7593b4b06ba3a7de8d6ca501c1d78bdd233a10d90be787b
languageName: node
linkType: hard
"@emotion/babel-plugin@npm:^11.13.5":
version: 11.13.5
resolution: "@emotion/babel-plugin@npm:11.13.5"
@@ -1291,23 +1249,29 @@ __metadata:
languageName: node
linkType: hard
"@trivago/prettier-plugin-sort-imports@npm:^4.3.0":
version: 4.3.0
resolution: "@trivago/prettier-plugin-sort-imports@npm:4.3.0"
"@trivago/prettier-plugin-sort-imports@npm:^5.0.1":
version: 5.0.1
resolution: "@trivago/prettier-plugin-sort-imports@npm:5.0.1"
dependencies:
"@babel/generator": "npm:7.17.7"
"@babel/parser": "npm:^7.20.5"
"@babel/traverse": "npm:7.23.2"
"@babel/types": "npm:7.17.0"
javascript-natural-sort: "npm:0.7.1"
"@babel/generator": "npm:^7.26.2"
"@babel/parser": "npm:^7.26.2"
"@babel/traverse": "npm:^7.25.9"
"@babel/types": "npm:^7.26.0"
javascript-natural-sort: "npm:^0.7.1"
lodash: "npm:^4.17.21"
peerDependencies:
"@vue/compiler-sfc": 3.x
prettier: 2.x - 3.x
prettier-plugin-svelte: 3.x
svelte: 4.x
peerDependenciesMeta:
"@vue/compiler-sfc":
optional: true
checksum: 10c0/42270fb9c89e54a3f8b6ac8c43e6d0e03350e2857e902cdad4de22c78ef1864da600525595311bc7e94e51c16c7dd3882c2e048a162fdab59761ffa893756aa2
prettier-plugin-svelte:
optional: true
svelte:
optional: true
checksum: 10c0/2256a2ff06f1809f52e37d609ed04cdb5253f3ee83e959dfff301f4e6f3295cdd4adb5015d5a1ac40ff934f6bde9c0c2bd1e84ee7c0d65e5b755c4ce739bfe08
languageName: node
linkType: hard
@@ -1661,7 +1625,7 @@ __metadata:
"@preact/compat": "npm:^18.3.1"
"@preact/preset-vite": "npm:^2.9.2"
"@table-library/react-table-library": "npm:4.1.7"
"@trivago/prettier-plugin-sort-imports": "npm:^4.3.0"
"@trivago/prettier-plugin-sort-imports": "npm:^5.0.1"
"@types/formidable": "npm:^3"
"@types/node": "npm:^22.10.1"
"@types/react": "npm:^18.3.13"
@@ -1676,17 +1640,17 @@ __metadata:
mime-types: "npm:^2.1.35"
preact: "npm:^10.25.1"
prettier: "npm:^3.4.2"
react: "npm:^18.3.1"
react-dom: "npm:^18.3.1"
react: "npm:^19.0.0"
react-dom: "npm:^19.0.0"
react-icons: "npm:^5.4.0"
react-router: "npm:^7.0.2"
react-toastify: "npm:^10.0.6"
rollup-plugin-visualizer: "npm:^5.12.0"
terser: "npm:^5.36.0"
terser: "npm:^5.37.0"
typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.7.2"
typescript-eslint: "npm:8.17.0"
vite: "npm:^6.0.2"
vite: "npm:^6.0.3"
vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^5.1.3"
languageName: unknown
@@ -4430,7 +4394,7 @@ __metadata:
languageName: node
linkType: hard
"javascript-natural-sort@npm:0.7.1":
"javascript-natural-sort@npm:^0.7.1":
version: 0.7.1
resolution: "javascript-natural-sort@npm:0.7.1"
checksum: 10c0/340f8ffc5d30fb516e06dc540e8fa9e0b93c865cf49d791fed3eac3bdc5fc71f0066fc81d44ec1433edc87caecaf9f13eec4a1fce8c5beafc709a71eaedae6fe
@@ -4487,15 +4451,6 @@ __metadata:
languageName: node
linkType: hard
"jsesc@npm:^2.5.1":
version: 2.5.2
resolution: "jsesc@npm:2.5.2"
bin:
jsesc: bin/jsesc
checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88
languageName: node
linkType: hard
"jsesc@npm:^3.0.2":
version: 3.0.2
resolution: "jsesc@npm:3.0.2"
@@ -4671,7 +4626,7 @@ __metadata:
languageName: node
linkType: hard
"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
"loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
@@ -5688,15 +5643,14 @@ __metadata:
languageName: node
linkType: hard
"react-dom@npm:^18.3.1":
version: 18.3.1
resolution: "react-dom@npm:18.3.1"
"react-dom@npm:^19.0.0":
version: 19.0.0
resolution: "react-dom@npm:19.0.0"
dependencies:
loose-envify: "npm:^1.1.0"
scheduler: "npm:^0.23.2"
scheduler: "npm:^0.25.0"
peerDependencies:
react: ^18.3.1
checksum: 10c0/a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85
react: ^19.0.0
checksum: 10c0/a36ce7ab507b237ae2759c984cdaad4af4096d8199fb65b3815c16825e5cfeb7293da790a3fc2184b52bfba7ba3ff31c058c01947aff6fd1a3701632aabaa6a9
languageName: node
linkType: hard
@@ -5791,12 +5745,10 @@ __metadata:
languageName: node
linkType: hard
"react@npm:^18.3.1":
version: 18.3.1
resolution: "react@npm:18.3.1"
dependencies:
loose-envify: "npm:^1.1.0"
checksum: 10c0/283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3
"react@npm:^19.0.0":
version: 19.0.0
resolution: "react@npm:19.0.0"
checksum: 10c0/9cad8f103e8e3a16d15cb18a0d8115d8bd9f9e1ce3420310aea381eb42aa0a4f812cf047bb5441349257a05fba8a291515691e3cb51267279b2d2c3253f38471
languageName: node
linkType: hard
@@ -6070,12 +6022,10 @@ __metadata:
languageName: node
linkType: hard
"scheduler@npm:^0.23.2":
version: 0.23.2
resolution: "scheduler@npm:0.23.2"
dependencies:
loose-envify: "npm:^1.1.0"
checksum: 10c0/26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78
"scheduler@npm:^0.25.0":
version: 0.25.0
resolution: "scheduler@npm:0.25.0"
checksum: 10c0/a4bb1da406b613ce72c1299db43759526058fdcc413999c3c3e0db8956df7633acf395cb20eb2303b6a65d658d66b6585d344460abaee8080b4aa931f10eaafe
languageName: node
linkType: hard
@@ -6273,7 +6223,7 @@ __metadata:
languageName: node
linkType: hard
"source-map@npm:^0.5.0, source-map@npm:^0.5.7":
"source-map@npm:^0.5.7":
version: 0.5.7
resolution: "source-map@npm:0.5.7"
checksum: 10c0/904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599
@@ -6602,9 +6552,9 @@ __metadata:
languageName: node
linkType: hard
"terser@npm:^5.36.0":
version: 5.36.0
resolution: "terser@npm:5.36.0"
"terser@npm:^5.37.0":
version: 5.37.0
resolution: "terser@npm:5.37.0"
dependencies:
"@jridgewell/source-map": "npm:^0.3.3"
acorn: "npm:^8.8.2"
@@ -6612,7 +6562,7 @@ __metadata:
source-map-support: "npm:~0.5.20"
bin:
terser: bin/terser
checksum: 10c0/f4ed2bead19f64789ddcfb85b7cef78f3942f967b8890c54f57d1e35bc7d547d551c6a4c32210bce6ba45b1c738314bbfac6acbc6c762a45cd171777d0c120d9
checksum: 10c0/ff0dc79b0a0da821e7f5bf7a047eab6d04e70e88b62339a0f1d71117db3310e255f5c00738fa3b391f56c3571f800a00047720261ba04ced0241c1f9922199f4
languageName: node
linkType: hard
@@ -6637,13 +6587,6 @@ __metadata:
languageName: node
linkType: hard
"to-fast-properties@npm:^2.0.0":
version: 2.0.0
resolution: "to-fast-properties@npm:2.0.0"
checksum: 10c0/b214d21dbfb4bce3452b6244b336806ffea9c05297148d32ebb428d5c43ce7545bdfc65a1ceb58c9ef4376a65c0cb2854d645f33961658b3e3b4f84910ddcdd7
languageName: node
linkType: hard
"to-regex-range@npm:^5.0.1":
version: 5.0.1
resolution: "to-regex-range@npm:5.0.1"
@@ -6952,9 +6895,9 @@ __metadata:
languageName: node
linkType: hard
"vite@npm:^6.0.2":
version: 6.0.2
resolution: "vite@npm:6.0.2"
"vite@npm:^6.0.3":
version: 6.0.3
resolution: "vite@npm:6.0.3"
dependencies:
esbuild: "npm:^0.24.0"
fsevents: "npm:~2.3.3"
@@ -7000,7 +6943,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 10c0/45fc609f2bc5fb5beb5a8e2cad9ad6c2edce229a922f6fc1270ea2a9d75819482edcc0f77c85b4a7abdad7eb69ce6a4f26131925d47cdc0778fc15d1bbc3b6a2
checksum: 10c0/764ebed14770426a638575b23a51127c630ace873999ab896b0184484d8107e7255cdf64cfb36c65c1ef1d583e44b70a1d14c0f05b89612e834a5806e3964475
languageName: node
linkType: hard

View File

@@ -56,7 +56,7 @@ void WebCustomEntity::read(WebCustomEntity & webEntity, JsonObject root) {
ei["offset"] = entityItem.offset;
ei["factor"] = entityItem.factor;
ei["name"] = entityItem.name;
ei["uom"] = entityItem.uom;
ei["uom"] = entityItem.value_type == DeviceValueType::BOOL ? 0 : entityItem.uom;
ei["value_type"] = entityItem.value_type;
ei["writeable"] = entityItem.writeable;
EMSESP::webCustomEntityService.render_value(ei, entityItem, true, true);
@@ -97,7 +97,6 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
if (entityItem.ram == 1) {
entityItem.device_id = 0;
entityItem.type_id = 0;
entityItem.uom = 0;
entityItem.value_type = DeviceValueType::STRING;
entityItem.writeable = true;
}
@@ -107,6 +106,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
entityItem.data = "";
} else if (entityItem.value_type == DeviceValueType::BOOL) {
entityItem.value = EMS_VALUE_DEFAULT_BOOL;
entityItem.uom = 0;
} else if (entityItem.value_type == DeviceValueType::INT8) {
entityItem.value = EMS_VALUE_DEFAULT_INT8;
} else if (entityItem.value_type == DeviceValueType::UINT8) {
@@ -180,7 +180,7 @@ bool WebCustomEntityService::command_setvalue(const char * value, const int8_t i
if (!Helpers::value2bool(value, v)) {
return false;
}
EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v ? 0xFF : 0, 0);
EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v ? (uint8_t)entityItem.factor : 0, 0);
} else {
float f;
if (!Helpers::value2float(value, f)) {
@@ -266,7 +266,7 @@ void WebCustomEntityService::render_value(JsonObject output, CustomEntityItem &
default:
// if no type treat it as a string
if (entity.data.length() > 0) {
output[name] = entity.data;
output[name] = add_uom ? entity.data + ' ' + EMSdevice::uom_to_string(entity.uom) : entity.data;
}
break;
}
@@ -490,7 +490,9 @@ void WebCustomEntityService::generate_value_web(JsonObject output, const bool is
}
obj["id"] = "00" + entity.name;
if (entity.value_type != DeviceValueType::BOOL) {
obj["u"] = entity.uom;
}
if (entity.writeable) {
obj["c"] = entity.name;
@@ -630,6 +632,10 @@ bool WebCustomEntityService::get_value(std::shared_ptr<const Telegram> telegram)
for (uint8_t i = 0; i < len[entity.value_type]; i++) {
value = (value << 8) + telegram->message_data[i + entity.offset - telegram->offset];
}
// mask bits for bool values
if (entity.value_type == DeviceValueType::BOOL && entity.factor > 0) {
value = (value & (uint8_t)entity.factor) ? 1 : 0;
}
if (value != entity.value) {
entity.value = value;
if (Mqtt::publish_single()) {