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) - 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) - 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) - 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 ## Fixed

View File

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

View File

@@ -83,7 +83,7 @@ const CustomEntities = () => {
const entity_theme = useTheme({ const entity_theme = useTheme({
Table: ` 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: ` BaseRow: `
font-size: 14px; 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 = () => { const addEntityItem = () => {
setCreating(true); setCreating(true);
setSelectedEntityItem({ setSelectedEntityItem({
@@ -220,7 +239,7 @@ const CustomEntities = () => {
: typeof value === 'number' : typeof value === 'number'
? new Intl.NumberFormat().format(value) + ? new Intl.NumberFormat().format(value) +
(uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]) (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom])
: (value as string); : (value as string) + (uom === 0 ? '' : ' ' + DeviceValueUOM_s[uom]);
} }
function showHex(value: number, digit: number) { function showHex(value: number, digit: number) {
@@ -296,6 +315,7 @@ const CustomEntities = () => {
creating={creating} creating={creating}
onClose={onDialogClose} onClose={onDialogClose}
onSave={onDialogSave} onSave={onDialogSave}
onDup={onDialogDup}
selectedItem={selectedEntityItem} selectedItem={selectedEntityItem}
validator={entityItemValidation(entities, selectedEntityItem)} validator={entityItemValidation(entities, selectedEntityItem)}
/> />

View File

@@ -34,6 +34,7 @@ interface CustomEntitiesDialogProps {
creating: boolean; creating: boolean;
onClose: () => void; onClose: () => void;
onSave: (ei: EntityItem) => void; onSave: (ei: EntityItem) => void;
onDup: (ei: EntityItem) => void;
selectedItem: EntityItem; selectedItem: EntityItem;
validator: Schema; validator: Schema;
} }
@@ -43,6 +44,7 @@ const CustomEntitiesDialog = ({
creating, creating,
onClose, onClose,
onSave, onSave,
onDup,
selectedItem, selectedItem,
validator validator
}: CustomEntitiesDialogProps) => { }: CustomEntitiesDialogProps) => {
@@ -91,6 +93,10 @@ const CustomEntitiesDialog = ({
onSave(editItem); onSave(editItem);
}; };
const dup = () => {
onDup(editItem);
};
return ( return (
<Dialog sx={dialogStyle} open={open} onClose={handleClose}> <Dialog sx={dialogStyle} open={open} onClose={handleClose}>
<DialogTitle> <DialogTitle>
@@ -128,18 +134,36 @@ const CustomEntitiesDialog = ({
</TextField> </TextField>
</Grid> </Grid>
{editItem.ram === 1 && ( {editItem.ram === 1 && (
<Grid> <>
<TextField <Grid>
name="value" <TextField
label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)} name="value"
type="string" label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)}
value={editItem.value as string} type="string"
variant="outlined" value={editItem.value as string}
onChange={updateFormValue} variant="outlined"
fullWidth onChange={updateFormValue}
margin="normal" fullWidth
/> margin="normal"
</Grid> />
</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 && ( {editItem.ram === 0 && (
<> <>
@@ -255,7 +279,7 @@ const CustomEntitiesDialog = ({
<TextField <TextField
name="factor" name="factor"
label={LL.FACTOR()} label={LL.FACTOR()}
value={numberValue(editItem.factor)} value={numberValue(editItem.factor as number)}
variant="outlined" variant="outlined"
onChange={updateFormValue} onChange={updateFormValue}
sx={{ width: '11ch' }} sx={{ width: '11ch' }}
@@ -292,15 +316,41 @@ const CustomEntitiesDialog = ({
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="factor" name="factor"
label="Bytes" label="Bytes"
value={numberValue(editItem.factor)} value={numberValue(editItem.factor as number)}
sx={{ width: '11ch' }} sx={{ width: '11ch' }}
variant="outlined" variant="outlined"
onChange={updateFormValue} onChange={updateFormValue}
margin="normal" margin="normal"
type="number" type="number"
slotProps={{
htmlInput: { step: '1', min: '1', max: '255' }
}}
/> />
</Grid> </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>
)}
</> </>
)} )}
</Grid> </Grid>
@@ -316,6 +366,15 @@ const CustomEntitiesDialog = ({
> >
{LL.REMOVE()} {LL.REMOVE()}
</Button> </Button>
<Button
sx={{ ml: 1 }}
startIcon={<AddIcon />}
variant="outlined"
color="primary"
onClick={dup}
>
{LL.DUPLICATE()}
</Button>
</Box> </Box>
)} )}
<Button <Button

View File

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

View File

@@ -368,7 +368,7 @@ export interface EntityItem {
device_id: number | string; device_id: number | string;
type_id: number | string; type_id: number | string;
offset: number; offset: number;
factor: number; factor: number | string;
uom: number; uom: number;
value_type: number; value_type: number;
value?: unknown; value?: unknown;
@@ -380,7 +380,7 @@ export interface EntityItem {
o_device_id?: number | string; o_device_id?: number | string;
o_type_id?: number | string; o_type_id?: number | string;
o_offset?: number; o_offset?: number;
o_factor?: number; o_factor?: number | string;
o_uom?: number; o_uom?: number;
o_value_type?: number; o_value_type?: number;
o_deleted?: boolean; 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' } { type: 'number', min: 0, max: 255, message: 'Must be between 0 and 255' }
], ],
factor: [ factor: [
{ required: true, message: 'is required' }, { required: true, message: 'is required' }
{ type: 'number', message: 'Must be a number' }
] ]
}); });

View File

@@ -343,6 +343,7 @@ const cz: Translation = {
NO_DATA: 'Žádná data nejsou k dispozici', 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í', 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', DEVELOPER_MODE: 'Režim vývojáře',
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate UPGRADE: 'Upgrade' // TODO translate
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -343,6 +343,7 @@ const sk: Translation = {
NO_DATA: 'Nie sú k dispozícii žiadne údaje', 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', 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 DEVELOPER_MODE: 'Developer Mode', // TODO translate
DUPLICATE: 'Duplicate', // TODO translate
UPGRADE: 'Upgrade' // TODO translate UPGRADE: 'Upgrade' // TODO translate
}; };

View File

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

View File

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

View File

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

View File

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