mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
Set sensornames from web
This commit is contained in:
@@ -45,16 +45,19 @@ import {
|
|||||||
Device,
|
Device,
|
||||||
DeviceValue,
|
DeviceValue,
|
||||||
DeviceValueUOM,
|
DeviceValueUOM,
|
||||||
DeviceValueUOM_s
|
DeviceValueUOM_s,
|
||||||
|
Sensor
|
||||||
} from './EMSESPtypes';
|
} from './EMSESPtypes';
|
||||||
|
|
||||||
import ValueForm from './ValueForm';
|
import ValueForm from './ValueForm';
|
||||||
|
import SensorForm from './SensorForm';
|
||||||
|
|
||||||
import { ENDPOINT_ROOT } from '../api';
|
import { ENDPOINT_ROOT } from '../api';
|
||||||
|
|
||||||
export const SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + 'scanDevices';
|
export const SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + 'scanDevices';
|
||||||
export const DEVICE_DATA_ENDPOINT = ENDPOINT_ROOT + 'deviceData';
|
export const DEVICE_DATA_ENDPOINT = ENDPOINT_ROOT + 'deviceData';
|
||||||
export const WRITE_VALUE_ENDPOINT = ENDPOINT_ROOT + 'writeValue';
|
export const WRITE_VALUE_ENDPOINT = ENDPOINT_ROOT + 'writeValue';
|
||||||
|
export const WRITE_SENSOR_ENDPOINT = ENDPOINT_ROOT + 'writeSensor';
|
||||||
|
|
||||||
const StyledTableCell = withStyles((theme: Theme) =>
|
const StyledTableCell = withStyles((theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
@@ -94,6 +97,7 @@ interface EMSESPDevicesFormState {
|
|||||||
deviceData?: EMSESPDeviceData;
|
deviceData?: EMSESPDeviceData;
|
||||||
selectedDevice?: number;
|
selectedDevice?: number;
|
||||||
edit_devicevalue?: DeviceValue;
|
edit_devicevalue?: DeviceValue;
|
||||||
|
edit_sensorname?: Sensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
type EMSESPDevicesFormProps = RestFormProps<EMSESPDevices> &
|
type EMSESPDevicesFormProps = RestFormProps<EMSESPDevices> &
|
||||||
@@ -215,6 +219,65 @@ class EMSESPDevicesForm extends Component<
|
|||||||
this.setState({ edit_devicevalue: dv });
|
this.setState({ edit_devicevalue: dv });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleSensorChange = (name: keyof Sensor) => (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement>
|
||||||
|
) => {
|
||||||
|
this.setState({
|
||||||
|
edit_sensorname: {
|
||||||
|
...this.state.edit_sensorname!,
|
||||||
|
[name]: extractEventValue(event)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
cancelEditingSensor = () => {
|
||||||
|
this.setState({ edit_sensorname: undefined });
|
||||||
|
};
|
||||||
|
|
||||||
|
doneEditingSensor = () => {
|
||||||
|
const { edit_sensorname } = this.state;
|
||||||
|
|
||||||
|
redirectingAuthorizedFetch(WRITE_SENSOR_ENDPOINT, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
sensorname: edit_sensorname
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.props.enqueueSnackbar('Sensorname set', {
|
||||||
|
variant: 'success'
|
||||||
|
});
|
||||||
|
} else if (response.status === 204) {
|
||||||
|
this.props.enqueueSnackbar('Sensorname not set', {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
} else if (response.status === 403) {
|
||||||
|
this.props.enqueueSnackbar('Write access denied', {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw Error('Unexpected response code: ' + response.status);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.props.enqueueSnackbar(error.message || 'Problem writing value', {
|
||||||
|
variant: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (edit_sensorname) {
|
||||||
|
this.setState({ edit_sensorname: undefined });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendSensor = (sn: Sensor) => {
|
||||||
|
this.setState({ edit_sensorname: sn });
|
||||||
|
};
|
||||||
|
|
||||||
noDevices = () => {
|
noDevices = () => {
|
||||||
return this.props.data.devices.length === 0;
|
return this.props.data.devices.length === 0;
|
||||||
};
|
};
|
||||||
@@ -298,28 +361,47 @@ class EMSESPDevicesForm extends Component<
|
|||||||
|
|
||||||
renderSensorItems() {
|
renderSensorItems() {
|
||||||
const { data } = this.props;
|
const { data } = this.props;
|
||||||
|
const me = this.props.authenticatedContext.me;
|
||||||
return (
|
return (
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
<p></p>
|
<p></p>
|
||||||
<Typography variant="h6" color="primary" paragraph>
|
<Typography variant="h6" color="primary" paragraph>
|
||||||
Dallas Sensors
|
Sensors
|
||||||
</Typography>
|
</Typography>
|
||||||
{!this.noSensors() && (
|
{!this.noSensors() && (
|
||||||
<Table size="small" padding="default">
|
<Table size="small" padding="default">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
<StyledTableCell
|
||||||
|
padding="checkbox"
|
||||||
|
style={{ width: 18 }}
|
||||||
|
></StyledTableCell>
|
||||||
<StyledTableCell>Sensor #</StyledTableCell>
|
<StyledTableCell>Sensor #</StyledTableCell>
|
||||||
<StyledTableCell align="center">ID</StyledTableCell>
|
<StyledTableCell align="left">ID / Name</StyledTableCell>
|
||||||
<StyledTableCell align="right">Temperature</StyledTableCell>
|
<StyledTableCell align="right">Temperature</StyledTableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{data.sensors.map((sensorData) => (
|
{data.sensors.map((sensorData) => (
|
||||||
<TableRow key={sensorData.no}>
|
<TableRow key={sensorData.no} hover>
|
||||||
|
<TableCell padding="checkbox" style={{ width: 18 }}>
|
||||||
|
{me.admin && (
|
||||||
|
<CustomTooltip title="change name" placement="left-end">
|
||||||
|
<IconButton
|
||||||
|
edge="start"
|
||||||
|
size="small"
|
||||||
|
aria-label="Edit"
|
||||||
|
onClick={() => this.sendSensor(sensorData)}
|
||||||
|
>
|
||||||
|
<EditIcon color="primary" fontSize="small" />
|
||||||
|
</IconButton>
|
||||||
|
</CustomTooltip>
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
<TableCell component="th" scope="row">
|
<TableCell component="th" scope="row">
|
||||||
{sensorData.no}
|
{sensorData.no}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">{sensorData.id}</TableCell>
|
<TableCell align="left">{sensorData.id}</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
{formatValue(sensorData.temp, DeviceValueUOM.DEGREES, 1)}
|
{formatValue(sensorData.temp, DeviceValueUOM.DEGREES, 1)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -339,6 +421,34 @@ class EMSESPDevicesForm extends Component<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderAnalog() {
|
||||||
|
const { data } = this.props;
|
||||||
|
return (
|
||||||
|
<TableContainer>
|
||||||
|
{data.analog > 0 && (
|
||||||
|
<Table size="small" padding="default">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<StyledTableCell>Sensortype</StyledTableCell>
|
||||||
|
<StyledTableCell align="right">Value</StyledTableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell component="th" scope="row">
|
||||||
|
Analog Input
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
{formatValue(data.analog, DeviceValueUOM.MV, 0)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
)}
|
||||||
|
</TableContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
renderScanDevicesDialog() {
|
renderScanDevicesDialog() {
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -504,13 +614,14 @@ class EMSESPDevicesForm extends Component<
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { edit_devicevalue } = this.state;
|
const { edit_devicevalue, edit_sensorname } = this.state;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<br></br>
|
<br></br>
|
||||||
{this.renderDeviceItems()}
|
{this.renderDeviceItems()}
|
||||||
{this.renderDeviceData()}
|
{this.renderDeviceData()}
|
||||||
{this.renderSensorItems()}
|
{this.renderSensorItems()}
|
||||||
|
{this.renderAnalog()}
|
||||||
<br></br>
|
<br></br>
|
||||||
<Box display="flex" flexWrap="wrap">
|
<Box display="flex" flexWrap="wrap">
|
||||||
<Box flexGrow={1} padding={1}>
|
<Box flexGrow={1} padding={1}>
|
||||||
@@ -542,6 +653,14 @@ class EMSESPDevicesForm extends Component<
|
|||||||
handleValueChange={this.handleValueChange}
|
handleValueChange={this.handleValueChange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{edit_sensorname && (
|
||||||
|
<SensorForm
|
||||||
|
sensor={edit_sensorname}
|
||||||
|
onDoneEditing={this.doneEditingSensor}
|
||||||
|
onCancelEditing={this.cancelEditingSensor}
|
||||||
|
handleSensorChange={this.handleSensorChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export interface Sensor {
|
|||||||
export interface EMSESPDevices {
|
export interface EMSESPDevices {
|
||||||
devices: Device[];
|
devices: Device[];
|
||||||
sensors: Sensor[];
|
sensors: Sensor[];
|
||||||
|
analog: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeviceValue {
|
export interface DeviceValue {
|
||||||
@@ -93,7 +94,8 @@ export enum DeviceValueUOM {
|
|||||||
DBM,
|
DBM,
|
||||||
NUM,
|
NUM,
|
||||||
BOOLEAN,
|
BOOLEAN,
|
||||||
LIST
|
LIST,
|
||||||
|
MV
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeviceValueUOM_s = [
|
export const DeviceValueUOM_s = [
|
||||||
@@ -114,5 +116,6 @@ export const DeviceValueUOM_s = [
|
|||||||
'dBm',
|
'dBm',
|
||||||
'number',
|
'number',
|
||||||
'on/off',
|
'on/off',
|
||||||
''
|
'',
|
||||||
|
'mV'
|
||||||
];
|
];
|
||||||
|
|||||||
92
interface/src/project/SensorForm.tsx
Normal file
92
interface/src/project/SensorForm.tsx
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import React, { RefObject } from 'react';
|
||||||
|
import { ValidatorForm } from 'react-material-ui-form-validator';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
FormHelperText,
|
||||||
|
OutlinedInput
|
||||||
|
} from '@material-ui/core';
|
||||||
|
|
||||||
|
import { FormButton } from '../components';
|
||||||
|
import { Sensor } from './EMSESPtypes';
|
||||||
|
|
||||||
|
interface SensorFormProps {
|
||||||
|
sensor: Sensor;
|
||||||
|
onDoneEditing: () => void;
|
||||||
|
onCancelEditing: () => void;
|
||||||
|
handleSensorChange: (
|
||||||
|
data: keyof Sensor
|
||||||
|
) => (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SensorForm extends React.Component<SensorFormProps> {
|
||||||
|
formRef: RefObject<any> = React.createRef();
|
||||||
|
|
||||||
|
submit = () => {
|
||||||
|
this.formRef.current.submit();
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
sensor,
|
||||||
|
handleSensorChange,
|
||||||
|
onDoneEditing,
|
||||||
|
onCancelEditing
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ValidatorForm onSubmit={onDoneEditing} ref={this.formRef}>
|
||||||
|
<Dialog
|
||||||
|
maxWidth="xs"
|
||||||
|
onClose={onCancelEditing}
|
||||||
|
aria-labelledby="user-form-dialog-title"
|
||||||
|
open
|
||||||
|
>
|
||||||
|
<DialogTitle id="user-form-dialog-title">
|
||||||
|
Change Sensor Name
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent dividers>
|
||||||
|
<FormHelperText id="outlined-value-name-text">
|
||||||
|
Name of sensor #{sensor.no}
|
||||||
|
</FormHelperText>
|
||||||
|
<OutlinedInput
|
||||||
|
id="outlined-adornment-value"
|
||||||
|
value={sensor.id}
|
||||||
|
autoFocus
|
||||||
|
fullWidth
|
||||||
|
onChange={handleSensorChange('id')}
|
||||||
|
aria-describedby="outlined-value-name-text"
|
||||||
|
inputProps={{
|
||||||
|
'aria-label': 'id'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormHelperText>
|
||||||
|
(optional 'offset' separated by space)
|
||||||
|
</FormHelperText>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<FormButton
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
onClick={onCancelEditing}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</FormButton>
|
||||||
|
<FormButton
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
type="submit"
|
||||||
|
onClick={this.submit}
|
||||||
|
>
|
||||||
|
Done
|
||||||
|
</FormButton>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</ValidatorForm>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SensorForm;
|
||||||
@@ -282,6 +282,7 @@ const EMSESP_DEVICEDATA_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceData'
|
|||||||
const EMSESP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'emsespStatus'
|
const EMSESP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'emsespStatus'
|
||||||
const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'
|
const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'
|
||||||
const WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeValue'
|
const WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeValue'
|
||||||
|
+const WRITE_SENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeSensor'
|
||||||
const emsesp_settings = {
|
const emsesp_settings = {
|
||||||
tx_mode: 1,
|
tx_mode: 1,
|
||||||
tx_delay: 0,
|
tx_delay: 0,
|
||||||
|
|||||||
@@ -310,10 +310,10 @@ std::string DallasSensor::Sensor::id_string() const {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DallasSensor::Sensor::to_string() const {
|
std::string DallasSensor::Sensor::to_string(const bool name) const {
|
||||||
std::string str = id_string();
|
std::string str = id_string();
|
||||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||||
if (settings.dallas_format == Dallas_Format::NAME) {
|
if (settings.dallas_format == Dallas_Format::NAME || name) {
|
||||||
for (uint8_t i = 0; i < NUM_SENSOR_NAMES; i++) {
|
for (uint8_t i = 0; i < NUM_SENSOR_NAMES; i++) {
|
||||||
if (strcmp(settings.sensor[i].id.c_str(), str.c_str()) == 0) {
|
if (strcmp(settings.sensor[i].id.c_str(), str.c_str()) == 0) {
|
||||||
str = settings.sensor[i].name.c_str();
|
str = settings.sensor[i].name.c_str();
|
||||||
@@ -339,7 +339,24 @@ int16_t DallasSensor::Sensor::offset() const {
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DallasSensor::add_name(const char * id, const char * name, int16_t offset) {
|
bool DallasSensor::add_name(const char * idstr, const char * name, int16_t offset) {
|
||||||
|
bool ok = false;
|
||||||
|
char id[20];
|
||||||
|
strlcpy(id, idstr, sizeof(id));
|
||||||
|
|
||||||
|
// check for number and convert to id
|
||||||
|
if (strlen(id) > 0 && strlen(id) <= 2 && id[0] >= '1' && id[0] <= '9') {
|
||||||
|
uint8_t no = atoi(idstr) - 1;
|
||||||
|
if (no < sensors_.size()) {
|
||||||
|
strlcpy(id, sensors_[no].id_string().c_str(), sizeof(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check valid id
|
||||||
|
if (strlen(id) != 17 || id[2] != '-' || id[7] != '-' || id[12] !='-') {
|
||||||
|
LOG_WARNING(F("Invalid sensor id: %s"), id);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
EMSESP::webSettingsService.update([&](WebSettings & settings) {
|
EMSESP::webSettingsService.update([&](WebSettings & settings) {
|
||||||
// check for new name of stored id
|
// check for new name of stored id
|
||||||
for (uint8_t i = 0; i < NUM_SENSOR_NAMES; i++) {
|
for (uint8_t i = 0; i < NUM_SENSOR_NAMES; i++) {
|
||||||
@@ -354,6 +371,7 @@ void DallasSensor::add_name(const char * id, const char * name, int16_t offset)
|
|||||||
settings.sensor[i].offset = offset;
|
settings.sensor[i].offset = offset;
|
||||||
LOG_INFO(F("Setting name of sensor %s to %s"), id, name);
|
LOG_INFO(F("Setting name of sensor %s to %s"), id, name);
|
||||||
}
|
}
|
||||||
|
ok = true;
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,6 +382,7 @@ void DallasSensor::add_name(const char * id, const char * name, int16_t offset)
|
|||||||
settings.sensor[i].name = (strlen(name) == 0) ? id : name;
|
settings.sensor[i].name = (strlen(name) == 0) ? id : name;
|
||||||
settings.sensor[i].offset = offset;
|
settings.sensor[i].offset = offset;
|
||||||
LOG_INFO(F("Setting name of sensor %s to %s"), id, name);
|
LOG_INFO(F("Setting name of sensor %s to %s"), id, name);
|
||||||
|
ok = true;
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,12 +399,14 @@ void DallasSensor::add_name(const char * id, const char * name, int16_t offset)
|
|||||||
settings.sensor[i].name = (strlen(name) == 0) ? id : name;
|
settings.sensor[i].name = (strlen(name) == 0) ? id : name;
|
||||||
settings.sensor[i].offset = offset;
|
settings.sensor[i].offset = offset;
|
||||||
LOG_INFO(F("Setting name of sensor %s to %s"), id, name);
|
LOG_INFO(F("Setting name of sensor %s to %s"), id, name);
|
||||||
|
ok = true;
|
||||||
return StateUpdateResult::CHANGED;
|
return StateUpdateResult::CHANGED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_ERROR(F("List full, remove one sensorname first"));
|
LOG_ERROR(F("List full, remove one sensorname first"));
|
||||||
return StateUpdateResult::UNCHANGED;
|
return StateUpdateResult::UNCHANGED;
|
||||||
}, "local");
|
}, "local");
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if values have been updated
|
// check to see if values have been updated
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class DallasSensor {
|
|||||||
|
|
||||||
uint64_t id() const;
|
uint64_t id() const;
|
||||||
std::string id_string() const;
|
std::string id_string() const;
|
||||||
std::string to_string() const;
|
std::string to_string(const bool name = false) const;
|
||||||
int16_t offset() const;
|
int16_t offset() const;
|
||||||
|
|
||||||
int16_t temperature_c = EMS_VALUE_SHORT_NOTSET;
|
int16_t temperature_c = EMS_VALUE_SHORT_NOTSET;
|
||||||
@@ -88,7 +88,7 @@ class DallasSensor {
|
|||||||
dallas_format_ = dallas_format;
|
dallas_format_ = dallas_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_name(const char * id, const char * name, int16_t offset);
|
bool add_name(const char * idstr, const char * name, int16_t offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint8_t MAX_SENSORS = 20;
|
static constexpr uint8_t MAX_SENSORS = 20;
|
||||||
@@ -134,7 +134,6 @@ class DallasSensor {
|
|||||||
bool command_commands(const char * value, const int8_t id, JsonObject & json);
|
bool command_commands(const char * value, const int8_t id, JsonObject & json);
|
||||||
|
|
||||||
uint32_t last_activity_ = uuid::get_uptime();
|
uint32_t last_activity_ = uuid::get_uptime();
|
||||||
uint32_t last_publish_ = uuid::get_uptime();
|
|
||||||
State state_ = State::IDLE;
|
State state_ = State::IDLE;
|
||||||
std::vector<Sensor> sensors_;
|
std::vector<Sensor> sensors_;
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,14 @@ class System {
|
|||||||
static bool is_valid_gpio(uint8_t pin);
|
static bool is_valid_gpio(uint8_t pin);
|
||||||
static bool load_board_profile(std::vector<uint8_t> & data, const std::string & board_profile);
|
static bool load_board_profile(std::vector<uint8_t> & data, const std::string & board_profile);
|
||||||
|
|
||||||
|
bool analog_enabled() {
|
||||||
|
return analog_enabled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t analog() {
|
||||||
|
return analog_;
|
||||||
|
}
|
||||||
|
|
||||||
std::string hostname() {
|
std::string hostname() {
|
||||||
return hostname_;
|
return hostname_;
|
||||||
}
|
}
|
||||||
@@ -96,6 +104,7 @@ class System {
|
|||||||
void ethernet_connected(bool b) {
|
void ethernet_connected(bool b) {
|
||||||
ethernet_connected_ = b;
|
ethernet_connected_ = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_connected(bool b) {
|
void network_connected(bool b) {
|
||||||
network_connected_ = b;
|
network_connected_ = b;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ WebDevicesService::WebDevicesService(AsyncWebServer * server, SecurityManager *
|
|||||||
: _device_dataHandler(DEVICE_DATA_SERVICE_PATH,
|
: _device_dataHandler(DEVICE_DATA_SERVICE_PATH,
|
||||||
securityManager->wrapCallback(std::bind(&WebDevicesService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED))
|
securityManager->wrapCallback(std::bind(&WebDevicesService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED))
|
||||||
, _writevalue_dataHandler(WRITE_VALUE_SERVICE_PATH,
|
, _writevalue_dataHandler(WRITE_VALUE_SERVICE_PATH,
|
||||||
securityManager->wrapCallback(std::bind(&WebDevicesService::write_value, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) {
|
securityManager->wrapCallback(std::bind(&WebDevicesService::write_value, this, _1, _2), AuthenticationPredicates::IS_ADMIN))
|
||||||
|
, _writesensor_dataHandler(WRITE_SENSOR_SERVICE_PATH,
|
||||||
|
securityManager->wrapCallback(std::bind(&WebDevicesService::write_sensor, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) {
|
||||||
server->on(EMSESP_DEVICES_SERVICE_PATH,
|
server->on(EMSESP_DEVICES_SERVICE_PATH,
|
||||||
HTTP_GET,
|
HTTP_GET,
|
||||||
securityManager->wrapRequest(std::bind(&WebDevicesService::all_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
securityManager->wrapRequest(std::bind(&WebDevicesService::all_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
@@ -41,6 +43,10 @@ WebDevicesService::WebDevicesService(AsyncWebServer * server, SecurityManager *
|
|||||||
_writevalue_dataHandler.setMethod(HTTP_POST);
|
_writevalue_dataHandler.setMethod(HTTP_POST);
|
||||||
_writevalue_dataHandler.setMaxContentLength(256);
|
_writevalue_dataHandler.setMaxContentLength(256);
|
||||||
server->addHandler(&_writevalue_dataHandler);
|
server->addHandler(&_writevalue_dataHandler);
|
||||||
|
|
||||||
|
_writesensor_dataHandler.setMethod(HTTP_POST);
|
||||||
|
_writesensor_dataHandler.setMaxContentLength(256);
|
||||||
|
server->addHandler(&_writesensor_dataHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebDevicesService::scan_devices(AsyncWebServerRequest * request) {
|
void WebDevicesService::scan_devices(AsyncWebServerRequest * request) {
|
||||||
@@ -73,10 +79,13 @@ void WebDevicesService::all_devices(AsyncWebServerRequest * request) {
|
|||||||
for (const auto & sensor : EMSESP::sensor_devices()) {
|
for (const auto & sensor : EMSESP::sensor_devices()) {
|
||||||
JsonObject obj = sensors.createNestedObject();
|
JsonObject obj = sensors.createNestedObject();
|
||||||
obj["no"] = i++;
|
obj["no"] = i++;
|
||||||
obj["id"] = sensor.to_string();
|
obj["id"] = sensor.to_string(true);
|
||||||
obj["temp"] = Helpers::render_value(s, sensor.temperature_c, 10);
|
obj["temp"] = Helpers::render_value(s, sensor.temperature_c, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (EMSESP::system_.analog_enabled()) {
|
||||||
|
root["analog"] = EMSESP::system_.analog();
|
||||||
|
}
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
@@ -146,4 +155,34 @@ void WebDevicesService::write_value(AsyncWebServerRequest * request, JsonVariant
|
|||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// takes a sensorname and optional offset from the Web
|
||||||
|
void WebDevicesService::write_sensor(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||||
|
bool ok = false;
|
||||||
|
if (json.is<JsonObject>()) {
|
||||||
|
JsonObject sn = json["sensorname"];
|
||||||
|
std::string id = sn["id"];
|
||||||
|
uint8_t no = sn["no"];
|
||||||
|
char nostr[3];
|
||||||
|
char name[25];
|
||||||
|
int16_t offset = 0;
|
||||||
|
|
||||||
|
strlcpy(name, id.c_str(), sizeof(name));
|
||||||
|
if (no > 0 && no < 100) {
|
||||||
|
itoa(no, nostr, 10);
|
||||||
|
char * c = strchr(name, ' '); // find space
|
||||||
|
if (c != nullptr) {
|
||||||
|
*c = '\0';
|
||||||
|
float v;
|
||||||
|
if (Helpers::value2float((c + 1), v)) {
|
||||||
|
offset = v * 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok = EMSESP::dallassensor_.add_name(nostr, name, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 204);
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#define SCAN_DEVICES_SERVICE_PATH "/rest/scanDevices"
|
#define SCAN_DEVICES_SERVICE_PATH "/rest/scanDevices"
|
||||||
#define DEVICE_DATA_SERVICE_PATH "/rest/deviceData"
|
#define DEVICE_DATA_SERVICE_PATH "/rest/deviceData"
|
||||||
#define WRITE_VALUE_SERVICE_PATH "/rest/writeValue"
|
#define WRITE_VALUE_SERVICE_PATH "/rest/writeValue"
|
||||||
|
#define WRITE_SENSOR_SERVICE_PATH "/rest/writeSensor"
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
@@ -43,8 +44,9 @@ class WebDevicesService {
|
|||||||
// POST
|
// POST
|
||||||
void device_data(AsyncWebServerRequest * request, JsonVariant & json);
|
void device_data(AsyncWebServerRequest * request, JsonVariant & json);
|
||||||
void write_value(AsyncWebServerRequest * request, JsonVariant & json);
|
void write_value(AsyncWebServerRequest * request, JsonVariant & json);
|
||||||
|
void write_sensor(AsyncWebServerRequest * request, JsonVariant & json);
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler _device_dataHandler, _writevalue_dataHandler;
|
AsyncCallbackJsonWebHandler _device_dataHandler, _writevalue_dataHandler, _writesensor_dataHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
Reference in New Issue
Block a user