mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
link to device entity details from customization page
This commit is contained in:
@@ -13,7 +13,8 @@ import {
|
||||
ToggleButtonGroup,
|
||||
Tooltip,
|
||||
Grid,
|
||||
TextField
|
||||
TextField,
|
||||
Link
|
||||
} from '@mui/material';
|
||||
|
||||
import { Table } from '@table-library/react-table-library/table';
|
||||
@@ -26,11 +27,6 @@ import { useSnackbar } from 'notistack';
|
||||
import SaveIcon from '@mui/icons-material/Save';
|
||||
import CancelIcon from '@mui/icons-material/Cancel';
|
||||
|
||||
// import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
|
||||
// import StarIcon from '@mui/icons-material/Star';
|
||||
// import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
|
||||
// import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
|
||||
|
||||
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
|
||||
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
|
||||
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
|
||||
@@ -48,13 +44,15 @@ import { extractErrorMessage } from '../utils';
|
||||
|
||||
import { DeviceShort, Devices, DeviceEntity, DeviceEntityMask } from './types';
|
||||
|
||||
export const APIURL = window.location.origin + '/api/';
|
||||
|
||||
const SettingsCustomization: FC = () => {
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([{ id: '', v: 0, n: '', m: 0, w: false }]);
|
||||
const [devices, setDevices] = useState<Devices>();
|
||||
const [errorMessage, setErrorMessage] = useState<string>();
|
||||
const [selectedDevice, setSelectedDevice] = useState<number>(0);
|
||||
const [selectedDevice, setSelectedDevice] = useState<number>(-1);
|
||||
const [confirmReset, setConfirmReset] = useState<boolean>(false);
|
||||
const [selectedFilters, setSelectedFilters] = useState<number>(0);
|
||||
const [search, setSearch] = useState('');
|
||||
@@ -94,7 +92,6 @@ const SettingsCustomization: FC = () => {
|
||||
Row: `
|
||||
background-color: #1e1e1e;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
.td {
|
||||
border-top: 1px solid #565656;
|
||||
@@ -107,11 +104,6 @@ const SettingsCustomization: FC = () => {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
&:hover .td {
|
||||
border-top: 1px solid #177ac9;
|
||||
border-bottom: 1px solid #177ac9;
|
||||
}
|
||||
|
||||
&:nth-of-type(odd) .td {
|
||||
background-color: #303030;
|
||||
}
|
||||
@@ -194,7 +186,15 @@ const SettingsCustomization: FC = () => {
|
||||
} else if (de.n === '') {
|
||||
return 'Command: ' + de.id;
|
||||
}
|
||||
return de.n + ' (' + de.id + ')';
|
||||
return (
|
||||
<>
|
||||
{de.n} (
|
||||
<Link target="_blank" href={APIURL + devices?.devices[selectedDevice].t + '/' + de.id}>
|
||||
{de.id}
|
||||
</Link>
|
||||
)
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const getMaskNumber = (newMask: string[]) => {
|
||||
@@ -239,20 +239,12 @@ const SettingsCustomization: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
function compareDevices(a: DeviceShort, b: DeviceShort) {
|
||||
if (a.s < b.s) {
|
||||
return -1;
|
||||
}
|
||||
if (a.s > b.s) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const changeSelectedDevice = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (devices) {
|
||||
const selected_device = parseInt(event.target.value, 10);
|
||||
setSelectedDevice(selected_device);
|
||||
fetchDeviceEntities(selected_device);
|
||||
fetchDeviceEntities(devices?.devices[selected_device].i);
|
||||
}
|
||||
};
|
||||
|
||||
const resetCustomization = async () => {
|
||||
@@ -267,7 +259,7 @@ const SettingsCustomization: FC = () => {
|
||||
};
|
||||
|
||||
const saveCustomization = async () => {
|
||||
if (deviceEntities && selectedDevice) {
|
||||
if (devices && deviceEntities && selectedDevice !== -1) {
|
||||
const masked_entities = deviceEntities
|
||||
.filter((de) => de.m !== de.om)
|
||||
.map((new_de) => new_de.m.toString(16).padStart(2, '0') + new_de.id);
|
||||
@@ -279,7 +271,7 @@ const SettingsCustomization: FC = () => {
|
||||
|
||||
try {
|
||||
const response = await EMSESP.writeMaskedEntities({
|
||||
id: selectedDevice,
|
||||
id: devices?.devices[selectedDevice].i,
|
||||
entity_ids: masked_entities
|
||||
});
|
||||
if (response.status === 200) {
|
||||
@@ -305,13 +297,13 @@ const SettingsCustomization: FC = () => {
|
||||
<Typography variant="body2">Select a device and customize each of its entities using the options:</Typography>
|
||||
<Typography variant="body2">
|
||||
<OptionIcon type="favorite" isSet={true} />
|
||||
=mark as a favorite
|
||||
=mark as favorite
|
||||
<OptionIcon type="readonly" isSet={true} />
|
||||
=disable write action
|
||||
<OptionIcon type="api_mqtt_exclude" isSet={true} />
|
||||
=exclude from MQTT and API outputs
|
||||
=exclude from MQTT and API
|
||||
<OptionIcon type="web_exclude" isSet={true} />
|
||||
=hide from Web Dashboard
|
||||
=hide from Dashboard
|
||||
</Typography>
|
||||
</Box>
|
||||
<ValidatedTextField
|
||||
@@ -324,11 +316,11 @@ const SettingsCustomization: FC = () => {
|
||||
margin="normal"
|
||||
select
|
||||
>
|
||||
<MenuItem disabled key={0} value={0}>
|
||||
<MenuItem disabled key={0} value={-1}>
|
||||
Select a device...
|
||||
</MenuItem>
|
||||
{devices.devices.sort(compareDevices).map((device: DeviceShort, index) => (
|
||||
<MenuItem key={index} value={device.i}>
|
||||
{devices.devices.map((device: DeviceShort, index) => (
|
||||
<MenuItem key={index} value={index}>
|
||||
{device.s}
|
||||
</MenuItem>
|
||||
))}
|
||||
|
||||
@@ -104,9 +104,10 @@ export interface CoreData {
|
||||
|
||||
export interface DeviceShort {
|
||||
i: number; // id
|
||||
d: number; // deviceid
|
||||
p: number; // productid
|
||||
d?: number; // deviceid
|
||||
p?: number; // productid
|
||||
s: string; // shortname
|
||||
t?: string; // device type name
|
||||
}
|
||||
|
||||
export interface Devices {
|
||||
|
||||
@@ -347,18 +347,21 @@ const emsesp_devices = {
|
||||
d: 23,
|
||||
p: 77,
|
||||
s: 'Thermostat (RC20/Moduline 300)',
|
||||
t: 'thermostat1',
|
||||
},
|
||||
{
|
||||
i: 2,
|
||||
d: 8,
|
||||
p: 123,
|
||||
s: 'Boiler (Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i)',
|
||||
t: 'boiler',
|
||||
},
|
||||
{
|
||||
i: 4,
|
||||
d: 16,
|
||||
p: 165,
|
||||
s: 'Thermostat (RC100/Moduline 1000/1010)',
|
||||
t: 'thermostat2',
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1224,8 +1227,8 @@ rest_server.get(GET_CUSTOMIZATIONS_ENDPOINT, (req, res) => {
|
||||
|
||||
// start server
|
||||
const expressServer = rest_server.listen(port, () =>
|
||||
console.log(`EMS-ESP REST API server running on http://localhost:${port}/api`),
|
||||
)
|
||||
console.log(`EMS-ESP Rest API listening to http://localhost:${port}/api`)
|
||||
|
||||
// start websocket server
|
||||
const websocketServer = new WebSocket.Server({
|
||||
|
||||
@@ -165,22 +165,23 @@ void WebCustomizationService::devices(AsyncWebServerRequest * request) {
|
||||
auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_LARGE_DYN);
|
||||
JsonObject root = response->getRoot();
|
||||
|
||||
// list is already sorted by device type
|
||||
// controller is ignored since it doesn't have any associated entities
|
||||
JsonArray devices = root.createNestedArray("devices");
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice->has_entities()) {
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["i"] = emsdevice->unique_id(); // a unique id
|
||||
obj["i"] = emsdevice->unique_id(); // its unique id
|
||||
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
|
||||
uint8_t device_index = EMSESP::device_index(emsdevice->device_type(), emsdevice->unique_id());
|
||||
if (device_index) {
|
||||
char s[10];
|
||||
obj["s"] = emsdevice->device_type_name() + Helpers::smallitoa(s, device_index) + " (" + emsdevice->name() + ")"; // shortname - we prefix the count to make it unique
|
||||
obj["t"] = Helpers::toLower(emsdevice->device_type_name()) + Helpers::smallitoa(s, device_index);
|
||||
} else {
|
||||
obj["s"] = emsdevice->device_type_name() + " (" + emsdevice->name() + ")";
|
||||
obj["t"] = Helpers::toLower(emsdevice->device_type_name());
|
||||
}
|
||||
*/
|
||||
obj["s"] = emsdevice->device_type_name() + " (" + emsdevice->name() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user