Merge branch 'ft_dashboard' of https://github.com/proddy/EMS-ESP32 into ft_dashboard

This commit is contained in:
MichaelDvP
2024-10-12 09:34:34 +02:00
6 changed files with 126 additions and 87 deletions

View File

@@ -35,7 +35,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-router-dom": "^6.26.2",
"react-router-dom": "^6.27.0",
"react-toastify": "^10.0.5",
"typesafe-i18n": "^5.26.2",
"typescript": "^5.6.3"
@@ -49,7 +49,7 @@
"@types/formidable": "^3",
"@types/node": "^22.7.5",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@types/react-dom": "^18.3.1",
"@types/react-router-dom": "^5.3.3",
"concurrently": "^9.0.1",
"eslint": "^9.12.0",

View File

@@ -25,7 +25,7 @@ const App = () => {
<CustomTheme>
<AppRouting />
<ToastContainer
position="bottom-right"
position="bottom-left"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}

View File

@@ -88,28 +88,38 @@ const Dashboard = () => {
const dashboard_theme = useTheme({
Table: `
--data-table-library_grid-template-columns: minmax(80px, auto) 120px 40px;
--data-table-library_grid-template-columns: minmax(80px, auto) 120px 32px;
`,
BaseRow: `
font-size: 14px;
.td {
height: 32px;
height: 28px;
}
`,
Row: `
cursor: pointer;
background-color: #1e1e1e;
.td {
height: 22px;
// border-top: 1px solid #0000;
// border-bottom: 1px solid #0000;
}
&.tr.tr-body.row-select.row-select-single-selected {
background-color: #177ac9;
font-weight: normal;
}
&:hover .td {
border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9;
background-color: #177ac9;
// border-top: 1px solid #177ac9;
// border-bottom: 1px solid #177ac9;
}
`,
BaseCell: `
&:nth-of-type(2) {
text-align: right;
}
&:nth-of-type(3) {
text-align: right;
}
`
});
@@ -164,9 +174,9 @@ const Dashboard = () => {
case DeviceType.CUSTOM:
return LL.CUSTOM_ENTITIES(0);
case DeviceType.ANALOGSENSOR:
return LL.ANALOG_SENSOR(0);
return LL.ANALOG_SENSORS();
case DeviceType.TEMPERATURESENSOR:
return LL.TEMP_SENSOR();
return LL.TEMP_SENSORS();
case DeviceType.SCHEDULER:
return LL.SCHEDULER();
default:
@@ -200,8 +210,10 @@ const Dashboard = () => {
(parseInt(id.slice(0, 2), 16) & mask) === mask;
const editDashboardValue = (di: DashboardItem) => {
setSelectedDashboardItem(di);
setDeviceValueDialogOpen(true);
if (me.admin && di.dv?.c) {
setSelectedDashboardItem(di);
setDeviceValueDialogOpen(true);
}
};
const handleShowAll = (
@@ -276,7 +288,11 @@ const Dashboard = () => {
{(tableList: DashboardItem[]) => (
<Body>
{tableList.map((di: DashboardItem) => (
<Row key={di.id} item={di}>
<Row
key={di.id}
item={di}
onClick={() => editDashboardValue(di)}
>
{di.id > 99 ? (
<>
<Cell>{showName(di)}</Cell>
@@ -294,7 +310,7 @@ const Dashboard = () => {
</Tooltip>
</Cell>
<Cell stiff pinRight>
<Cell>
{me.admin &&
di.dv?.c &&
!hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && (

View File

@@ -148,22 +148,23 @@ const Devices = () => {
}
`,
Row: `
background-color: #1E1E1E;
position: relative;
cursor: pointer;
background-color: #1E1E1E;
// position: relative;
.td {
padding: 8px;
border-top: 1px solid #565656;
border-bottom: 1px solid #565656;
// border-top: 1px solid #565656;
// border-bottom: 1px solid #565656;
}
&.tr.tr-body.row-select.row-select-single-selected {
background-color: #3d4752;
background-color: #177ac9;
font-weight: normal;
}
&:hover .td {
border-top: 1px solid #177ac9;
border-bottom: 1px solid #177ac9;
}
// &:hover .td {
// background-color: #177ac9;
// border-top: 1px solid #177ac9;
// border-bottom: 1px solid #177ac9;
// }
`
});
@@ -174,14 +175,18 @@ const Devices = () => {
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 130px;
`,
BaseRow: `
.td {
height: 42px;
}
// .td {
// height: 42px;
// }
`,
HeaderRow: `
.th {
padding: 8px;
height: 36px;
`,
Row: `
&:hover .td {
background-color: #177ac9;
`
}
]);
@@ -222,7 +227,12 @@ const Devices = () => {
Row: `
&:nth-of-type(odd) .td {
background-color: #303030;
}
},
&:hover .td {
background-color: #177ac9;
// border-top: 1px solid #177ac9;
// border-bottom: 1px solid #177ac9;
}
`
}
]);

View File

@@ -1360,10 +1360,10 @@ __metadata:
languageName: node
linkType: hard
"@remix-run/router@npm:1.19.2":
version: 1.19.2
resolution: "@remix-run/router@npm:1.19.2"
checksum: 10c0/ac7fc813350686705f2c29219e70e1e299d9a8e3b301e9e81f7e84f578c40c6462b590cf0d78863bac40dbc325b68c71ae070f4a1465793d1d1971b619618295
"@remix-run/router@npm:1.20.0":
version: 1.20.0
resolution: "@remix-run/router@npm:1.20.0"
checksum: 10c0/2e017dea530717a6e93a16d478714c4c9165313a1c48e39172ec609bc20324ca6362e8ee2243602df6343644c9268d82a3f50f154d3bb8a17dddde6c37be6e83
languageName: node
linkType: hard
@@ -1699,12 +1699,12 @@ __metadata:
languageName: node
linkType: hard
"@types/react-dom@npm:^18.3.0":
version: 18.3.0
resolution: "@types/react-dom@npm:18.3.0"
"@types/react-dom@npm:^18.3.1":
version: 18.3.1
resolution: "@types/react-dom@npm:18.3.1"
dependencies:
"@types/react": "npm:*"
checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b
checksum: 10c0/8b416551c60bb6bd8ec10e198c957910cfb271bc3922463040b0d57cf4739cdcd24b13224f8d68f10318926e1ec3cd69af0af79f0291b599a992f8c80d47f1eb
languageName: node
linkType: hard
@@ -1910,7 +1910,7 @@ __metadata:
"@types/formidable": "npm:^3"
"@types/node": "npm:^22.7.5"
"@types/react": "npm:^18.3.11"
"@types/react-dom": "npm:^18.3.0"
"@types/react-dom": "npm:^18.3.1"
"@types/react-router-dom": "npm:^5.3.3"
alova: "npm:3.0.20"
async-validator: "npm:^4.2.5"
@@ -1925,7 +1925,7 @@ __metadata:
react: "npm:^18.3.1"
react-dom: "npm:^18.3.1"
react-icons: "npm:^5.3.0"
react-router-dom: "npm:^6.26.2"
react-router-dom: "npm:^6.27.0"
react-toastify: "npm:^10.0.5"
rollup-plugin-visualizer: "npm:^5.12.0"
terser: "npm:^5.34.1"
@@ -6003,27 +6003,27 @@ __metadata:
languageName: node
linkType: hard
"react-router-dom@npm:^6.26.2":
version: 6.26.2
resolution: "react-router-dom@npm:6.26.2"
"react-router-dom@npm:^6.27.0":
version: 6.27.0
resolution: "react-router-dom@npm:6.27.0"
dependencies:
"@remix-run/router": "npm:1.19.2"
react-router: "npm:6.26.2"
"@remix-run/router": "npm:1.20.0"
react-router: "npm:6.27.0"
peerDependencies:
react: ">=16.8"
react-dom: ">=16.8"
checksum: 10c0/7515128a98eef0a6b2bf354ef9dfefad03556a06be00fa9220eda6526aaada8a42f294911083473d7ced6d7128c3088bd193218bbb3d62593f9f4f7053781c23
checksum: 10c0/7db48ffd0b387af0eed060ceaf42075d074e63fbd30f4cf60993526b3610883a9ff82615965001165ed69d2bf2f1bce05c594a21c8d0d845e7b9bf203201116e
languageName: node
linkType: hard
"react-router@npm:6.26.2":
version: 6.26.2
resolution: "react-router@npm:6.26.2"
"react-router@npm:6.27.0":
version: 6.27.0
resolution: "react-router@npm:6.27.0"
dependencies:
"@remix-run/router": "npm:1.19.2"
"@remix-run/router": "npm:1.20.0"
peerDependencies:
react: ">=16.8"
checksum: 10c0/0d15a39b419c99fb5ccad76388bfc4ee2b01323b3b1b694595a9f9ea28e1fbeea25486b5398f5d3d93922f5c6a9aa751b6bb27419488d85279f6ca5ff9e0a6bb
checksum: 10c0/440d6ee00890cec92a0c2183164149fbb96363efccf52bb132a964f44e51aec2f4b5a0520c67f6f17faddaa4097090fd76f7efe58263947532fceeb11dd4cdf3
languageName: node
linkType: hard

View File

@@ -4351,7 +4351,6 @@ router
t: element.t,
nodes: getDashboardEntityData(id)
};
// only add to dashboard if we have values
if ((dashboard_object.nodes ?? []).length > 0) {
dashboard_data.push(dashboard_object);
@@ -4374,7 +4373,7 @@ router
sensor_data = emsesp_sensordata.ts.map((item, index) => ({
id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID * 100 + index,
dv: {
id: item.n,
id: '00' + item.n,
v: item.t, // value is called t in ts (temperature)
u: item.u
}
@@ -4395,12 +4394,11 @@ router
sensor_data = sensor_data.map((item, index) => ({
id: DeviceTypeUniqueID.ANALOGSENSOR_UID * 100 + index,
dv: {
id: item.n,
id: '00' + item.n,
v: item.v,
u: item.u
}
}));
dashboard_object = {
id: DeviceTypeUniqueID.ANALOGSENSOR_UID,
t: DeviceType.ANALOGSENSOR,
@@ -4417,9 +4415,10 @@ router
let scheduler_data2 = scheduler_data.map((item, index) => ({
id: DeviceTypeUniqueID.SCHEDULER_UID * 100 + index,
dv: {
id: item.name,
v: item.active
// u: item.u // don't need uom
id: '00' + item.name,
v: item.active ? 'on' : 'off',
c: item.name,
l: ['off', 'on']
}
}));
dashboard_object = {
@@ -4431,22 +4430,39 @@ router
if ((dashboard_object.nodes ?? []).length > 0) {
dashboard_data.push(dashboard_object);
}
//
} else {
// for testing
// single object
const element = emsesp_coredata.devices[3]; // pick the 4th device
const id = element.id;
// for testing only
// add the custom entity data
dashboard_object = {
id: id,
n: element.n,
t: element.t,
nodes: getDashboardEntityData(id)
id: DeviceTypeUniqueID.CUSTOM_UID, // unique ID for custom entities
t: DeviceType.CUSTOM,
nodes: getDashboardEntityData(99)
};
// only add to dashboard if we have values
if ((dashboard_object.nodes ?? []).length > 0) {
dashboard_data.push(dashboard_object);
}
let scheduler_data = emsesp_schedule.schedule.filter((item) => item.name);
let scheduler_data2 = scheduler_data.map((item, index) => ({
id: DeviceTypeUniqueID.SCHEDULER_UID * 100 + index,
dv: {
id: '00' + item.name,
v: item.active ? 'on' : 'off',
c: item.name,
l: ['off', 'on']
}
}));
dashboard_object = {
id: DeviceTypeUniqueID.SCHEDULER_UID,
t: DeviceType.SCHEDULER,
nodes: scheduler_data2
};
// only add to dashboard if we have values
if ((dashboard_object.nodes ?? []).length > 0) {
dashboard_data.push(dashboard_object);
}
console.log('dashboard_data: ', dashboard_data);
}
// console.log('dashboard_data: ', dashboard_data);
@@ -4498,24 +4514,6 @@ router
// Scheduler
.post(EMSESP_SCHEDULE_ENDPOINT, async (request: any) => {
const content = await request.json();
// check if we're changing active from the Dashboard
if (content.schedule.id === 0) {
console.log(
"Toggle schedule '" +
content.schedule.name +
"' to " +
content.schedule.active
);
// find the schedule in emsesp_schedule via the name and toggle the active
const objIndex = emsesp_schedule.schedule.findIndex(
(obj) => obj.name === content.schedule.name
);
if (objIndex !== -1) {
emsesp_schedule.schedule[objIndex].active = content.schedule.active;
}
return status(200);
}
emsesp_schedule = content;
console.log('schedule saved', emsesp_schedule);
return status(200);
@@ -4557,6 +4555,10 @@ router
const value = content.v;
const id = content.id;
console.log(
'write device value, id: ' + id + ' command: ' + command + ' value: ' + value
);
var objIndex;
if (id === 1) {
objIndex = emsesp_devicedata_1.nodes.findIndex((obj) => obj.c == command);
@@ -4598,16 +4600,27 @@ router
objIndex = emsesp_devicedata_10.nodes.findIndex((obj) => obj.c == command);
emsesp_devicedata_10.nodes[objIndex].v = value;
}
if (id === 99) {
if (id === DeviceTypeUniqueID.CUSTOM_UID) {
// custom entities
objIndex = emsesp_devicedata_99.nodes.findIndex((obj) => obj.c == command);
emsesp_devicedata_99.nodes[objIndex].v = value;
}
if (id === DeviceTypeUniqueID.SCHEDULER_UID) {
// toggle scheduler
// find the schedule in emsesp_schedule via the name and toggle the active
const objIndex = emsesp_schedule.schedule.findIndex(
(obj) => obj.name === command
);
if (objIndex !== -1) {
emsesp_schedule.schedule[objIndex].active = value;
console.log("Toggle schedule '" + command + "' to " + value);
}
}
// await delay(1000); // wait to show spinner
console.log(
'Device Value updated. command:' + command + ' value:' + value + ' id:' + id
);
// console.log(
// 'Device Value updated. command:' + command + ' value:' + value + ' id:' + id
// );
return status(200);
})