mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
Merge remote-tracking branch 'origin/ft_webcallcmd' into dev
This commit is contained in:
@@ -1,13 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## Added
|
||||
|
||||
- Mock API to simulate an ESP, for testing web
|
||||
- Able to write values from the Web UI
|
||||
|
||||
## Fixed
|
||||
- Don't create Home Assistant MQTT discovery entries for device values that don't exists (#756 on EMS-ESP repo)
|
||||
- Update shower MQTT when a shower start is detected
|
||||
|
||||
## Changed
|
||||
|
||||
- Icon for Network
|
||||
- MQTT Formatting payload (nested vs single) is a pull-down option
|
||||
- moved mqtt-topics and texts to local_EN, all topics lower case
|
||||
- Re-enabled Shower Alert (still experimental)
|
||||
- lowercased Flow temp in commands
|
||||
|
||||
## Removed
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
|
||||
**EMS-ESP** is an open-source firmware for the Espressif ESP8266 and ESP32 microcontroller that communicates with **EMS** (Energy Management System) based equipment from manufacturers like Bosch, Buderus, Nefit, Junkers, Worcester and Sieger.
|
||||
|
||||
This is the firmware for the ESP32.
|
||||
This is the firmware for the ESP32. Compared to version 2 on the ESP8266, this version has
|
||||
- Ethernet Support
|
||||
- Pre-configured board layouts
|
||||
- Writing values directly from the Web UI
|
||||
- Mock API server for faster offline development
|
||||
- Expose to more commands, via MQTT
|
||||
- Improvements to Dallas sensors, Shower service
|
||||
|
||||
[](https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md)
|
||||
[](https://github.com/emsesp/EMS-ESP32/commits/main)
|
||||
|
||||
@@ -9,7 +9,7 @@ const fs = require('fs');
|
||||
|
||||
module.exports = function override(config, env) {
|
||||
if (env === "production") {
|
||||
// rename the ouput file, we need it's path to be short, for SPIFFS
|
||||
// rename the output file, we need it's path to be short for LittleFS
|
||||
config.output.filename = 'js/[id].[chunkhash:4].js';
|
||||
config.output.chunkFilename = 'js/[id].[chunkhash:4].js';
|
||||
|
||||
|
||||
8578
interface/package-lock.json
generated
8578
interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -6,29 +6,29 @@
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/node": "^12.20.4",
|
||||
"@types/node": "^14.14.37",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-dom": "^17.0.1",
|
||||
"@types/react-dom": "^17.0.3",
|
||||
"@types/react-material-ui-form-validator": "^2.1.0",
|
||||
"@types/react-router": "^5.1.12",
|
||||
"@types/react-router-dom": "^5.1.6",
|
||||
"compression-webpack-plugin": "^4.0.0",
|
||||
"@types/react-router": "^5.1.13",
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"compression-webpack-plugin": "^5.0.2",
|
||||
"express": "^4.17.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mime-types": "^2.1.29",
|
||||
"mime-types": "^2.1.30",
|
||||
"notistack": "^1.0.5",
|
||||
"parse-ms": "^2.1.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-dropzone": "^11.3.1",
|
||||
"parse-ms": "^3.0.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-dropzone": "^11.3.2",
|
||||
"react-form-validator-core": "^1.1.1",
|
||||
"react-material-ui-form-validator": "^2.1.4",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "4.0.1",
|
||||
"react-scripts": "4.0.3",
|
||||
"sockette": "^2.0.6",
|
||||
"typescript": "4.0.5",
|
||||
"typescript": "4.2.4",
|
||||
"zlib": "^1.0.5"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -54,9 +54,9 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^6.0.0",
|
||||
"http-proxy-middleware": "^0.19.1",
|
||||
"nodemon": "^2.0.4",
|
||||
"concurrently": "^6.0.1",
|
||||
"http-proxy-middleware": "^1.1.1",
|
||||
"nodemon": "^2.0.7",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"react-app-rewired": "^2.1.8"
|
||||
}
|
||||
|
||||
@@ -5,10 +5,8 @@ import { withSnackbar, WithSnackbarProps } from 'notistack';
|
||||
import * as Authentication from './Authentication';
|
||||
import { withAuthenticationContext, AuthenticationContextProps, AuthenticatedContext, AuthenticatedContextValue } from './AuthenticationContext';
|
||||
|
||||
type ChildComponent = React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>;
|
||||
|
||||
interface AuthenticatedRouteProps extends RouteProps, WithSnackbarProps, AuthenticationContextProps {
|
||||
component: ChildComponent;
|
||||
component: React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>;
|
||||
}
|
||||
|
||||
type RenderComponent = (props: RouteComponentProps<any>) => React.ReactNode;
|
||||
@@ -27,7 +25,7 @@ export class AuthenticatedRoute extends React.Component<AuthenticatedRouteProps>
|
||||
);
|
||||
}
|
||||
Authentication.storeLoginRedirect(location);
|
||||
enqueueSnackbar("Please sign in to continue.", { variant: 'info' });
|
||||
enqueueSnackbar("Please sign in to continue", { variant: 'info' });
|
||||
return (
|
||||
<Redirect to='/' />
|
||||
);
|
||||
|
||||
@@ -101,7 +101,7 @@ class AuthenticationWrapper extends React.Component<AuthenticationWrapperProps,
|
||||
me: undefined
|
||||
}
|
||||
});
|
||||
this.props.enqueueSnackbar("You have signed out.", { variant: 'success', });
|
||||
this.props.enqueueSnackbar("You have signed out", { variant: 'success', });
|
||||
history.push('/');
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,10 @@ class UnauthenticatedRoute extends Route<UnauthenticatedRouteProps> {
|
||||
if (authenticationContext.me) {
|
||||
return (<Redirect to={Authentication.fetchLoginRedirect(features)} />);
|
||||
}
|
||||
if (Component) {
|
||||
return (<Component {...props} />);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Route {...rest} render={renderComponent} />
|
||||
);
|
||||
|
||||
@@ -8,15 +8,21 @@ import {
|
||||
|
||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||
import ListIcon from "@material-ui/icons/List";
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import EditIcon from '@material-ui/icons/Edit';
|
||||
|
||||
import { redirectingAuthorizedFetch, withAuthenticatedContext, AuthenticatedContextProps } from "../authentication";
|
||||
import { RestFormProps, FormButton } from "../components";
|
||||
import { RestFormProps, FormButton, extractEventValue } from "../components";
|
||||
|
||||
import { EMSESPDevices, EMSESPDeviceData, Device } from "./EMSESPtypes";
|
||||
import { EMSESPDevices, EMSESPDeviceData, Device, DeviceValue } from "./EMSESPtypes";
|
||||
|
||||
import ValueForm from './ValueForm';
|
||||
|
||||
import { ENDPOINT_ROOT } from "../api";
|
||||
|
||||
export const SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + "scanDevices";
|
||||
export const DEVICE_DATA_ENDPOINT = ENDPOINT_ROOT + "deviceData";
|
||||
export const WRITE_VALUE_ENDPOINT = ENDPOINT_ROOT + "writeValue";
|
||||
|
||||
const StyledTableCell = withStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -30,6 +36,16 @@ const StyledTableCell = withStyles((theme: Theme) =>
|
||||
})
|
||||
)(TableCell);
|
||||
|
||||
const CustomTooltip = withStyles((theme: Theme) => ({
|
||||
tooltip: {
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
color: 'white',
|
||||
boxShadow: theme.shadows[1],
|
||||
fontSize: 11,
|
||||
border: '1px solid #dadde9',
|
||||
},
|
||||
}))(Tooltip);
|
||||
|
||||
function compareDevices(a: Device, b: Device) {
|
||||
if (a.type < b.type) {
|
||||
return -1;
|
||||
@@ -44,11 +60,11 @@ interface EMSESPDevicesFormState {
|
||||
confirmScanDevices: boolean;
|
||||
processing: boolean;
|
||||
deviceData?: EMSESPDeviceData;
|
||||
selectedDevice?: number;
|
||||
devicevalue?: DeviceValue;
|
||||
}
|
||||
|
||||
type EMSESPDevicesFormProps = RestFormProps<EMSESPDevices> &
|
||||
AuthenticatedContextProps &
|
||||
WithWidthProps;
|
||||
type EMSESPDevicesFormProps = RestFormProps<EMSESPDevices> & AuthenticatedContextProps & WithWidthProps;
|
||||
|
||||
function formatTemp(t: string) {
|
||||
if (t == null) {
|
||||
@@ -67,9 +83,66 @@ function formatUnit(u: string) {
|
||||
class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesFormState> {
|
||||
state: EMSESPDevicesFormState = {
|
||||
confirmScanDevices: false,
|
||||
processing: false,
|
||||
processing: false
|
||||
};
|
||||
|
||||
handleValueChange = (name: keyof DeviceValue) => (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.setState({ devicevalue: { ...this.state.devicevalue!, [name]: extractEventValue(event) } });
|
||||
};
|
||||
|
||||
cancelEditingValue = () => {
|
||||
this.setState({
|
||||
devicevalue: undefined
|
||||
});
|
||||
}
|
||||
|
||||
doneEditingValue = () => {
|
||||
const { devicevalue } = this.state;
|
||||
|
||||
redirectingAuthorizedFetch(WRITE_VALUE_ENDPOINT, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ devicevalue: devicevalue }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status === 200) {
|
||||
this.props.enqueueSnackbar("Write command sent to device", { variant: "success" });
|
||||
} else if (response.status === 204) {
|
||||
this.props.enqueueSnackbar("Write command failed", { 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 (devicevalue) {
|
||||
this.setState({
|
||||
devicevalue: undefined
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
sendCommand = (i: any) => {
|
||||
this.setState({
|
||||
devicevalue: {
|
||||
id: this.state.selectedDevice!,
|
||||
data: this.state.deviceData?.data[i]!,
|
||||
uom: this.state.deviceData?.data[i + 1]!,
|
||||
name: this.state.deviceData?.data[i + 2]!,
|
||||
cmd: this.state.deviceData?.data[i + 3]!,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
noDevices = () => {
|
||||
return this.props.data.devices.length === 0;
|
||||
};
|
||||
@@ -95,50 +168,20 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
size="small"
|
||||
padding={isWidthDown("xs", width!) ? "none" : "default"}
|
||||
>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<StyledTableCell>Type</StyledTableCell>
|
||||
<StyledTableCell align="center">Brand</StyledTableCell>
|
||||
<StyledTableCell align="center">Model</StyledTableCell>
|
||||
<StyledTableCell align="center">Device ID</StyledTableCell>
|
||||
<StyledTableCell align="center">Product ID</StyledTableCell>
|
||||
<StyledTableCell align="center">Version</StyledTableCell>
|
||||
<StyledTableCell></StyledTableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{data.devices.sort(compareDevices).map((device) => (
|
||||
<TableRow
|
||||
hover
|
||||
key={device.id}
|
||||
onClick={() => this.handleRowClick(device.id)}
|
||||
>
|
||||
<TableCell component="th" scope="row">
|
||||
<Tooltip
|
||||
title="click for details..."
|
||||
arrow
|
||||
<TableRow hover key={device.id} onClick={() => this.handleRowClick(device)}>
|
||||
<TableCell>
|
||||
<CustomTooltip
|
||||
title={"DeviceID:0x" + ("00" + device.deviceid.toString(16).toUpperCase()).slice(-2) + " ProductID:" + device.productid + " Version:" + device.version}
|
||||
placement="right-end"
|
||||
>
|
||||
<Button
|
||||
startIcon={<ListIcon />}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
>
|
||||
<Button startIcon={<ListIcon />} size="small" variant="outlined">
|
||||
{device.type}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</CustomTooltip>
|
||||
</TableCell>
|
||||
<TableCell align="center">{device.brand}</TableCell>
|
||||
<TableCell align="center">{device.name}</TableCell>
|
||||
<TableCell align="center">
|
||||
0x
|
||||
{("00" + device.deviceid.toString(16).toUpperCase()).slice(
|
||||
-2
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell align="center">{device.productid}</TableCell>
|
||||
<TableCell align="center">{device.version}</TableCell>
|
||||
<TableCell></TableCell>
|
||||
<TableCell align="right">{device.brand + " " + device.name} </TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
@@ -148,13 +191,10 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
<Box
|
||||
bgcolor="error.main"
|
||||
color="error.contrastText"
|
||||
p={2}
|
||||
mt={2}
|
||||
mb={2}
|
||||
p={2} mt={2} mb={2}
|
||||
>
|
||||
<Typography variant="body1">
|
||||
No EMS devices found. Check the connections and for possible Tx
|
||||
errors.
|
||||
No EMS devices found. Check the connections and for possible Tx errors.
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
@@ -213,25 +253,14 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
>
|
||||
<DialogTitle>Confirm Scan Devices</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
Are you sure you want to initiate a scan on the EMS bus for all new
|
||||
devices?
|
||||
Are you sure you want to initiate a scan on the EMS bus for all new devices?
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={this.onScanDevicesRejected}
|
||||
color="secondary"
|
||||
>
|
||||
<Button variant="contained" onClick={this.onScanDevicesRejected} color="secondary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<RefreshIcon />}
|
||||
variant="contained"
|
||||
onClick={this.onScanDevicesConfirmed}
|
||||
disabled={this.state.processing}
|
||||
color="primary"
|
||||
autoFocus
|
||||
>
|
||||
startIcon={<RefreshIcon />} variant="contained" onClick={this.onScanDevicesConfirmed} disabled={this.state.processing} color="primary" autoFocus>
|
||||
Start Scan
|
||||
</Button>
|
||||
</DialogActions>
|
||||
@@ -268,11 +297,11 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
});
|
||||
};
|
||||
|
||||
handleRowClick = (id: any) => {
|
||||
this.setState({ deviceData: undefined });
|
||||
handleRowClick = (device: any) => {
|
||||
this.setState({ selectedDevice: device.id, deviceData: undefined });
|
||||
redirectingAuthorizedFetch(DEVICE_DATA_ENDPOINT, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ id: id }),
|
||||
body: JSON.stringify({ id: device.id }),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
@@ -298,6 +327,7 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
renderDeviceData() {
|
||||
const { deviceData } = this.state;
|
||||
const { width } = this.props;
|
||||
const me = this.props.authenticatedContext.me;
|
||||
|
||||
if (this.noDevices()) {
|
||||
return;
|
||||
@@ -321,16 +351,28 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
size="small"
|
||||
padding={isWidthDown("xs", width!) ? "none" : "default"}
|
||||
>
|
||||
<TableHead></TableHead>
|
||||
<TableHead>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{deviceData.data.map((item, i) => {
|
||||
if (i % 3) {
|
||||
if (i % 4) {
|
||||
return null;
|
||||
} else {
|
||||
return (
|
||||
<TableRow key={i}>
|
||||
<TableCell component="th" scope="row">{deviceData.data[i + 2]}</TableCell>
|
||||
<TableCell align="right">{deviceData.data[i]}{formatUnit(deviceData.data[i + 1])}</TableCell>
|
||||
<TableRow hover key={i}>
|
||||
<TableCell padding="checkbox" style={{ width: 18 }} >
|
||||
{deviceData.data[i + 3] && me.admin && (
|
||||
<CustomTooltip title="change value" placement="left-end"
|
||||
>
|
||||
<IconButton edge="start" size="small" aria-label="Edit"
|
||||
onClick={() => this.sendCommand(i)}>
|
||||
<EditIcon color="primary" fontSize="small" />
|
||||
</IconButton>
|
||||
</CustomTooltip>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell padding="none" component="th" scope="row">{deviceData.data[i + 2]}</TableCell>
|
||||
<TableCell padding="none" align="right">{deviceData.data[i]}{formatUnit(deviceData.data[i + 1])}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
@@ -351,6 +393,7 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
}
|
||||
|
||||
render() {
|
||||
const { devicevalue } = this.state;
|
||||
return (
|
||||
<Fragment>
|
||||
<br></br>
|
||||
@@ -360,27 +403,26 @@ class EMSESPDevicesForm extends Component<EMSESPDevicesFormProps, EMSESPDevicesF
|
||||
<br></br>
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1} padding={1}>
|
||||
<FormButton
|
||||
startIcon={<RefreshIcon />}
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
onClick={this.props.loadData}
|
||||
>
|
||||
<FormButton startIcon={<RefreshIcon />} variant="contained" color="secondary" onClick={this.props.loadData} >
|
||||
Refresh
|
||||
</FormButton>
|
||||
</Box>
|
||||
<Box flexWrap="none" padding={1} whiteSpace="nowrap">
|
||||
<FormButton
|
||||
startIcon={<RefreshIcon />}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={this.onScanDevices}
|
||||
>
|
||||
<FormButton startIcon={<RefreshIcon />} variant="contained" onClick={this.onScanDevices} >
|
||||
Scan Devices
|
||||
</FormButton>
|
||||
</Box>
|
||||
</Box>
|
||||
{this.renderScanDevicesDialog()}
|
||||
{
|
||||
devicevalue &&
|
||||
<ValueForm
|
||||
devicevalue={devicevalue}
|
||||
onDoneEditing={this.doneEditingValue}
|
||||
onCancelEditing={this.cancelEditingValue}
|
||||
handleValueChange={this.handleValueChange}
|
||||
/>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ class EMSESPSettingsForm extends React.Component<EMSESPSettingsFormProps> {
|
||||
<ValidatorForm onSubmit={saveData}>
|
||||
<Box bgcolor="info.main" p={2} mt={2} mb={2}>
|
||||
<Typography variant="body1">
|
||||
Modify any of the EMS-ESP settings here. For help refer to the{" "}
|
||||
Adjust any of the EMS-ESP settings here. For help refer to the{" "}
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://emsesp.github.io/docs/#/Configure-firmware32?id=ems-esp-settings"
|
||||
|
||||
@@ -62,3 +62,11 @@ export interface EMSESPDeviceData {
|
||||
name: string;
|
||||
data: string[];
|
||||
}
|
||||
|
||||
export interface DeviceValue {
|
||||
id: number;
|
||||
data: string,
|
||||
uom: string,
|
||||
name: string,
|
||||
cmd: string
|
||||
}
|
||||
|
||||
64
interface/src/project/ValueForm.tsx
Normal file
64
interface/src/project/ValueForm.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import React, { RefObject } from 'react';
|
||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||
import { Dialog, DialogTitle, DialogContent, DialogActions, Box, Typography } from '@material-ui/core';
|
||||
import { FormButton } from '../components';
|
||||
import { DeviceValue } from './EMSESPtypes';
|
||||
|
||||
interface ValueFormProps {
|
||||
devicevalue: DeviceValue;
|
||||
onDoneEditing: () => void;
|
||||
onCancelEditing: () => void;
|
||||
handleValueChange: (data: keyof DeviceValue) => (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
class ValueForm extends React.Component<ValueFormProps> {
|
||||
|
||||
formRef: RefObject<any> = React.createRef();
|
||||
|
||||
submit = () => {
|
||||
this.formRef.current.submit();
|
||||
}
|
||||
|
||||
buildLabel = (devicevalue: DeviceValue) => {
|
||||
if ((devicevalue.uom === "") || (!devicevalue.uom)) {
|
||||
return "New value";
|
||||
}
|
||||
return "New value (" + devicevalue.uom + ")";
|
||||
}
|
||||
|
||||
render() {
|
||||
const { devicevalue, handleValueChange, 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 the {devicevalue.name}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<TextValidator
|
||||
validators={['required']}
|
||||
errorMessages={['is required']}
|
||||
name="data"
|
||||
label={this.buildLabel(devicevalue)}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
value={devicevalue.data}
|
||||
margin="normal"
|
||||
onChange={handleValueChange('data')}
|
||||
/>
|
||||
<Box color="warning.main" p={1} pl={0} pr={0} mt={0} mb={0}>
|
||||
<Typography variant="body2">
|
||||
<i>Note: it may take a few seconds before the change is visible. If nothing happens check the logs.</i>
|
||||
</Typography>
|
||||
</Box>
|
||||
</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 ValueForm;
|
||||
@@ -122,9 +122,7 @@ class ManageUsersForm extends React.Component<ManageUsersFormProps, ManageUsersF
|
||||
{user.username}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
{
|
||||
user.admin ? <CheckIcon /> : <CloseIcon />
|
||||
}
|
||||
{user.admin ? <CheckIcon /> : <CloseIcon />}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
<IconButton size="small" aria-label="Delete" onClick={() => this.removeUser(user)}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const createProxyMiddleware = require('http-proxy-middleware');
|
||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||
|
||||
module.exports = function (app) {
|
||||
app.use(
|
||||
@@ -6,10 +6,7 @@ module.exports = function (app) {
|
||||
createProxyMiddleware({
|
||||
target: 'http://localhost:3080',
|
||||
secure: false,
|
||||
changeOrigin: true,
|
||||
// pathRewrite: {
|
||||
// '^/api/settings': '/api/app/settings'
|
||||
// },
|
||||
changeOrigin: true
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react",
|
||||
"jsx": "react-jsx",
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": [
|
||||
|
||||
1691
mock-api/package-lock.json
generated
1691
mock-api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"private": "true",
|
||||
"description": "mock api for EMS-ESP",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
@@ -11,6 +12,6 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"nodemon": "^2.0.4"
|
||||
"nodemon": "^2.0.7"
|
||||
}
|
||||
}
|
||||
@@ -110,6 +110,7 @@ const EMSESP_SCANDEVICES_ENDPOINT = ENDPOINT_ROOT + "scanDevices";
|
||||
const EMSESP_DEVICEDATA_ENDPOINT = ENDPOINT_ROOT + "deviceData";
|
||||
const EMSESP_STATUS_ENDPOINT = ENDPOINT_ROOT + "emsespStatus";
|
||||
const EMSESP_BOARDPROFILE_ENDPOINT = ENDPOINT_ROOT + "boardProfile";
|
||||
const WRITE_VALUE_ENDPOINT = ENDPOINT_ROOT + "writeValue";
|
||||
const emsesp_settings = {
|
||||
"tx_mode": 1, "tx_delay": 0, "ems_bus_id": 11, "syslog_enabled": false, "syslog_level": 3,
|
||||
"trace_raw": false, "syslog_mark_interval": 0, "syslog_host": "192.168.1.4", "syslog_port": 514,
|
||||
@@ -119,13 +120,13 @@ const emsesp_settings = {
|
||||
};
|
||||
const emsesp_alldevices = {
|
||||
"devices": [{
|
||||
"id": 1, "type": "Thermostat", "brand": "---", "name": "RC20/Moduline 300",
|
||||
"id": 1, "type": "Thermostat", "brand": "", "name": "RC20/Moduline 300",
|
||||
"deviceid": 23, "productid": 77, "version": "03.03"
|
||||
}, {
|
||||
"id": 2, "type": "Boiler", "brand": "Nefit", "name": "GBx72/Trendline/Cerapur/Greenstar Si/27i",
|
||||
"deviceid": 8, "productid": 123, "version": "06.01"
|
||||
}, {
|
||||
"id": 3, "type": "Controller", "brand": "---", "name": "BC10",
|
||||
"id": 3, "type": "Controller", "brand": "", "name": "BC10",
|
||||
"deviceid": 9, "productid": 190, "version": "01.03"
|
||||
}],
|
||||
"sensors": []
|
||||
@@ -134,33 +135,78 @@ const emsesp_status = {
|
||||
"status": 0, "rx_received": 344, "tx_sent": 104, "rx_quality": 100, "tx_quality": 100
|
||||
};
|
||||
const emsesp_devicedata_1 = {
|
||||
"name": "Thermostat: RC20/Moduline 300", "data": ["16:28:21 01/04/2021", "", "date/time",
|
||||
"(0)", "", "error code", 15, "°C", "(hc1) setpoint room temperature", 20.5, "°C",
|
||||
"(hc1) current room temperature", "auto", "", "(hc1) mode"]
|
||||
"name": "Thermostat: RC20/Moduline 300",
|
||||
"data": [
|
||||
"16:28:21 01/04/2021", "", "date/time", "datetime",
|
||||
"(0)", "", "error code", "",
|
||||
15, "°C", "(hc1) setpoint room temperature", "temp",
|
||||
20.5, "°C", "(hc1) current room temperature", "",
|
||||
"auto", "", "(hc1) mode", "mode"
|
||||
]
|
||||
};
|
||||
const emsesp_devicedata_2 = {
|
||||
"name": "Boiler: Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i", "data": ["off", "", "heating active", "off", "",
|
||||
"warm water active", 5, "°C", "selected flow temperature", 0, "%", "burner selected max power", 0, "%",
|
||||
"heating pump modulation", 42.7, "°C", "current flow temperature", 39, "°C", "return temperature", 1.2,
|
||||
"bar", "system pressure", 45.3, "°C", "max boiler temperature", "off", "", "gas", 0, "uA", "flame current",
|
||||
"off", "", "heating pump", "off", "", "fan", "off", "", "ignition", "on", "", "heating activated", 75, "°C",
|
||||
"heating temperature", 90, "%", "burner pump max power", 55, "%", "burner pump min power", 1, null, "pump delay",
|
||||
10, null, "burner min period", 0, "%", "burner min power", 75, "%", "burner max power", -6, "°C", "hysteresis on temperature", 6,
|
||||
"°C", "hysteresis off temperature", 0, "%", "burner current power", 295740, "", "burner # starts", "344 days 2 hours 8 minutes",
|
||||
null, "total burner operating time", "279 days 11 hours 55 minutes", null, "total heat operating time",
|
||||
"2946 days 19 hours 8 minutes", null, "total UBA operating time", "1C(210) 06.06.2020 12:07", "",
|
||||
"last error code", "0H", "", "service code", 203, "", "service code number", "01.01.2012", "",
|
||||
"maintenance set date", "off", "", "maintenance scheduled", 6000, "hours", "maintenance set time", 60, "°C",
|
||||
"(warm water) selected temperature", 62, "°C", "(warm water) set temperature", "flow", "", "(warm water) type", "hot",
|
||||
"", "(warm water) comfort", 40, "", "(warm water) flow temperature offset", 100, "%", "(warm water) max power", "off",
|
||||
"", "(warm water) circulation pump available", "3-way valve", "", "(warm water) charging type", 70, "°C",
|
||||
"(warm water) disinfection temperature", "off", "", "(warm water) circulation pump freq", "off", "",
|
||||
"(warm water) circulation active", 34.7, "°C", "(warm water) current intern temperature", 0, "l/min",
|
||||
"(warm water) current tap water flow", 34.6, "°C", "(warm water) storage intern temperature", "on", "",
|
||||
"(warm water) activated", "off", "", "(warm water) one time charging", "off", "",
|
||||
"(warm water) disinfecting", "off", "", "(warm water) charging", "off", "", "(warm water) recharging", "on", "",
|
||||
"(warm water) temperature ok", "off", "", "(warm water) active", "on", "", "(warm water) heating", 262387, "",
|
||||
"(warm water) # starts", "64 days 14 hours 13 minutes", null, "(warm water) active time"]
|
||||
"name": "Boiler: Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i",
|
||||
"data": [
|
||||
"off", "", "heating active", "",
|
||||
"off", "", "warm water active", "",
|
||||
5, "°C", "selected flow temperature", "selflowtemp",
|
||||
0, "%", "burner selected max power", "",
|
||||
0, "%", "heating pump modulation", "",
|
||||
42.7, "°C", "current flow temperature", "",
|
||||
39, "°C", "return temperature", "",
|
||||
1.2, "bar", "system pressure", "",
|
||||
45.3, "°C", "max boiler temperature", "",
|
||||
"off", "", "gas", "",
|
||||
0, "uA", "flame current", "",
|
||||
"off", "", "heating pump", "",
|
||||
"off", "", "fan", "",
|
||||
"off", "", "ignition", "",
|
||||
"on", "", "heating activated", "",
|
||||
75, "°C", "heating temperature", "",
|
||||
90, "%", "burner pump max power", "",
|
||||
55, "%", "burner pump min power", "",
|
||||
1, null, "pump delay", "",
|
||||
10, null, "burner min period", "",
|
||||
0, "%", "burner min power", "",
|
||||
75, "%", "burner max power", "",
|
||||
-6, "°C", "hysteresis on temperature", "",
|
||||
6, "°C", "hysteresis off temperature", "",
|
||||
0, "%", "burner current power", "",
|
||||
295740, "", "burner # starts", "",
|
||||
"344 days 2 hours 8 minutes", null, "total burner operating time", "",
|
||||
"279 days 11 hours 55 minutes", null, "total heat operating time", "",
|
||||
"2946 days 19 hours 8 minutes", null, "total UBA operating time", "",
|
||||
"1C(210) 06.06.2020 12:07", "", "last error code", "",
|
||||
"0H", "", "service code", "",
|
||||
203, "", "service code number", "",
|
||||
"01.01.2012", "", "maintenance set date", "",
|
||||
"off", "", "maintenance scheduled", "",
|
||||
6000, "hours", "maintenance set time", "",
|
||||
60, "°C", "(warm water) selected temperature", "",
|
||||
62, "°C", "(warm water) set temperature", "",
|
||||
"flow", "", "(warm water) type", "",
|
||||
"hot", "", "(warm water) comfort", "",
|
||||
40, "", "(warm water) flow temperature offset", "",
|
||||
100, "%", "(warm water) max power", "",
|
||||
"off", "", "(warm water) circulation pump available", "",
|
||||
"3-way valve", "", "(warm water) charging type", "",
|
||||
70, "°C", "(warm water) disinfection temperature", "",
|
||||
"off", "", "(warm water) circulation pump freq", "",
|
||||
"off", "", "(warm water) circulation active", "",
|
||||
34.7, "°C", "(warm water) current intern temperature", "",
|
||||
0, "l/min", "(warm water) current tap water flow", "",
|
||||
34.6, "°C", "(warm water) storage intern temperature", "",
|
||||
"on", "", "(warm water) activated", "",
|
||||
"off", "", "(warm water) one time charging", "",
|
||||
"off", "", "(warm water) disinfecting", "",
|
||||
"off", "", "(warm water) charging", "",
|
||||
"off", "", "(warm water) recharging", "",
|
||||
"on", "", "(warm water) temperature ok", "",
|
||||
"off", "", "(warm water) active", "",
|
||||
"on", "", "(warm water) heating", "",
|
||||
262387, "", "(warm water) # starts", "",
|
||||
"64 days 14 hours 13 minutes", null, "(warm water) active time", ""
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
@@ -206,6 +252,7 @@ app.post(SIGN_IN_ENDPOINT, (req, res) => { res.json(signin); });
|
||||
app.get(EMSESP_SETTINGS_ENDPOINT, (req, res) => { res.json(emsesp_settings); });
|
||||
app.post(EMSESP_SETTINGS_ENDPOINT, (req, res) => { res.json(emsesp_settings); });
|
||||
app.get(EMSESP_ALLDEVICES_ENDPOINT, (req, res) => { res.json(emsesp_alldevices); });
|
||||
app.post(EMSESP_SCANDEVICES_ENDPOINT, (req, res) => { res.sendStatus(200); });
|
||||
app.get(EMSESP_STATUS_ENDPOINT, (req, res) => { res.json(emsesp_status); });
|
||||
app.post(EMSESP_DEVICEDATA_ENDPOINT, (req, res) => {
|
||||
const id = req.body.id;
|
||||
@@ -216,6 +263,15 @@ app.post(EMSESP_DEVICEDATA_ENDPOINT, (req, res) => {
|
||||
res.json(emsesp_devicedata_2);
|
||||
}
|
||||
});
|
||||
|
||||
app.post(WRITE_VALUE_ENDPOINT, (req, res) => {
|
||||
const devicevalue = req.body.devicevalue;
|
||||
|
||||
console.log(devicevalue);
|
||||
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
app.post(EMSESP_BOARDPROFILE_ENDPOINT, (req, res) => {
|
||||
const board_profile = req.body.code;
|
||||
|
||||
|
||||
@@ -28,10 +28,6 @@ WebAPIService::WebAPIService(AsyncWebServer * server) {
|
||||
|
||||
// e.g. http://ems-esp/api?device=boiler&cmd=wwtemp&data=20&id=1
|
||||
void WebAPIService::webAPIService(AsyncWebServerRequest * request) {
|
||||
// see if the API is enabled
|
||||
bool api_enabled;
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) { api_enabled = settings.api_enabled; });
|
||||
|
||||
// must have device and cmd parameters
|
||||
if ((!request->hasParam(F_(device))) || (!request->hasParam(F_(cmd)))) {
|
||||
request->send(400, "text/plain", F("Invalid syntax"));
|
||||
@@ -77,8 +73,10 @@ void WebAPIService::webAPIService(AsyncWebServerRequest * request) {
|
||||
if (data.isEmpty()) {
|
||||
ok = Command::call(device_type, cmd.c_str(), nullptr, id.toInt(), json); // command only
|
||||
} else {
|
||||
if (api_enabled) {
|
||||
// we only allow commands with parameters if the API is enabled
|
||||
bool api_enabled;
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) { api_enabled = settings.api_enabled; });
|
||||
if (api_enabled) {
|
||||
ok = Command::call(device_type, cmd.c_str(), data.c_str(), id.toInt(), json); // has cmd, data and id
|
||||
} else {
|
||||
request->send(401, "text/plain", F("Unauthorized"));
|
||||
|
||||
@@ -23,14 +23,18 @@ namespace emsesp {
|
||||
using namespace std::placeholders; // for `_1` etc
|
||||
|
||||
WebDevicesService::WebDevicesService(AsyncWebServer * server, SecurityManager * securityManager)
|
||||
: _device_dataHandler(DEVICE_DATA_SERVICE_PATH, securityManager->wrapCallback(std::bind(&WebDevicesService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED)) {
|
||||
: _device_dataHandler(DEVICE_DATA_SERVICE_PATH, securityManager->wrapCallback(std::bind(&WebDevicesService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED))
|
||||
, _writevalue_dataHandler(WRITE_VALUE_SERVICE_PATH, securityManager->wrapCallback(std::bind(&WebDevicesService::write_value, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED)) {
|
||||
server->on(EMSESP_DEVICES_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebDevicesService::all_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||
|
||||
server->on(SCAN_DEVICES_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebDevicesService::scan_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||
|
||||
_device_dataHandler.setMethod(HTTP_POST);
|
||||
_device_dataHandler.setMaxContentLength(256);
|
||||
server->addHandler(&_device_dataHandler);
|
||||
|
||||
_writevalue_dataHandler.setMethod(HTTP_POST);
|
||||
_writevalue_dataHandler.setMaxContentLength(256);
|
||||
server->addHandler(&_writevalue_dataHandler);
|
||||
}
|
||||
|
||||
void WebDevicesService::scan_devices(AsyncWebServerRequest * request) {
|
||||
@@ -96,4 +100,49 @@ void WebDevicesService::device_data(AsyncWebServerRequest * request, JsonVariant
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
// takes a command and its data value from a specific Device, from the Web
|
||||
void WebDevicesService::write_value(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
// only issue commands if the API is enabled
|
||||
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||
if (!settings.api_enabled) {
|
||||
request->send(403); // forbidden error
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject dv = json["devicevalue"];
|
||||
|
||||
// using the unique ID from the web find the real device type
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice) {
|
||||
if (emsdevice->unique_id() == dv["id"].as<int>()) {
|
||||
const char * cmd = dv["cmd"];
|
||||
uint8_t device_type = emsdevice->device_type();
|
||||
bool ok = false;
|
||||
char s[10];
|
||||
// the data could be in any format, but we need string
|
||||
JsonVariant data = dv["data"];
|
||||
if (data.is<char *>()) {
|
||||
ok = Command::call(device_type, cmd, data.as<const char *>());
|
||||
} else if (data.is<int>()) {
|
||||
ok = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int16_t>(), 0));
|
||||
} else if (data.is<float>()) {
|
||||
ok = Command::call(device_type, cmd, Helpers::render_value(s, (float)data.as<float>(), 1));
|
||||
} else if (data.is<bool>()) {
|
||||
ok = Command::call(device_type, cmd, data.as<bool>() ? "true" : "false");
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
request->send(200);
|
||||
}
|
||||
return; // found device, quit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
request->send(204); // no content error
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
@@ -27,6 +27,8 @@
|
||||
#define EMSESP_DEVICES_SERVICE_PATH "/rest/allDevices"
|
||||
#define SCAN_DEVICES_SERVICE_PATH "/rest/scanDevices"
|
||||
#define DEVICE_DATA_SERVICE_PATH "/rest/deviceData"
|
||||
#define WRITE_VALUE_SERVICE_PATH "/rest/writeValue"
|
||||
|
||||
|
||||
namespace emsesp {
|
||||
|
||||
@@ -35,11 +37,15 @@ class WebDevicesService {
|
||||
WebDevicesService(AsyncWebServer * server, SecurityManager * securityManager);
|
||||
|
||||
private:
|
||||
// GET
|
||||
void all_devices(AsyncWebServerRequest * request);
|
||||
void scan_devices(AsyncWebServerRequest * request);
|
||||
void device_data(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
|
||||
AsyncCallbackJsonWebHandler _device_dataHandler;
|
||||
// POST
|
||||
void device_data(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
void write_value(AsyncWebServerRequest * request, JsonVariant & json);
|
||||
|
||||
AsyncCallbackJsonWebHandler _device_dataHandler, _writevalue_dataHandler;
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -30,14 +30,15 @@ std::vector<Command::CmdFunction> Command::cmdfunctions_;
|
||||
// id may be used to represent a heating circuit for example, it's optional
|
||||
// returns false if error or not found
|
||||
bool Command::call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id) {
|
||||
std::string dname = EMSdevice::device_type_2_device_name(device_type);
|
||||
|
||||
auto cf = find_command(device_type, cmd);
|
||||
if ((cf == nullptr) || (cf->cmdfunction_json_)) {
|
||||
LOG_WARNING(F("Command %s not found"), cmd);
|
||||
LOG_WARNING(F("Command %s on %s not found"), cmd, dname.c_str());
|
||||
return false; // command not found, or requires a json
|
||||
}
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
std::string dname = EMSdevice::device_type_2_device_name(device_type);
|
||||
if (value == nullptr) {
|
||||
LOG_DEBUG(F("[DEBUG] Calling %s command %s"), dname.c_str(), cmd);
|
||||
} else if (id == -1) {
|
||||
@@ -54,14 +55,15 @@ bool Command::call(const uint8_t device_type, const char * cmd, const char * val
|
||||
// id may be used to represent a heating circuit for example
|
||||
// returns false if error or not found
|
||||
bool Command::call(const uint8_t device_type, const char * cmd, const char * value, const int8_t id, JsonObject & json) {
|
||||
std::string dname = EMSdevice::device_type_2_device_name(device_type);
|
||||
|
||||
auto cf = find_command(device_type, cmd);
|
||||
if (cf == nullptr) {
|
||||
LOG_WARNING(F("Command %s not found"), cmd);
|
||||
LOG_WARNING(F("Command %s on %s not found"), cmd, dname.c_str());
|
||||
return false; // command not found or not json
|
||||
}
|
||||
|
||||
#ifdef EMSESP_DEBUG
|
||||
std::string dname = EMSdevice::device_type_2_device_name(device_type);
|
||||
if (value == nullptr) {
|
||||
LOG_DEBUG(F("[DEBUG] Calling %s command %s"), dname.c_str(), cmd);
|
||||
} else if (id == -1) {
|
||||
@@ -110,6 +112,7 @@ void Command::add_with_json(const uint8_t device_type, const __FlashStringHelper
|
||||
}
|
||||
|
||||
// see if a command exists for that device type
|
||||
// is not case sensitive
|
||||
Command::CmdFunction * Command::find_command(const uint8_t device_type, const char * cmd) {
|
||||
if ((cmd == nullptr) || (strlen(cmd) == 0) || (cmdfunctions_.empty())) {
|
||||
return nullptr;
|
||||
|
||||
@@ -41,7 +41,7 @@ class Command {
|
||||
public:
|
||||
struct CmdFunction {
|
||||
uint8_t device_type_; // DeviceType::
|
||||
uint8_t flag_;
|
||||
uint8_t flag_; // mqtt flags for command subscriptions
|
||||
const __FlashStringHelper * cmd_;
|
||||
cmdfunction_p cmdfunction_;
|
||||
cmdfunction_json_p cmdfunction_json_;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
// Boilers - 0x08
|
||||
{ 64, DeviceType::BOILER, F("BK13/BK15/Smartline/GB1x2"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 72, DeviceType::BOILER, F("GB125/MC10"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 72, DeviceType::BOILER, F("GB125/MC10"), DeviceFlags::EMS_DEVICE_FLAG_EMS},
|
||||
{ 84, DeviceType::BOILER, F("Logamax Plus GB022"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{ 95, DeviceType::BOILER, F("Condens 2500/Logamax/Logomatic/Cerapur Top/Greenstar/Generic HT3"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
{115, DeviceType::BOILER, F("Topline/GB162"), DeviceFlags::EMS_DEVICE_FLAG_NONE},
|
||||
@@ -68,13 +68,13 @@
|
||||
{203, DeviceType::THERMOSTAT, F("EasyControl CT200"), DeviceFlags::EMS_DEVICE_FLAG_EASY | DeviceFlags::EMS_DEVICE_FLAG_NO_WRITE}, // 0x18, cannot write
|
||||
|
||||
// Thermostat - Buderus/Nefit/Bosch specific - 0x17 / 0x10 / 0x18 / 0x19 / 0x38
|
||||
{ 67, DeviceType::THERMOSTAT, F("RC30"), DeviceFlags::EMS_DEVICE_FLAG_RC30_1},// 0x10 - based on RC35
|
||||
{ 67, DeviceType::THERMOSTAT, F("RC30"), DeviceFlags::EMS_DEVICE_FLAG_RC30_N},// 0x10 - based on RC35
|
||||
{ 77, DeviceType::THERMOSTAT, F("RC20/Moduline 300"), DeviceFlags::EMS_DEVICE_FLAG_RC20},// 0x17
|
||||
{ 78, DeviceType::THERMOSTAT, F("Moduline 400"), DeviceFlags::EMS_DEVICE_FLAG_RC30}, // 0x10
|
||||
{ 79, DeviceType::THERMOSTAT, F("RC10/Moduline 100"), DeviceFlags::EMS_DEVICE_FLAG_RC10},// 0x17
|
||||
{ 80, DeviceType::THERMOSTAT, F("Moduline 200"), DeviceFlags::EMS_DEVICE_FLAG_RC10}, // 0x17
|
||||
{ 86, DeviceType::THERMOSTAT, F("RC35"), DeviceFlags::EMS_DEVICE_FLAG_RC35}, // 0x10
|
||||
{ 90, DeviceType::THERMOSTAT, F("RC10/Moduline 100"), DeviceFlags::EMS_DEVICE_FLAG_RC20_2}, // 0x17
|
||||
{ 90, DeviceType::THERMOSTAT, F("RC10/Moduline 100"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17
|
||||
{ 93, DeviceType::THERMOSTAT, F("RC20RF"), DeviceFlags::EMS_DEVICE_FLAG_RC20}, // 0x19
|
||||
{ 94, DeviceType::THERMOSTAT, F("RFM20 Remote"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x18
|
||||
{157, DeviceType::THERMOSTAT, F("RC200/CW100"), DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18
|
||||
@@ -82,9 +82,9 @@
|
||||
{165, DeviceType::THERMOSTAT, F("RC100/Moduline 1000/1010"), DeviceFlags::EMS_DEVICE_FLAG_RC100}, // 0x18, 0x38
|
||||
|
||||
// Thermostat - Sieger - 0x10 / 0x17
|
||||
{ 66, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_2}, // 0x17 or remote
|
||||
{ 66, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17 or remote
|
||||
{ 76, DeviceType::THERMOSTAT, F("ES73"), DeviceFlags::EMS_DEVICE_FLAG_RC35}, // 0x10
|
||||
{113, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_2}, // 0x17
|
||||
{113, DeviceType::THERMOSTAT, F("ES72/RC20"), DeviceFlags::EMS_DEVICE_FLAG_RC20_N}, // 0x17
|
||||
|
||||
// Thermostat - Junkers - 0x10
|
||||
{105, DeviceType::THERMOSTAT, F("FW100"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS},
|
||||
|
||||
@@ -48,64 +48,50 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
reserve_telgram_functions(25); // reserve some space for the telegram registries, to avoid memory fragmentation
|
||||
|
||||
// the telegram handlers...
|
||||
// common for all boilers
|
||||
register_telegram_type(0x10, F("UBAErrorMessage1"), false, MAKE_PF_CB(process_UBAErrorMessage));
|
||||
register_telegram_type(0x11, F("UBAErrorMessage2"), false, MAKE_PF_CB(process_UBAErrorMessage));
|
||||
register_telegram_type(0x14, F("UBATotalUptime"), true, MAKE_PF_CB(process_UBATotalUptime));
|
||||
register_telegram_type(0x15, F("UBAMaintenanceData"), false, MAKE_PF_CB(process_UBAMaintenanceData));
|
||||
register_telegram_type(0x16, F("UBAParameters"), true, MAKE_PF_CB(process_UBAParameters));
|
||||
register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, MAKE_PF_CB(process_UBAMaintenanceStatus));
|
||||
// EMS1.0 and maybe EMS+?
|
||||
register_telegram_type(0x18, F("UBAMonitorFast"), false, MAKE_PF_CB(process_UBAMonitorFast));
|
||||
register_telegram_type(0x19, F("UBAMonitorSlow"), true, MAKE_PF_CB(process_UBAMonitorSlow));
|
||||
register_telegram_type(0x1A, F("UBASetPoints"), false, MAKE_PF_CB(process_UBASetPoints));
|
||||
register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, MAKE_PF_CB(process_UBAMaintenanceStatus));
|
||||
register_telegram_type(0x26, F("UBASettingsWW"), true, MAKE_PF_CB(process_UBASettingsWW));
|
||||
register_telegram_type(0x2A, F("MC10Status"), false, MAKE_PF_CB(process_MC10Status));
|
||||
register_telegram_type(0x35, F("UBAFlags"), false, MAKE_PF_CB(process_UBAFlags));
|
||||
// only EMS 1.0
|
||||
register_telegram_type(0x16, F("UBAParameters"), true, MAKE_PF_CB(process_UBAParameters));
|
||||
register_telegram_type(0x33, F("UBAParameterWW"), true, MAKE_PF_CB(process_UBAParameterWW));
|
||||
register_telegram_type(0x34, F("UBAMonitorWW"), false, MAKE_PF_CB(process_UBAMonitorWW));
|
||||
register_telegram_type(0x35, F("UBAFlags"), false, MAKE_PF_CB(process_UBAFlags));
|
||||
// only EMS+
|
||||
if ((flags & 0x0F) != EMSdevice::EMS_DEVICE_FLAG_EMS) {
|
||||
register_telegram_type(0x1A, F("UBASetPoints"), false, MAKE_PF_CB(process_UBASetPoints));
|
||||
register_telegram_type(0x26, F("UBASettingsWW"), true, MAKE_PF_CB(process_UBASettingsWW));
|
||||
register_telegram_type(0x2A, F("MC110Status"), false, MAKE_PF_CB(process_MC110Status));
|
||||
register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, MAKE_PF_CB(process_UBAOutdoorTemp));
|
||||
register_telegram_type(0xE3, F("UBAMonitorSlowPlus"), false, MAKE_PF_CB(process_UBAMonitorSlowPlus2));
|
||||
register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, MAKE_PF_CB(process_UBAMonitorFastPlus));
|
||||
register_telegram_type(0xE5, F("UBAMonitorSlowPlus"), false, MAKE_PF_CB(process_UBAMonitorSlowPlus));
|
||||
register_telegram_type(0xE6, F("UBAParametersPlus"), true, MAKE_PF_CB(process_UBAParametersPlus));
|
||||
register_telegram_type(0xE9, F("UBADHWStatus"), false, MAKE_PF_CB(process_UBADHWStatus));
|
||||
register_telegram_type(0xE9, F("UBAMonitorWWPlus"), false, MAKE_PF_CB(process_UBAMonitorWWPlus));
|
||||
register_telegram_type(0xEA, F("UBAParameterWWPlus"), true, MAKE_PF_CB(process_UBAParameterWWPlus));
|
||||
register_telegram_type(0x494, F("UBAEnergySupplied"), false, MAKE_PF_CB(process_UBAEnergySupplied));
|
||||
register_telegram_type(0x495, F("UBAInformation"), false, MAKE_PF_CB(process_UBAInformation));
|
||||
}
|
||||
|
||||
// MQTT commands for boiler topic
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWComfort), MAKE_CF_CB(set_warmwater_mode));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWActivated), MAKE_CF_CB(set_warmwater_activated));
|
||||
register_mqtt_cmd(F_(wwtapactivated), MAKE_CF_CB(set_tapwarmwater_activated));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWFlowTempOffset), MAKE_CF_CB(set_wWFlowTempOffset));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWMaxPower), MAKE_CF_CB(set_warmwater_maxpower));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWOneTime), MAKE_CF_CB(set_warmwater_onetime));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWCircPump), MAKE_CF_CB(set_warmwater_circulation_pump));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWCirc), MAKE_CF_CB(set_warmwater_circulation));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWCircMode), MAKE_CF_CB(set_warmwater_circulation_mode));
|
||||
register_mqtt_cmd(MQTT_TOPIC(selFlowTemp), MAKE_CF_CB(set_flow_temp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWSetTemp), MAKE_CF_CB(set_warmwater_temp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(heatingActivated), MAKE_CF_CB(set_heating_activated));
|
||||
register_mqtt_cmd(MQTT_TOPIC(heatingTemp), MAKE_CF_CB(set_heating_temp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(burnMaxPower), MAKE_CF_CB(set_max_power));
|
||||
register_mqtt_cmd(MQTT_TOPIC(burnMinPower), MAKE_CF_CB(set_min_power));
|
||||
register_mqtt_cmd(MQTT_TOPIC(boilHystOn), MAKE_CF_CB(set_hyst_on));
|
||||
register_mqtt_cmd(MQTT_TOPIC(boilHystOff), MAKE_CF_CB(set_hyst_off));
|
||||
register_mqtt_cmd(MQTT_TOPIC(burnPeriod), MAKE_CF_CB(set_burn_period));
|
||||
register_mqtt_cmd(MQTT_TOPIC(pumpDelay), MAKE_CF_CB(set_pump_delay));
|
||||
register_mqtt_cmd(F_(maintenance), MAKE_CF_CB(set_maintenance));
|
||||
register_mqtt_cmd(MQTT_TOPIC(pumpModMax), MAKE_CF_CB(set_max_pump));
|
||||
register_mqtt_cmd(MQTT_TOPIC(pumpModMin), MAKE_CF_CB(set_min_pump));
|
||||
register_mqtt_cmd(F_(reset), MAKE_CF_CB(set_reset));
|
||||
register_cmd(MQTT_TOPIC(wwtapactivated), MAKE_CF_CB(set_tapwarmwater_activated));
|
||||
register_cmd(MQTT_TOPIC(reset), MAKE_CF_CB(set_reset));
|
||||
|
||||
// add values
|
||||
reserve_device_values(50);
|
||||
|
||||
// main - boiler_data topic
|
||||
register_device_value(TAG_BOILER_DATA, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_BOILER_DATA, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr, DeviceValueUOM::NONE); // empty full name to prevent being shown in web or console
|
||||
id_ = product_id;
|
||||
|
||||
register_device_value(TAG_BOILER_DATA, &heatingActive_, DeviceValueType::BOOL, nullptr, FL_(heatingActive));
|
||||
register_device_value(TAG_BOILER_DATA, &tapwaterActive_, DeviceValueType::BOOL, nullptr, FL_(tapwaterActive));
|
||||
register_device_value(TAG_BOILER_DATA, &selFlowTemp_, DeviceValueType::UINT, nullptr, FL_(selFlowTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA, &heatingActive_, DeviceValueType::BOOL, nullptr, FL_(heatingActive), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &tapwaterActive_, DeviceValueType::BOOL, nullptr, FL_(tapwaterActive), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &selFlowTemp_, DeviceValueType::UINT, nullptr, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp));
|
||||
register_device_value(TAG_BOILER_DATA, &selBurnPow_, DeviceValueType::UINT, nullptr, FL_(selBurnPow), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &heatingPumpMod_, DeviceValueType::UINT, nullptr, FL_(heatingPumpMod), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &heatingPump2Mod_, DeviceValueType::UINT, nullptr, FL_(heatingPump2Mod), DeviceValueUOM::PERCENT);
|
||||
@@ -116,85 +102,85 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
register_device_value(TAG_BOILER_DATA, &sysPress_, DeviceValueType::UINT, FL_(div10), FL_(sysPress), DeviceValueUOM::BAR);
|
||||
register_device_value(TAG_BOILER_DATA, &boilTemp_, DeviceValueType::USHORT, FL_(div10), FL_(boilTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA, &exhaustTemp_, DeviceValueType::USHORT, FL_(div10), FL_(exhaustTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA, &burnGas_, DeviceValueType::BOOL, nullptr, FL_(burnGas));
|
||||
register_device_value(TAG_BOILER_DATA, &burnGas_, DeviceValueType::BOOL, nullptr, FL_(burnGas), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &flameCurr_, DeviceValueType::USHORT, FL_(div10), FL_(flameCurr), DeviceValueUOM::UA);
|
||||
register_device_value(TAG_BOILER_DATA, &heatingPump_, DeviceValueType::BOOL, nullptr, FL_(heatingPump), DeviceValueUOM::PUMP);
|
||||
register_device_value(TAG_BOILER_DATA, &fanWork_, DeviceValueType::BOOL, nullptr, FL_(fanWork));
|
||||
register_device_value(TAG_BOILER_DATA, &ignWork_, DeviceValueType::BOOL, nullptr, FL_(ignWork));
|
||||
register_device_value(TAG_BOILER_DATA, &heatingActivated_, DeviceValueType::BOOL, nullptr, FL_(heatingActivated));
|
||||
register_device_value(TAG_BOILER_DATA, &heatingTemp_, DeviceValueType::UINT, nullptr, FL_(heatingTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA, &pumpModMax_, DeviceValueType::UINT, nullptr, FL_(pumpModMax), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &pumpModMin_, DeviceValueType::UINT, nullptr, FL_(pumpModMin), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &pumpDelay_, DeviceValueType::UINT, nullptr, FL_(pumpDelay), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &burnMinPeriod_, DeviceValueType::UINT, nullptr, FL_(burnMinPeriod), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &burnMinPower_, DeviceValueType::UINT, nullptr, FL_(burnMinPower), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &burnMaxPower_, DeviceValueType::UINT, nullptr, FL_(burnMaxPower), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &boilHystOn_, DeviceValueType::INT, nullptr, FL_(boilHystOn), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA, &boilHystOff_, DeviceValueType::INT, nullptr, FL_(boilHystOff), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA, &fanWork_, DeviceValueType::BOOL, nullptr, FL_(fanWork), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &ignWork_, DeviceValueType::BOOL, nullptr, FL_(ignWork), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &heatingActivated_, DeviceValueType::BOOL, nullptr, FL_(heatingActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_heating_activated));
|
||||
register_device_value(TAG_BOILER_DATA, &heatingTemp_, DeviceValueType::UINT, nullptr, FL_(heatingTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heating_temp));
|
||||
register_device_value(TAG_BOILER_DATA, &pumpModMax_, DeviceValueType::UINT, nullptr, FL_(pumpModMax), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_pump));
|
||||
register_device_value(TAG_BOILER_DATA, &pumpModMin_, DeviceValueType::UINT, nullptr, FL_(pumpModMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_pump));
|
||||
register_device_value(TAG_BOILER_DATA, &pumpDelay_, DeviceValueType::UINT, nullptr, FL_(pumpDelay), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_pump_delay));
|
||||
register_device_value(TAG_BOILER_DATA, &burnMinPeriod_, DeviceValueType::UINT, nullptr, FL_(burnMinPeriod), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_burn_period));
|
||||
register_device_value(TAG_BOILER_DATA, &burnMinPower_, DeviceValueType::UINT, nullptr, FL_(burnMinPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_power));
|
||||
register_device_value(TAG_BOILER_DATA, &burnMaxPower_, DeviceValueType::UINT, nullptr, FL_(burnMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_power));
|
||||
register_device_value(TAG_BOILER_DATA, &boilHystOn_, DeviceValueType::INT, nullptr, FL_(boilHystOn), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_hyst_on));
|
||||
register_device_value(TAG_BOILER_DATA, &boilHystOff_, DeviceValueType::INT, nullptr, FL_(boilHystOff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_hyst_off));
|
||||
register_device_value(TAG_BOILER_DATA, &setFlowTemp_, DeviceValueType::UINT, nullptr, FL_(setFlowTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA, &setBurnPow_, DeviceValueType::UINT, nullptr, FL_(setBurnPow), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &curBurnPow_, DeviceValueType::UINT, nullptr, FL_(curBurnPow), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA, &burnStarts_, DeviceValueType::ULONG, nullptr, FL_(burnStarts));
|
||||
register_device_value(TAG_BOILER_DATA, &burnStarts_, DeviceValueType::ULONG, nullptr, FL_(burnStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &burnWorkMin_, DeviceValueType::TIME, nullptr, FL_(burnWorkMin), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &heatWorkMin_, DeviceValueType::TIME, nullptr, FL_(heatWorkMin), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &UBAuptime_, DeviceValueType::TIME, nullptr, FL_(UBAuptime), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &lastCode_, DeviceValueType::TEXT, nullptr, FL_(lastCode));
|
||||
register_device_value(TAG_BOILER_DATA, &serviceCode_, DeviceValueType::TEXT, nullptr, FL_(serviceCode));
|
||||
register_device_value(TAG_BOILER_DATA, &serviceCodeNumber_, DeviceValueType::USHORT, nullptr, FL_(serviceCodeNumber));
|
||||
register_device_value(TAG_BOILER_DATA, &lastCode_, DeviceValueType::TEXT, nullptr, FL_(lastCode), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &serviceCode_, DeviceValueType::TEXT, nullptr, FL_(serviceCode), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &serviceCodeNumber_, DeviceValueType::USHORT, nullptr, FL_(serviceCodeNumber), DeviceValueUOM::NONE);
|
||||
|
||||
register_device_value(TAG_BOILER_DATA, &upTimeControl_, DeviceValueType::TIME, FL_(div60), FL_(upTimeControl), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &upTimeCompHeating_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompHeating), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &upTimeCompCooling_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompCooling), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &upTimeCompWw_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompWw), DeviceValueUOM::MINUTES);
|
||||
register_device_value(TAG_BOILER_DATA, &heatingStarts_, DeviceValueType::ULONG, nullptr, FL_(heatingStarts));
|
||||
register_device_value(TAG_BOILER_DATA, &coolingStarts_, DeviceValueType::ULONG, nullptr, FL_(coolingStarts));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsTotal));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompTotal));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompHeating_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompHeating));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompWw_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompWw));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompCooling));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppTotal));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppHeating));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppWw_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppWw));
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppCooling));
|
||||
register_device_value(TAG_BOILER_DATA, &auxElecHeatNrgConsTotal_, DeviceValueType::ULONG, nullptr, FL_(auxElecHeatNrgConsTotal));
|
||||
register_device_value(TAG_BOILER_DATA, &auxElecHeatNrgConsHeating_, DeviceValueType::ULONG, nullptr, FL_(auxElecHeatNrgConsHeating));
|
||||
register_device_value(TAG_BOILER_DATA, &auxElecHeatNrgConsDHW_, DeviceValueType::ULONG, nullptr, FL_(auxElecHeatNrgConsDHW));
|
||||
register_device_value(TAG_BOILER_DATA, &maintenanceMessage_, DeviceValueType::TEXT, nullptr, FL_(maintenanceMessage));
|
||||
register_device_value(TAG_BOILER_DATA, &maintenanceDate_, DeviceValueType::TEXT, nullptr, FL_(maintenanceDate));
|
||||
register_device_value(TAG_BOILER_DATA, &maintenanceType_, DeviceValueType::ENUM, FL_(enum_off_time_date), FL_(maintenanceType));
|
||||
register_device_value(TAG_BOILER_DATA, &heatingStarts_, DeviceValueType::ULONG, nullptr, FL_(heatingStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &coolingStarts_, DeviceValueType::ULONG, nullptr, FL_(coolingStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsTotal), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompTotal), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompHeating_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompHeating), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompWw_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompWw), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgConsCompCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompCooling), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppTotal), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppHeating), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppWw_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppWw), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppCooling), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &auxElecHeatNrgConsTotal_, DeviceValueType::ULONG, nullptr, FL_(auxElecHeatNrgConsTotal), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &auxElecHeatNrgConsHeating_, DeviceValueType::ULONG, nullptr, FL_(auxElecHeatNrgConsHeating), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &auxElecHeatNrgConsDHW_, DeviceValueType::ULONG, nullptr, FL_(auxElecHeatNrgConsDHW), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &maintenanceMessage_, DeviceValueType::TEXT, nullptr, FL_(maintenanceMessage), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &maintenanceDate_, DeviceValueType::TEXT, nullptr, FL_(maintenanceDate), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA, &maintenanceType_, DeviceValueType::ENUM, FL_(enum_off_time_date), FL_(maintenance), DeviceValueUOM::NONE, MAKE_CF_CB(set_maintenance));
|
||||
register_device_value(TAG_BOILER_DATA, &maintenanceTime_, DeviceValueType::USHORT, nullptr, FL_(maintenanceTime), DeviceValueUOM::HOURS);
|
||||
|
||||
// warm water - boiler_data_ww topic
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWSelTemp_, DeviceValueType::UINT, nullptr, FL_(wWSelTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWSetTemp_, DeviceValueType::UINT, nullptr, FL_(wWSetTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWType_, DeviceValueType::ENUM, FL_(enum_flow), FL_(wWType));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWComfort_, DeviceValueType::ENUM, FL_(enum_comfort), FL_(wWComfort));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWFlowTempOffset_, DeviceValueType::UINT, nullptr, FL_(wWFlowTempOffset));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWMaxPower_, DeviceValueType::UINT, nullptr, FL_(wWMaxPower), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCircPump_, DeviceValueType::BOOL, nullptr, FL_(wWCircPump));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWChargeType_, DeviceValueType::BOOL, FL_(enum_charge), FL_(wWChargeType));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWDisinfectionTemp_, DeviceValueType::UINT, nullptr, FL_(wWDisinfectionTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCircMode_, DeviceValueType::ENUM, FL_(enum_freq), FL_(wWCircMode));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCirc_, DeviceValueType::BOOL, nullptr, FL_(wWCirc));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWSetTemp_, DeviceValueType::UINT, nullptr, FL_(wWSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_warmwater_temp));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWType_, DeviceValueType::ENUM, FL_(enum_flow), FL_(wWType), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWComfort_, DeviceValueType::ENUM, FL_(enum_comfort), FL_(wWComfort), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_mode));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWFlowTempOffset_, DeviceValueType::UINT, nullptr, FL_(wWFlowTempOffset), DeviceValueUOM::NONE, MAKE_CF_CB(set_wWFlowTempOffset));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWMaxPower_, DeviceValueType::UINT, nullptr, FL_(wWMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_warmwater_maxpower));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCircPump_, DeviceValueType::BOOL, nullptr, FL_(wWCircPump), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_circulation_pump));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWChargeType_, DeviceValueType::BOOL, FL_(enum_charge), FL_(wWChargeType), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWDisinfectionTemp_, DeviceValueType::UINT, nullptr, FL_(wWDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_disinfect_temp));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCircMode_, DeviceValueType::ENUM, FL_(enum_freq), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_circulation_mode));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCirc_, DeviceValueType::BOOL, nullptr, FL_(wWCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_circulation));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCurTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wWCurTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCurTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wWCurTemp2), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCurFlow_, DeviceValueType::UINT, FL_(div10), FL_(wWCurFlow), DeviceValueUOM::LMIN);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWStorageTemp1_, DeviceValueType::USHORT, FL_(div10), FL_(wWStorageTemp1), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWStorageTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wWStorageTemp2), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWActivated_, DeviceValueType::BOOL, nullptr, FL_(wWActivated));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWOneTime_, DeviceValueType::BOOL, nullptr, FL_(wWOneTime));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWDisinfecting_, DeviceValueType::BOOL, nullptr, FL_(wWDisinfecting));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCharging_, DeviceValueType::BOOL, nullptr, FL_(wWCharging));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWRecharging_, DeviceValueType::BOOL, nullptr, FL_(wWRecharging));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWTempOK_, DeviceValueType::BOOL, nullptr, FL_(wWTempOK));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWActive_, DeviceValueType::BOOL, nullptr, FL_(wWActive));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWHeat_, DeviceValueType::BOOL, nullptr, FL_(wWHeat));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWActivated_, DeviceValueType::BOOL, nullptr, FL_(wWActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_activated));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWOneTime_, DeviceValueType::BOOL, nullptr, FL_(wWOneTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_onetime));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWDisinfecting_, DeviceValueType::BOOL, nullptr, FL_(wWDisinfecting), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWCharging_, DeviceValueType::BOOL, nullptr, FL_(wWCharging), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWRecharging_, DeviceValueType::BOOL, nullptr, FL_(wWRecharging), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWTempOK_, DeviceValueType::BOOL, nullptr, FL_(wWTempOK), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWActive_, DeviceValueType::BOOL, nullptr, FL_(wWActive), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWHeat_, DeviceValueType::BOOL, nullptr, FL_(wWHeat), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWSetPumpPower_, DeviceValueType::UINT, nullptr, FL_(wWSetPumpPower), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &mixerTemp_, DeviceValueType::USHORT, FL_(div10), FL_(mixerTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &tankMiddleTemp_, DeviceValueType::USHORT, FL_(div10), FL_(tankMiddleTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWStarts_, DeviceValueType::ULONG, nullptr, FL_(wWStarts));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWStarts2_, DeviceValueType::ULONG, nullptr, FL_(wWStarts2));
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWStarts_, DeviceValueType::ULONG, nullptr, FL_(wWStarts), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWStarts2_, DeviceValueType::ULONG, nullptr, FL_(wWStarts2), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_BOILER_DATA_WW, &wWWorkM_, DeviceValueType::TIME, nullptr, FL_(wWWorkM), DeviceValueUOM::MINUTES);
|
||||
|
||||
// fetch some initial data
|
||||
@@ -514,9 +500,9 @@ void Boiler::process_UBAParameterWWPlus(std::shared_ptr<const Telegram> telegram
|
||||
// has_update(telegram->read_value(wWSelTemp_, 6)); // settings, status in E9
|
||||
}
|
||||
|
||||
// 0xE9 - DHW Status
|
||||
// 0xE9 - WW monitor ems+
|
||||
// e.g. 08 00 E9 00 37 01 F6 01 ED 00 00 00 00 41 3C 00 00 00 00 00 00 00 00 00 00 00 00 37 00 00 00 (CRC=77) #data=27
|
||||
void Boiler::process_UBADHWStatus(std::shared_ptr<const Telegram> telegram) {
|
||||
void Boiler::process_UBAMonitorWWPlus(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(wWSetTemp_, 0));
|
||||
has_update(telegram->read_value(wWCurTemp_, 1));
|
||||
has_update(telegram->read_value(wWCurTemp2_, 3));
|
||||
@@ -581,10 +567,10 @@ void Boiler::process_UBAEnergySupplied(std::shared_ptr<const Telegram> telegram)
|
||||
has_update(telegram->read_value(nrgSuppCooling_, 16));
|
||||
}
|
||||
|
||||
// 0x2A - MC10Status
|
||||
// 0x2A - MC110Status
|
||||
// e.g. 88 00 2A 00 00 00 00 00 00 00 00 00 D2 00 00 80 00 00 01 08 80 00 02 47 00
|
||||
// see https://github.com/emsesp/EMS-ESP/issues/397
|
||||
void Boiler::process_MC10Status(std::shared_ptr<const Telegram> telegram) {
|
||||
void Boiler::process_MC110Status(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(mixerTemp_, 14));
|
||||
has_update(telegram->read_value(tankMiddleTemp_, 18));
|
||||
}
|
||||
@@ -598,8 +584,7 @@ void Boiler::process_UBAOutdoorTemp(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
// UBASetPoint 0x1A
|
||||
void Boiler::process_UBASetPoints(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(setFlowTemp_,
|
||||
0)); // boiler set temp from thermostat
|
||||
has_update(telegram->read_value(setFlowTemp_, 0)); // boiler set temp from thermostat
|
||||
has_update(telegram->read_value(setBurnPow_, 1)); // max json power in %
|
||||
has_update(telegram->read_value(wWSetPumpPower_, 2)); // ww pump speed/power?
|
||||
}
|
||||
@@ -618,6 +603,7 @@ void Boiler::process_CascadeMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// 0x35 - not yet implemented
|
||||
void Boiler::process_UBAFlags(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// 0x1C
|
||||
@@ -706,6 +692,23 @@ bool Boiler::set_warmwater_temp(const char * value, const int8_t id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set the warm water disinfection temperature
|
||||
bool Boiler::set_disinfect_temp(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
LOG_WARNING(F("Set boiler warm water disinfect temperature: Invalid value"));
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler warm water disinfect temperature to %d C"), v);
|
||||
if (get_toggle_fetch(EMS_TYPE_UBAParametersPlus)) {
|
||||
write_command(EMS_TYPE_UBAParameterWWPlus, 12, v, EMS_TYPE_UBAParameterWWPlus);
|
||||
} else {
|
||||
write_command(EMS_TYPE_UBAParameterWW, 8, v, EMS_TYPE_UBAParameterWW);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// flow temp
|
||||
bool Boiler::set_flow_temp(const char * value, const int8_t id) {
|
||||
int v = 0;
|
||||
|
||||
@@ -161,11 +161,11 @@ class Boiler : public EMSdevice {
|
||||
void process_UBAOutdoorTemp(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBASetPoints(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAFlags(std::shared_ptr<const Telegram> telegram);
|
||||
void process_MC10Status(std::shared_ptr<const Telegram> telegram);
|
||||
void process_MC110Status(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAMaintenanceStatus(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAMaintenanceData(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBADHWStatus(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAMonitorWWPlus(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAInformation(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAEnergySupplied(std::shared_ptr<const Telegram> telegram);
|
||||
void process_CascadeMessage(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -180,6 +180,7 @@ class Boiler : public EMSdevice {
|
||||
bool set_warmwater_circulation_pump(const char * value, const int8_t id);
|
||||
bool set_warmwater_circulation_mode(const char * value, const int8_t id);
|
||||
bool set_warmwater_temp(const char * value, const int8_t id);
|
||||
bool set_disinfect_temp(const char * value, const int8_t id);
|
||||
bool set_warmwater_maxpower(const char * value, const int8_t id);
|
||||
bool set_wWFlowTempOffset(const char * value, const int8_t id);
|
||||
bool set_flow_temp(const char * value, const int8_t id);
|
||||
|
||||
@@ -33,7 +33,7 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c
|
||||
register_telegram_type(0x047B, F("HP2"), true, MAKE_PF_CB(process_HPMonitor2));
|
||||
|
||||
// device values
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr, DeviceValueUOM::NONE); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_NONE, &airHumidity_, DeviceValueType::UINT, FL_(div2), FL_(airHumidity), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_NONE, &dewTemperature_, DeviceValueType::UINT, nullptr, FL_(dewTemperature), DeviceValueUOM::DEGREES);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr); // empty full name to prevent being shown in web or console
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr, DeviceValueUOM::NONE); // empty full name to prevent being shown in web or console
|
||||
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::PUMP);
|
||||
@@ -67,10 +67,10 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
type_ = Type::WWC;
|
||||
hc_ = device_id - 0x28 + 1;
|
||||
uint8_t tag = TAG_WWC1 + hc_ - 1;
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr); // empty full name to prevent being shown in web or console
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr, DeviceValueUOM::NONE); // empty full name to prevent being shown in web or console
|
||||
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::PUMP);
|
||||
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(tempStatus));
|
||||
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(tempStatus), DeviceValueUOM::NONE);
|
||||
}
|
||||
|
||||
id_ = product_id;
|
||||
|
||||
@@ -50,8 +50,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
register_telegram_type(0x0380, F("SM100CollectorConfig"), true, MAKE_PF_CB(process_SM100CollectorConfig));
|
||||
register_telegram_type(0x038E, F("SM100Energy"), true, MAKE_PF_CB(process_SM100Energy));
|
||||
register_telegram_type(0x0391, F("SM100Time"), true, MAKE_PF_CB(process_SM100Time));
|
||||
|
||||
register_mqtt_cmd(F("SM100TankBottomMaxTemp"), MAKE_CF_CB(set_SM100TankBottomMaxTemp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,11 +62,11 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
|
||||
// special case for a device_id with 0x2A where it's not actual a solar module
|
||||
if (device_id == 0x2A) {
|
||||
register_device_value(TAG_NONE, &type_, DeviceValueType::TEXT, nullptr, F("type"), F("type"));
|
||||
register_device_value(TAG_NONE, &type_, DeviceValueType::TEXT, nullptr, F("type"), F("type"), DeviceValueUOM::NONE);
|
||||
strncpy(type_, "warm water circuit", sizeof(type_));
|
||||
}
|
||||
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr, DeviceValueUOM::NONE); // empty full name to prevent being shown in web or console
|
||||
id_ = product_id;
|
||||
|
||||
register_device_value(TAG_NONE, &collectorTemp_, DeviceValueType::SHORT, FL_(div10), FL_(collectorTemp), DeviceValueUOM::DEGREES);
|
||||
@@ -76,14 +74,14 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
register_device_value(TAG_NONE, &tankBottomTemp2_, DeviceValueType::SHORT, FL_(div10), FL_(tank2BottomTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_NONE, &heatExchangerTemp_, DeviceValueType::SHORT, FL_(div10), FL_(heatExchangerTemp), DeviceValueUOM::DEGREES);
|
||||
|
||||
register_device_value(TAG_NONE, &tankBottomMaxTemp_, DeviceValueType::UINT, nullptr, FL_(tankMaxTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_NONE, &tankBottomMaxTemp_, DeviceValueType::UINT, nullptr, FL_(tankMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_SM100TankBottomMaxTemp));
|
||||
register_device_value(TAG_NONE, &solarPumpModulation_, DeviceValueType::UINT, nullptr, FL_(solarPumpModulation), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_NONE, &cylinderPumpModulation_, DeviceValueType::UINT, nullptr, FL_(cylinderPumpModulation), DeviceValueUOM::PERCENT);
|
||||
|
||||
register_device_value(TAG_NONE, &solarPump_, DeviceValueType::BOOL, nullptr, FL_(solarPump), DeviceValueUOM::PUMP);
|
||||
register_device_value(TAG_NONE, &valveStatus_, DeviceValueType::BOOL, nullptr, FL_(valveStatus));
|
||||
register_device_value(TAG_NONE, &tankHeated_, DeviceValueType::BOOL, nullptr, FL_(tankHeated));
|
||||
register_device_value(TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown));
|
||||
register_device_value(TAG_NONE, &valveStatus_, DeviceValueType::BOOL, nullptr, FL_(valveStatus), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &tankHeated_, DeviceValueType::BOOL, nullptr, FL_(tankHeated), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE);
|
||||
|
||||
register_device_value(TAG_NONE, &pumpWorkTime_, DeviceValueType::TIME, nullptr, FL_(pumpWorkTime), DeviceValueUOM::MINUTES);
|
||||
|
||||
|
||||
@@ -34,10 +34,10 @@ Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const
|
||||
register_telegram_type(0x9D, F("WM10SetMessage"), false, MAKE_PF_CB(process_WM10SetMessage));
|
||||
register_telegram_type(0x1E, F("WM10TempMessage"), false, MAKE_PF_CB(process_WM10TempMessage));
|
||||
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_NONE, &activated_, DeviceValueType::BOOL, nullptr, FL_(activated));
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr, DeviceValueUOM::NONE); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_NONE, &activated_, DeviceValueType::BOOL, nullptr, FL_(activated), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_NONE, &status_, DeviceValueType::INT, nullptr, FL_(status));
|
||||
register_device_value(TAG_NONE, &status_, DeviceValueType::INT, nullptr, FL_(status), DeviceValueUOM::NONE);
|
||||
id_ = product_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
}
|
||||
|
||||
// RC35
|
||||
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model == EMSdevice::EMS_DEVICE_FLAG_RC30_1)) {
|
||||
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC35) || (model == EMSdevice::EMS_DEVICE_FLAG_RC30_N)) {
|
||||
monitor_typeids = {0x3E, 0x48, 0x52, 0x5C};
|
||||
set_typeids = {0x3D, 0x47, 0x51, 0x5B};
|
||||
timer_typeids = {0x3F, 0x49, 0x53, 0x5D};
|
||||
@@ -84,7 +84,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
register_telegram_type(0xAF, F("RC20Remote"), false, MAKE_PF_CB(process_RC20Remote));
|
||||
}
|
||||
// RC20 newer
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20_2) {
|
||||
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC20_N) {
|
||||
monitor_typeids = {0xAE};
|
||||
set_typeids = {0xAD};
|
||||
if (actual_master_thermostat == device_id) {
|
||||
@@ -167,8 +167,6 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
||||
// register device values for common values (not heating circuit)
|
||||
register_device_values();
|
||||
|
||||
add_commands();
|
||||
|
||||
// only for for the master-thermostat, go a query all the heating circuits. This is only done once.
|
||||
// The automatic fetch will from now on only update the active heating circuits
|
||||
for (uint8_t i = 0; i < monitor_typeids.size(); i++) {
|
||||
@@ -513,7 +511,7 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const {
|
||||
} else if (modetype == 1) {
|
||||
return HeatingCircuit::Mode::NOFROST;
|
||||
}
|
||||
} else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_1)) {
|
||||
} else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_N)) {
|
||||
if (modetype == 0) {
|
||||
return HeatingCircuit::Mode::NIGHT;
|
||||
} else if (modetype == 1) {
|
||||
@@ -537,59 +535,65 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const {
|
||||
std::string Thermostat::mode_tostring(uint8_t mode) {
|
||||
switch (mode) {
|
||||
case HeatingCircuit::Mode::OFF:
|
||||
return read_flash_string(F("off"));
|
||||
return read_flash_string(F_(off));
|
||||
break;
|
||||
case HeatingCircuit::Mode::MANUAL:
|
||||
return read_flash_string(F("manual"));
|
||||
return read_flash_string(F_(manual));
|
||||
break;
|
||||
case HeatingCircuit::Mode::DAY:
|
||||
return read_flash_string(F("day"));
|
||||
return read_flash_string(F_(day));
|
||||
break;
|
||||
case HeatingCircuit::Mode::NIGHT:
|
||||
return read_flash_string(F("night"));
|
||||
return read_flash_string(F_(night));
|
||||
break;
|
||||
case HeatingCircuit::Mode::ECO:
|
||||
return read_flash_string(F("eco"));
|
||||
return read_flash_string(F_(eco));
|
||||
break;
|
||||
case HeatingCircuit::Mode::COMFORT:
|
||||
return read_flash_string(F("comfort"));
|
||||
return read_flash_string(F_(comfort));
|
||||
break;
|
||||
case HeatingCircuit::Mode::HEAT:
|
||||
return read_flash_string(F("heat"));
|
||||
return read_flash_string(F_(heat));
|
||||
break;
|
||||
case HeatingCircuit::Mode::HOLIDAY:
|
||||
return read_flash_string(F("holiday"));
|
||||
return read_flash_string(F_(holiday));
|
||||
break;
|
||||
case HeatingCircuit::Mode::NOFROST:
|
||||
return read_flash_string(F("nofrost"));
|
||||
return read_flash_string(F_(nofrost));
|
||||
break;
|
||||
case HeatingCircuit::Mode::AUTO:
|
||||
return read_flash_string(F("auto"));
|
||||
return read_flash_string(F_(auto));
|
||||
break;
|
||||
case HeatingCircuit::Mode::SUMMER:
|
||||
return read_flash_string(F("summer"));
|
||||
return read_flash_string(F_(summer));
|
||||
break;
|
||||
case HeatingCircuit::Mode::OFFSET:
|
||||
return read_flash_string(F("offset"));
|
||||
return read_flash_string(F_(offset));
|
||||
break;
|
||||
case HeatingCircuit::Mode::DESIGN:
|
||||
return read_flash_string(F("design"));
|
||||
return read_flash_string(F_(design));
|
||||
break;
|
||||
case HeatingCircuit::Mode::MINFLOW:
|
||||
return read_flash_string(F("minflow"));
|
||||
return read_flash_string(F_(minflow));
|
||||
break;
|
||||
case HeatingCircuit::Mode::MAXFLOW:
|
||||
return read_flash_string(F("maxflow"));
|
||||
return read_flash_string(F_(maxflow));
|
||||
break;
|
||||
case HeatingCircuit::Mode::ROOMINFLUENCE:
|
||||
return read_flash_string(F("roominfluence"));
|
||||
return read_flash_string(F_(roominfluence[0]));
|
||||
break;
|
||||
case HeatingCircuit::Mode::FLOWOFFSET:
|
||||
return read_flash_string(F("flowtempoffset"));
|
||||
return read_flash_string(F_(flowtempoffset[0]));
|
||||
break;
|
||||
case HeatingCircuit::Mode::TEMPAUTO:
|
||||
return read_flash_string(F_(tempauto));
|
||||
break;
|
||||
case HeatingCircuit::Mode::NOREDUCE:
|
||||
return read_flash_string(F_(noreduce));
|
||||
break;
|
||||
default:
|
||||
case HeatingCircuit::Mode::UNKNOWN:
|
||||
return read_flash_string(F("unknown"));
|
||||
return read_flash_string(F_(unknown));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -792,6 +796,7 @@ void Thermostat::process_RC300Set(std::shared_ptr<const Telegram> telegram) {
|
||||
// has_update(telegram->read_value(hc->mode, 0); // Auto = xFF, Manual = x00 eg. 10 00 FF 08 01 B9 FF
|
||||
has_update(telegram->read_value(hc->daytemp, 2)); // is * 2
|
||||
has_update(telegram->read_value(hc->nighttemp, 4)); // is * 2
|
||||
has_update(telegram->read_value(hc->tempautotemp, 8));
|
||||
has_update(telegram->read_value(hc->manualtemp, 10)); // is * 2
|
||||
has_update(telegram->read_value(hc->program, 11)); // timer program 1 or 2
|
||||
}
|
||||
@@ -957,7 +962,8 @@ void Thermostat::process_RC35Set(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(hc->reducemode, 25)); // 0-nofrost, 1-reduce, 2-roomhold, 3-outdoorhold
|
||||
has_update(telegram->read_value(hc->control, 26)); // 0-off, 1-RC20 (remote), 2-RC35
|
||||
has_update(telegram->read_value(hc->controlmode, 33)); // 0-outdoortemp, 1-roomtemp
|
||||
// has_update(telegram->read_value(hc->noreducetemp, 38)); // outdoor temperature for no reduce
|
||||
has_update(telegram->read_value(hc->tempautotemp, 37)); // 0-outdoortemp, 1-roomtemp
|
||||
has_update(telegram->read_value(hc->noreducetemp, 38)); // outdoor temperature for no reduce
|
||||
has_update(telegram->read_value(hc->minflowtemp, 16));
|
||||
if (hc->heatingtype == 3) {
|
||||
has_update(telegram->read_value(hc->designtemp, 36)); // is * 1
|
||||
@@ -976,6 +982,8 @@ void Thermostat::process_RC35Timer(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
has_update(telegram->read_value(hc->program, 84)); // 0 .. 10, 0-userprogram 1, 10-userprogram 2
|
||||
has_update(telegram->read_value(hc->pause, 85)); // time in hours
|
||||
has_update(telegram->read_value(hc->party, 86)); // time in hours
|
||||
}
|
||||
|
||||
// process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long
|
||||
@@ -1311,7 +1319,7 @@ bool Thermostat::set_holiday(const char * value, const int8_t id) {
|
||||
LOG_INFO(F("Setting holiday at home for hc %d"), hc->hc_num());
|
||||
write_command(timer_typeids[hc->hc_num() - 1], 93, data, 6, 0);
|
||||
} else {
|
||||
LOG_WARNING(F("Set holiday: Invalid"));
|
||||
LOG_WARNING(F("Set holiday: Invalid value"));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1503,7 +1511,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) {
|
||||
offset = EMS_OFFSET_RC20Set_mode;
|
||||
validate_typeid = set_typeids[hc_p];
|
||||
break;
|
||||
case EMSdevice::EMS_DEVICE_FLAG_RC20_2: // ES72
|
||||
case EMSdevice::EMS_DEVICE_FLAG_RC20_N: // ES72
|
||||
offset = EMS_OFFSET_RC20_2_Set_mode;
|
||||
validate_typeid = set_typeids[hc_p];
|
||||
break;
|
||||
@@ -1512,7 +1520,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const uint8_t hc_num) {
|
||||
validate_typeid = set_typeids[hc_p];
|
||||
break;
|
||||
case EMSdevice::EMS_DEVICE_FLAG_RC35:
|
||||
case EMSdevice::EMS_DEVICE_FLAG_RC30_1:
|
||||
case EMSdevice::EMS_DEVICE_FLAG_RC30_N:
|
||||
offset = EMS_OFFSET_RC35Set_mode;
|
||||
validate_typeid = set_typeids[hc_p];
|
||||
break;
|
||||
@@ -1608,7 +1616,7 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) {
|
||||
write_command(curve_typeids[hc->hc_num() - 1], 0, set, curve_typeids[hc->hc_num() - 1]);
|
||||
return true;
|
||||
}
|
||||
} else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_1) {
|
||||
} else if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) {
|
||||
if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) {
|
||||
LOG_INFO(F("Setting control mode to %d for heating circuit %d"), set, hc->hc_num());
|
||||
write_command(set_typeids[hc->hc_num() - 1], 33, set, set_typeids[hc->hc_num() - 1]);
|
||||
@@ -1658,7 +1666,7 @@ bool Thermostat::set_switchtime(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_1)) {
|
||||
if ((model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N)) {
|
||||
write_command(timer_typeids[hc->hc_num() - 1], no * 2, (uint8_t *)&data, 2, timer_typeids[hc->hc_num() - 1]);
|
||||
} else {
|
||||
LOG_WARNING(F("Setting switchtime: thermostat not supported"));
|
||||
@@ -1687,9 +1695,9 @@ bool Thermostat::set_program(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (model() == EMS_DEVICE_FLAG_RC20_2 && set > 0 && set < 10) {
|
||||
if (model() == EMS_DEVICE_FLAG_RC20_N && set > 0 && set < 10) {
|
||||
write_command(set_typeids[hc->hc_num() - 1], 11, set, set_typeids[hc->hc_num() - 1]);
|
||||
} else if ((model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_1) && set < 11) {
|
||||
} else if ((model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) && set < 11) {
|
||||
write_command(timer_typeids[hc->hc_num() - 1], 84, set, timer_typeids[hc->hc_num() - 1]);
|
||||
} else if ((model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) && (set == 1 || set == 2)) {
|
||||
write_command(set_typeids[hc->hc_num() - 1], 11, set, set_typeids[hc->hc_num() - 1]);
|
||||
@@ -1738,6 +1746,12 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
|
||||
case HeatingCircuit::Mode::MANUAL:
|
||||
offset = 0x0A; // manual offset
|
||||
break;
|
||||
case HeatingCircuit::Mode::TEMPAUTO:
|
||||
offset = 0x08; // manual offset
|
||||
if (temperature == -1) {
|
||||
factor = 0xFF; // use factor as value
|
||||
}
|
||||
break;
|
||||
case HeatingCircuit::Mode::COMFORT:
|
||||
offset = 0x02; // comfort offset level 2
|
||||
break;
|
||||
@@ -1804,7 +1818,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (model == EMS_DEVICE_FLAG_RC20_2) {
|
||||
} else if (model == EMS_DEVICE_FLAG_RC20_N) {
|
||||
switch (mode) {
|
||||
case HeatingCircuit::Mode::NIGHT: // change the night temp
|
||||
offset = EMS_OFFSET_RC20_2_Set_temp_night;
|
||||
@@ -1819,7 +1833,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
|
||||
break;
|
||||
}
|
||||
|
||||
} else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_1)) {
|
||||
} else if ((model == EMS_DEVICE_FLAG_RC35) || (model == EMS_DEVICE_FLAG_RC30_N)) {
|
||||
validate_typeid = set_typeids[hc->hc_num() - 1];
|
||||
switch (mode) {
|
||||
case HeatingCircuit::Mode::NIGHT: // change the night temp
|
||||
@@ -1858,6 +1872,13 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
|
||||
offset = 4;
|
||||
factor = 1;
|
||||
break;
|
||||
case HeatingCircuit::Mode::NOREDUCE:
|
||||
offset = EMS_OFFSET_RC35Set_noreducetemp;
|
||||
factor = 1;
|
||||
break;
|
||||
case HeatingCircuit::Mode::TEMPAUTO:
|
||||
offset = EMS_OFFSET_RC35Set_seltemp;
|
||||
break;
|
||||
case HeatingCircuit::Mode::MINFLOW:
|
||||
offset = 16;
|
||||
factor = 1;
|
||||
@@ -2026,6 +2047,14 @@ bool Thermostat::set_manualtemp(const char * value, const int8_t id) {
|
||||
return set_temperature_value(value, id, HeatingCircuit::Mode::MANUAL);
|
||||
}
|
||||
|
||||
bool Thermostat::set_tempautotemp(const char * value, const int8_t id) {
|
||||
return set_temperature_value(value, id, HeatingCircuit::Mode::TEMPAUTO);
|
||||
}
|
||||
|
||||
bool Thermostat::set_noreducetemp(const char * value, const int8_t id) {
|
||||
return set_temperature_value(value, id, HeatingCircuit::Mode::NOREDUCE);
|
||||
}
|
||||
|
||||
bool Thermostat::set_flowtempoffset(const char * value, const int8_t id) {
|
||||
return set_temperature_value(value, id, HeatingCircuit::Mode::FLOWOFFSET);
|
||||
}
|
||||
@@ -2042,133 +2071,66 @@ bool Thermostat::set_roominfluence(const char * value, const int8_t id) {
|
||||
return set_temperature_value(value, id, HeatingCircuit::Mode::ROOMINFLUENCE);
|
||||
}
|
||||
|
||||
// API commands for MQTT and Console
|
||||
void Thermostat::add_commands() {
|
||||
// if this thermostat doesn't support write, don't add the commands
|
||||
if (has_flags(EMS_DEVICE_FLAG_NO_WRITE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// common to all thermostats
|
||||
register_mqtt_cmd(F_(temp), MAKE_CF_CB(set_temp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(mode), MAKE_CF_CB(set_mode), FLAG_HC);
|
||||
if (model() == EMS_DEVICE_FLAG_RC35) { // section is together with RC30
|
||||
register_mqtt_cmd(MQTT_TOPIC(dateTime), MAKE_CF_CB(set_datetime));
|
||||
}
|
||||
|
||||
switch (model()) {
|
||||
case EMS_DEVICE_FLAG_RC100:
|
||||
case EMS_DEVICE_FLAG_RC300:
|
||||
register_mqtt_cmd(MQTT_TOPIC(dateTime), MAKE_CF_CB(set_datetime));
|
||||
register_mqtt_cmd(MQTT_TOPIC(manualtemp), MAKE_CF_CB(set_manualtemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(ecotemp), MAKE_CF_CB(set_ecotemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(comforttemp), MAKE_CF_CB(set_comforttemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(summermode), MAKE_CF_CB(set_summermode), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(summertemp), MAKE_CF_CB(set_summertemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(wwMode), MAKE_CF_CB(set_wwmode));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wwSetTemp), MAKE_CF_CB(set_wwtemp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wwSetTempLow), MAKE_CF_CB(set_wwtemplow));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWOneTime), MAKE_CF_CB(set_wwonetime));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWCircMode), MAKE_CF_CB(set_wwcircmode));
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaBuildingType), MAKE_CF_CB(set_building));
|
||||
register_mqtt_cmd(MQTT_TOPIC(nofrosttemp), MAKE_CF_CB(set_nofrosttemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(designtemp), MAKE_CF_CB(set_designtemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(offsettemp), MAKE_CF_CB(set_offsettemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(minflowtemp), MAKE_CF_CB(set_minflowtemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(maxflowtemp), MAKE_CF_CB(set_maxflowtemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaMinExtTemperature), MAKE_CF_CB(set_minexttemp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(roominfluence), MAKE_CF_CB(set_roominfluence), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(program), MAKE_CF_CB(set_program), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(controlmode), MAKE_CF_CB(set_controlmode), FLAG_HC);
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC20_2:
|
||||
register_mqtt_cmd(MQTT_TOPIC(nighttemp), MAKE_CF_CB(set_nighttemp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(daytemp), MAKE_CF_CB(set_daytemp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(program), MAKE_CF_CB(set_program));
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC30_1: // only RC30_1
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaClockOffset), MAKE_CF_CB(set_clockoffset));
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaLanguage), MAKE_CF_CB(set_language));
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaMainDisplay), MAKE_CF_CB(set_display));
|
||||
case EMS_DEVICE_FLAG_RC35: // RC30 and RC35
|
||||
register_mqtt_cmd(MQTT_TOPIC(nighttemp), MAKE_CF_CB(set_nighttemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(daytemp), MAKE_CF_CB(set_daytemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(nofrosttemp), MAKE_CF_CB(set_nofrosttemp), FLAG_HC);
|
||||
register_mqtt_cmd(F_(remoteTemp), MAKE_CF_CB(set_remotetemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaMinExtTemperature), MAKE_CF_CB(set_minexttemp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaCalIntTemperature), MAKE_CF_CB(set_calinttemp));
|
||||
register_mqtt_cmd(MQTT_TOPIC(ibaBuildingType), MAKE_CF_CB(set_building));
|
||||
register_mqtt_cmd(MQTT_TOPIC(control), MAKE_CF_CB(set_control), FLAG_HC);
|
||||
register_mqtt_cmd(F_(pause), MAKE_CF_CB(set_pause), FLAG_HC);
|
||||
register_mqtt_cmd(F_(party), MAKE_CF_CB(set_party), FLAG_HC);
|
||||
register_mqtt_cmd(F_(holiday), MAKE_CF_CB(set_holiday), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(summertemp), MAKE_CF_CB(set_summertemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(designtemp), MAKE_CF_CB(set_designtemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(offsettemp), MAKE_CF_CB(set_offsettemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(holidaytemp), MAKE_CF_CB(set_holidaytemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(wwMode), MAKE_CF_CB(set_wwmode));
|
||||
register_mqtt_cmd(MQTT_TOPIC(wWCircMode), MAKE_CF_CB(set_wwcircmode));
|
||||
register_mqtt_cmd(MQTT_TOPIC(roominfluence), MAKE_CF_CB(set_roominfluence), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(flowtempoffset), MAKE_CF_CB(set_flowtempoffset), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(minflowtemp), MAKE_CF_CB(set_minflowtemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(maxflowtemp), MAKE_CF_CB(set_maxflowtemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(reducemode), MAKE_CF_CB(set_reducemode), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(program), MAKE_CF_CB(set_program), FLAG_HC);
|
||||
register_mqtt_cmd(F_(switchtime), MAKE_CF_CB(set_switchtime), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(controlmode), MAKE_CF_CB(set_controlmode), FLAG_HC);
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_JUNKERS:
|
||||
register_mqtt_cmd(MQTT_TOPIC(dateTime), MAKE_CF_CB(set_datetime));
|
||||
register_mqtt_cmd(MQTT_TOPIC(nofrosttemp), MAKE_CF_CB(set_nofrosttemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(ecotemp), MAKE_CF_CB(set_ecotemp), FLAG_HC);
|
||||
register_mqtt_cmd(MQTT_TOPIC(heattemp), MAKE_CF_CB(set_heattemp), FLAG_HC);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// register main device values, top level for all thermostats (excluding heating circuits)
|
||||
// as these are done in void Thermostat::register_device_values_hc()
|
||||
void Thermostat::register_device_values() {
|
||||
uint8_t model = this->model();
|
||||
// extra commands
|
||||
if (!has_flags(EMS_DEVICE_FLAG_NO_WRITE)) {
|
||||
register_cmd(MQTT_TOPIC(temp), MAKE_CF_CB(set_temp), FLAG_HC); // for backwards compatibility
|
||||
}
|
||||
|
||||
// Common for all thermostats
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &errorCode_, DeviceValueType::TEXT, nullptr, FL_(errorCode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &lastCode_, DeviceValueType::TEXT, nullptr, FL_(lastCode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &id_, DeviceValueType::UINT, nullptr, F("id"), nullptr, DeviceValueUOM::NONE); // empty full name to prevent being shown in web or console
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &errorCode_, DeviceValueType::TEXT, nullptr, FL_(errorCode), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &lastCode_, DeviceValueType::TEXT, nullptr, FL_(lastCode), DeviceValueUOM::NONE);
|
||||
|
||||
// RC30 only
|
||||
if (model == EMSdevice::EMS_DEVICE_FLAG_RC30_1) {
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaMainDisplay_, DeviceValueType::ENUM, FL_(enum_ibaMainDisplay), FL_(ibaMainDisplay));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaLanguage_, DeviceValueType::ENUM, FL_(enum_ibaLanguage), FL_(ibaLanguage));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaClockOffset_, DeviceValueType::UINT, nullptr, FL_(ibaClockOffset)); // offset (in sec) to clock, 0xff=-1s, 0x02=2s
|
||||
}
|
||||
|
||||
// RC300 and RC100
|
||||
if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) {
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &floordrystatus_, DeviceValueType::ENUM, FL_(enum_floordrystatus), FL_(floordrystatus));
|
||||
switch (this->model()) {
|
||||
case EMS_DEVICE_FLAG_RC100:
|
||||
case EMS_DEVICE_FLAG_RC300:
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_datetime));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &floordrystatus_, DeviceValueType::ENUM, FL_(enum_floordrystatus), FL_(floordrystatus), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dampedoutdoortemp2_, DeviceValueType::SHORT, FL_(div10), FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &floordrytemp_, DeviceValueType::UINT, nullptr, FL_(floordrytemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType), FL_(ibaBuildingType));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwSetTempLow_, DeviceValueType::UINT, nullptr, FL_(wwSetTempLow), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wWCircMode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType), FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwSetTempLow_, DeviceValueType::UINT, nullptr, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwExtra1_, DeviceValueType::UINT, nullptr, FL_(wwExtra1), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwExtra2_, DeviceValueType::UINT, nullptr, FL_(wwExtra2), DeviceValueUOM::DEGREES);
|
||||
}
|
||||
|
||||
// RC30 and RC35
|
||||
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) {
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaCalIntTemperature_, DeviceValueType::INT, FL_(div2), FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaMinExtTemperature_, DeviceValueType::INT, nullptr, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES);
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC20_N:
|
||||
case EMS_DEVICE_FLAG_RC20:
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC30_N:
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaMainDisplay_, DeviceValueType::ENUM, FL_(enum_ibaMainDisplay), FL_(ibaMainDisplay), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaLanguage_, DeviceValueType::ENUM, FL_(enum_ibaLanguage), FL_(ibaLanguage), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaClockOffset_, DeviceValueType::UINT, nullptr, FL_(ibaClockOffset), DeviceValueUOM::NONE); // offset (in sec) to clock, 0xff=-1s, 0x02=2s
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaCalIntTemperature_, DeviceValueType::INT, FL_(div2), FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_calinttemp));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaMinExtTemperature_, DeviceValueType::INT, nullptr, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dampedoutdoortemp_, DeviceValueType::INT, nullptr, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType2), FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode2), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode));
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC35:
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_datetime));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaCalIntTemperature_, DeviceValueType::INT, FL_(div2), FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_calinttemp));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaMinExtTemperature_, DeviceValueType::INT, nullptr, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &tempsensor1_, DeviceValueType::USHORT, FL_(div10), FL_(tempsensor1), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &tempsensor2_, DeviceValueType::USHORT, FL_(div10), FL_(tempsensor2), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dampedoutdoortemp_, DeviceValueType::INT, nullptr, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType2), FL_(ibaBuildingType));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode2), FL_(wWCircMode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType2), FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode2), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode));
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_JUNKERS:
|
||||
register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_datetime));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2193,7 +2155,11 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
||||
setpoint_temp_divider = FL_(div2);
|
||||
curr_temp_divider = FL_(div10);
|
||||
}
|
||||
if (has_flags(EMS_DEVICE_FLAG_NO_WRITE) || device_id() != EMSESP::actual_master_thermostat()) {
|
||||
register_device_value(tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, FL_(setpoint_roomTemp), DeviceValueUOM::DEGREES);
|
||||
} else {
|
||||
register_device_value(tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, FL_(setpoint_roomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp));
|
||||
}
|
||||
register_device_value(tag, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, FL_(curr_roomTemp), DeviceValueUOM::DEGREES);
|
||||
|
||||
if (device_id() != EMSESP::actual_master_thermostat()) {
|
||||
@@ -2205,82 +2171,87 @@ void Thermostat::register_device_values_hc(std::shared_ptr<emsesp::Thermostat::H
|
||||
if (Mqtt::ha_enabled()) {
|
||||
uint8_t option = Mqtt::ha_climate_format();
|
||||
if (option == Mqtt::HA_Climate_Format::CURRENT) {
|
||||
register_device_value(tag, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, F("hatemp"), nullptr);
|
||||
register_device_value(tag, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, F("hatemp"), nullptr, DeviceValueUOM::NONE);
|
||||
} else if (option == Mqtt::HA_Climate_Format::SETPOINT) {
|
||||
register_device_value(tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, F("hatemp"), nullptr);
|
||||
register_device_value(tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, F("hatemp"), nullptr, DeviceValueUOM::NONE);
|
||||
} else if (option == Mqtt::HA_Climate_Format::ZERO) {
|
||||
register_device_value(tag, &zero_value_, DeviceValueType::UINT, nullptr, F("hatemp"), nullptr);
|
||||
register_device_value(tag, &zero_value_, DeviceValueType::UINT, nullptr, F("hatemp"), nullptr, DeviceValueUOM::NONE);
|
||||
}
|
||||
|
||||
// if we're sending to HA the only valid mode types are heat, auto and off
|
||||
// manual & day = heat
|
||||
// night & off = off
|
||||
// everything else auto
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_hamode), F("hamode"), nullptr);
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_hamode), F("hamode"), nullptr, DeviceValueUOM::NONE);
|
||||
}
|
||||
|
||||
if (model == EMSdevice::EMS_DEVICE_FLAG_RC300 || model == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode), FL_(mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype), FL_(modetype));
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(ecotemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->manualtemp, DeviceValueType::UINT, FL_(div2), FL_(manualtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(comforttemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, nullptr, FL_(designtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, nullptr, FL_(offsettemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, nullptr, FL_(minflowtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, nullptr, FL_(maxflowtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, nullptr, FL_(roominfluence));
|
||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES);
|
||||
switch (model) {
|
||||
case EMS_DEVICE_FLAG_RC100:
|
||||
case EMS_DEVICE_FLAG_RC300:
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype), FL_(modetype), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp));
|
||||
register_device_value(tag, &hc->manualtemp, DeviceValueType::UINT, FL_(div2), FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp));
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(comforttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_comforttemp));
|
||||
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp));
|
||||
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, nullptr, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp));
|
||||
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, nullptr, FL_(offsettemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offsettemp));
|
||||
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, nullptr, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp));
|
||||
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, nullptr, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp));
|
||||
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, nullptr, FL_(roominfluence), DeviceValueUOM::NONE, MAKE_CF_CB(set_roominfluence));
|
||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp));
|
||||
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, nullptr, FL_(targetflowtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype));
|
||||
register_device_value(tag, &hc->summer_setmode, DeviceValueType::ENUM, FL_(enum_summermode), FL_(summermode));
|
||||
register_device_value(tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode), FL_(controlmode));
|
||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program));
|
||||
}
|
||||
|
||||
if (model == EMS_DEVICE_FLAG_RC20) {
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode));
|
||||
}
|
||||
|
||||
if (model == EMS_DEVICE_FLAG_RC20_2) {
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype2), FL_(modetype));
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(daytemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program));
|
||||
}
|
||||
|
||||
if (model == EMS_DEVICE_FLAG_RC35 || model == EMS_DEVICE_FLAG_RC30_1) {
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype));
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(daytemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, nullptr, FL_(designtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, FL_(div2), FL_(offsettemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->holidaytemp, DeviceValueType::UINT, FL_(div2), FL_(holidaytemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->summer_setmode, DeviceValueType::ENUM, FL_(enum_summermode), FL_(summermode), DeviceValueUOM::NONE, MAKE_CF_CB(set_summermode));
|
||||
register_device_value(tag, &hc->summermode, DeviceValueType::BOOL, nullptr, FL_(summermode), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode));
|
||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
|
||||
register_device_value(tag, &hc->tempautotemp, DeviceValueType::UINT, FL_(div2), FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp));
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC20:
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC20_N:
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype2), FL_(modetype), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
|
||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_RC30_N:
|
||||
case EMS_DEVICE_FLAG_RC35:
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode3), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype3), FL_(modetype), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
|
||||
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, nullptr, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp));
|
||||
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, FL_(div2), FL_(offsettemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offsettemp));
|
||||
register_device_value(tag, &hc->holidaytemp, DeviceValueType::UINT, FL_(div2), FL_(holidaytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_holidaytemp));
|
||||
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, nullptr, FL_(targetflowtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->summermode, DeviceValueType::BOOL, nullptr, FL_(summermode));
|
||||
register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL, nullptr, FL_(holidaymode));
|
||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, nullptr, FL_(roominfluence));
|
||||
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, nullptr, FL_(minflowtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, nullptr, FL_(maxflowtemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT, nullptr, FL_(flowtempoffset), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype));
|
||||
register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(reducemode));
|
||||
register_device_value(tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode));
|
||||
register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_control), FL_(control));
|
||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program));
|
||||
}
|
||||
|
||||
if (model == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode4), FL_(mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype4), FL_(modetype));
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(heattemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(ecotemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, FL_(div2), FL_(nofrosttemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp));
|
||||
register_device_value(tag, &hc->summermode, DeviceValueType::BOOL, nullptr, FL_(summermode), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL, nullptr, FL_(holidaymode), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday));
|
||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp));
|
||||
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, nullptr, FL_(roominfluence), DeviceValueUOM::NONE, MAKE_CF_CB(set_roominfluence));
|
||||
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, nullptr, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp));
|
||||
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, nullptr, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp));
|
||||
register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT, nullptr, FL_(flowtempoffset), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowtempoffset));
|
||||
register_device_value(tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode));
|
||||
register_device_value(tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode));
|
||||
register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_control), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control));
|
||||
register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
|
||||
register_device_value(tag, &hc->pause, DeviceValueType::UINT, nullptr, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause));
|
||||
register_device_value(tag, &hc->party, DeviceValueType::UINT, nullptr, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party));
|
||||
register_device_value(tag, &hc->tempautotemp, DeviceValueType::UINT, FL_(div2), FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp));
|
||||
register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, nullptr, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp));
|
||||
break;
|
||||
case EMS_DEVICE_FLAG_JUNKERS:
|
||||
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode4), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
|
||||
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype4), FL_(modetype), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(heattemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heattemp));
|
||||
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp));
|
||||
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, FL_(div2), FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ class Thermostat : public EMSdevice {
|
||||
|
||||
int16_t setpoint_roomTemp;
|
||||
int16_t curr_roomTemp;
|
||||
uint8_t tempautotemp;
|
||||
uint8_t mode;
|
||||
uint8_t modetype;
|
||||
uint8_t summermode;
|
||||
@@ -59,6 +60,9 @@ class Thermostat : public EMSdevice {
|
||||
uint8_t program;
|
||||
uint8_t controlmode;
|
||||
uint8_t control;
|
||||
uint8_t pause;
|
||||
uint8_t party;
|
||||
int8_t noreducetemp; // signed -20°C to +10°C
|
||||
|
||||
uint8_t hc_num() const {
|
||||
return hc_num_;
|
||||
@@ -94,6 +98,8 @@ class Thermostat : public EMSdevice {
|
||||
MINFLOW,
|
||||
MAXFLOW,
|
||||
ROOMINFLUENCE,
|
||||
TEMPAUTO,
|
||||
NOREDUCE,
|
||||
UNKNOWN
|
||||
|
||||
};
|
||||
@@ -115,8 +121,6 @@ class Thermostat : public EMSdevice {
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
void add_commands();
|
||||
|
||||
void register_device_values();
|
||||
void register_device_values(uint8_t hc_num);
|
||||
|
||||
@@ -201,6 +205,7 @@ class Thermostat : public EMSdevice {
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_heatingtype = 0; // e.g. floor heating = 3
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_targetflowtemp = 14; // target flow temperature
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_seltemp = 37; // selected temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_noreducetemp = 38; // temp to stop reducing
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_temp_offset = 6;
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_temp_flowoffset = 24;
|
||||
static constexpr uint8_t EMS_OFFSET_RC35Set_temp_design = 17;
|
||||
@@ -310,6 +315,8 @@ class Thermostat : public EMSdevice {
|
||||
bool set_offsettemp(const char * value, const int8_t id);
|
||||
bool set_holidaytemp(const char * value, const int8_t id);
|
||||
bool set_manualtemp(const char * value, const int8_t id);
|
||||
bool set_tempautotemp(const char * value, const int8_t id);
|
||||
bool set_noreducetemp(const char * value, const int8_t id);
|
||||
bool set_remotetemp(const char * value, const int8_t id);
|
||||
bool set_roominfluence(const char * value, const int8_t id);
|
||||
bool set_flowtempoffset(const char * value, const int8_t id);
|
||||
|
||||
@@ -149,7 +149,7 @@ std::string EMSdevice::brand_to_string() const {
|
||||
break;
|
||||
case EMSdevice::Brand::NO_BRAND:
|
||||
default:
|
||||
return read_flash_string(F("---"));
|
||||
return read_flash_string(F(""));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ void EMSdevice::register_mqtt_topic(const std::string & topic, mqtt_subfunction_
|
||||
}
|
||||
|
||||
// add command to library
|
||||
void EMSdevice::register_mqtt_cmd(const __FlashStringHelper * cmd, cmdfunction_p f, uint8_t flag) {
|
||||
void EMSdevice::register_cmd(const __FlashStringHelper * cmd, cmdfunction_p f, uint8_t flag) {
|
||||
Command::add(device_type_, cmd, f, flag);
|
||||
}
|
||||
|
||||
@@ -423,7 +423,14 @@ void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __
|
||||
// short_name: used in Mqtt as keys
|
||||
// full name: used in Web and Console unless empty (nullptr)
|
||||
// uom: unit of measure from DeviceValueUOM
|
||||
void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * short_name, const __FlashStringHelper * full_name, uint8_t uom) {
|
||||
void EMSdevice::register_device_value(uint8_t tag,
|
||||
void * value_p,
|
||||
uint8_t type,
|
||||
const __FlashStringHelper * const * options,
|
||||
const __FlashStringHelper * short_name,
|
||||
const __FlashStringHelper * full_name,
|
||||
uint8_t uom,
|
||||
bool has_cmd) {
|
||||
// init the value depending on it's type
|
||||
if (type == DeviceValueType::TEXT) {
|
||||
*(char *)(value_p) = {'\0'};
|
||||
@@ -448,11 +455,18 @@ void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type,
|
||||
};
|
||||
}
|
||||
|
||||
devicevalues_.emplace_back(device_type_, tag, value_p, type, options, options_size, short_name, full_name, uom);
|
||||
devicevalues_.emplace_back(device_type_, tag, value_p, type, options, options_size, short_name, full_name, uom, 0, has_cmd);
|
||||
}
|
||||
|
||||
void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom) {
|
||||
register_device_value(tag, value_p, type, options, name[0], name[1], uom);
|
||||
void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom, cmdfunction_p f) {
|
||||
register_device_value(tag, value_p, type, options, name[0], name[1], uom, (f != nullptr));
|
||||
if (f != nullptr) {
|
||||
if (tag >= TAG_HC1 && tag <= TAG_HC4) {
|
||||
Command::add(device_type_, name[0], f, FLAG_HC);
|
||||
} else {
|
||||
Command::add(device_type_, name[0], f, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// looks up the uom (suffix) for a given key from the device value table
|
||||
@@ -570,7 +584,7 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
||||
if (sz > num_elements) {
|
||||
// add the unit of measure (uom)
|
||||
if (dv.uom == DeviceValueUOM::MINUTES) {
|
||||
data.add(nullptr);
|
||||
data.add(nullptr); // use null for time/date
|
||||
} else {
|
||||
data.add(uom_to_string(dv.uom));
|
||||
}
|
||||
@@ -583,7 +597,15 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
||||
snprintf_P(name, sizeof(name), "(%s) %s", tag_to_string(dv.tag).c_str(), uuid::read_flash_string(dv.full_name).c_str());
|
||||
data.add(name);
|
||||
}
|
||||
num_elements = sz + 2;
|
||||
|
||||
// add the name of the Command function if it exists
|
||||
if (dv.has_cmd) {
|
||||
data.add(dv.short_name);
|
||||
} else {
|
||||
data.add("");
|
||||
}
|
||||
|
||||
num_elements = sz + 3; // increase count by 3
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -595,11 +617,12 @@ bool EMSdevice::generate_values_json_web(JsonObject & json) {
|
||||
// return false if empty
|
||||
// this is used to create both the MQTT payloads and Console messages (console = true)
|
||||
bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter, const bool nested, const bool console) {
|
||||
bool has_value = false; // to see if we've added a value. it's faster than doing a json.size() at the end
|
||||
bool has_values = false; // to see if we've added a value. it's faster than doing a json.size() at the end
|
||||
uint8_t old_tag = 255; // NAN
|
||||
JsonObject json = root;
|
||||
|
||||
for (const auto & dv : devicevalues_) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
bool has_value = false;
|
||||
// only show if tag is either empty (TAG_NONE) or matches a value
|
||||
// and don't show if full_name is empty unless we're outputing for mqtt payloads
|
||||
// for nested we use all values
|
||||
@@ -731,20 +754,33 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter
|
||||
}
|
||||
}
|
||||
}
|
||||
dv.ha |= has_value ? DeviceValueHA::HA_VALUE : DeviceValueHA::HA_NONE;
|
||||
has_values |= has_value;
|
||||
}
|
||||
|
||||
return has_value;
|
||||
return has_values;
|
||||
}
|
||||
|
||||
// create the Home Assistant configs for each value
|
||||
// this is called when an MQTT publish is done via an EMS Device, and only done once
|
||||
// this is called when an MQTT publish is done via an EMS Device
|
||||
void EMSdevice::publish_mqtt_ha_sensor() {
|
||||
for (const auto & dv : devicevalues_) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
if (dv.ha == DeviceValueHA::HA_VALUE) {
|
||||
Mqtt::publish_mqtt_ha_sensor(dv.type, dv.tag, dv.full_name, device_type_, dv.short_name, dv.uom);
|
||||
dv.ha |= DeviceValueHA::HA_DONE;
|
||||
}
|
||||
|
||||
}
|
||||
if (!ha_config_done()) {
|
||||
bool ok = publish_ha_config();
|
||||
ha_config_done(ok); // see if it worked
|
||||
}
|
||||
}
|
||||
|
||||
void EMSdevice::ha_config_clear() {
|
||||
for (auto & dv : devicevalues_) {
|
||||
dv.ha &= ~DeviceValueHA::HA_DONE;
|
||||
}
|
||||
ha_config_done(false);
|
||||
}
|
||||
|
||||
// return the name of the telegram type
|
||||
|
||||
@@ -141,6 +141,9 @@ enum DeviceValueTAG : uint8_t {
|
||||
// mqtt flags for command subscriptions
|
||||
enum MqttSubFlag : uint8_t { FLAG_NORMAL = 0, FLAG_HC, FLAG_WWC, FLAG_NOSUB };
|
||||
|
||||
// mqtt-HA flags
|
||||
enum DeviceValueHA : uint8_t { HA_NONE = 0, HA_VALUE, HA_DONE};
|
||||
|
||||
class EMSdevice {
|
||||
public:
|
||||
virtual ~EMSdevice() = default; // destructor of base class must always be virtual because it's a polymorphic class
|
||||
@@ -269,16 +272,17 @@ class EMSdevice {
|
||||
const __FlashStringHelper * const * options,
|
||||
const __FlashStringHelper * short_name,
|
||||
const __FlashStringHelper * full_name,
|
||||
uint8_t uom = DeviceValueUOM::NONE);
|
||||
uint8_t uom,
|
||||
bool has_cmd = false);
|
||||
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom, cmdfunction_p f = nullptr);
|
||||
|
||||
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom = DeviceValueUOM::NONE);
|
||||
void write_command(const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid);
|
||||
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid);
|
||||
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value);
|
||||
void read_command(const uint16_t type_id, uint8_t offset = 0, uint8_t length = 0);
|
||||
|
||||
void register_mqtt_topic(const std::string & topic, mqtt_subfunction_p f);
|
||||
void register_mqtt_cmd(const __FlashStringHelper * cmd, cmdfunction_p f, uint8_t flag = 0);
|
||||
void register_cmd(const __FlashStringHelper * cmd, cmdfunction_p f, uint8_t flag = 0);
|
||||
|
||||
void publish_mqtt_ha_sensor();
|
||||
|
||||
@@ -296,6 +300,8 @@ class EMSdevice {
|
||||
ha_config_done_ = v;
|
||||
}
|
||||
|
||||
void ha_config_clear();
|
||||
|
||||
enum Brand : uint8_t {
|
||||
NO_BRAND = 0, // 0
|
||||
BOSCH, // 1
|
||||
@@ -353,8 +359,8 @@ class EMSdevice {
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_EASY = 1;
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC10 = 2;
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC20 = 3;
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC20_2 = 4; // Variation on RC20, Older, like ES72
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC30_1 = 5; // variation on RC30, Newer models
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC20_N = 4; // Variation on RC20, Older, like ES72
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC30_N = 5; // variation on RC30, Newer models
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC30 = 6;
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC35 = 7;
|
||||
static constexpr uint8_t EMS_DEVICE_FLAG_RC300 = 8;
|
||||
@@ -406,6 +412,8 @@ class EMSdevice {
|
||||
const __FlashStringHelper * short_name; // used in MQTT
|
||||
const __FlashStringHelper * full_name; // used in Web and Console
|
||||
uint8_t uom; // DeviceValueUOM::*
|
||||
uint8_t ha; // DevcieValueHA::
|
||||
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
||||
|
||||
DeviceValue(uint8_t device_type,
|
||||
uint8_t tag,
|
||||
@@ -415,7 +423,9 @@ class EMSdevice {
|
||||
uint8_t options_size,
|
||||
const __FlashStringHelper * short_name,
|
||||
const __FlashStringHelper * full_name,
|
||||
uint8_t uom)
|
||||
uint8_t uom,
|
||||
uint8_t ha,
|
||||
bool has_cmd)
|
||||
: device_type(device_type)
|
||||
, tag(tag)
|
||||
, value_p(value_p)
|
||||
@@ -424,7 +434,9 @@ class EMSdevice {
|
||||
, options_size(options_size)
|
||||
, short_name(short_name)
|
||||
, full_name(full_name)
|
||||
, uom(uom) {
|
||||
, uom(uom)
|
||||
, ha(ha)
|
||||
, has_cmd(has_cmd) {
|
||||
}
|
||||
};
|
||||
const std::vector<DeviceValue> devicevalues() const;
|
||||
|
||||
@@ -423,7 +423,7 @@ void EMSESP::reset_mqtt_ha() {
|
||||
}
|
||||
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
emsdevice->ha_config_done(false);
|
||||
emsdevice->ha_config_clear();
|
||||
}
|
||||
dallassensor_.reload();
|
||||
}
|
||||
@@ -440,8 +440,8 @@ void EMSESP::publish_device_values(uint8_t device_type) {
|
||||
// group by device type
|
||||
for (const auto & emsdevice : emsdevices) {
|
||||
if (emsdevice && (emsdevice->device_type() == device_type)) {
|
||||
// if we're using HA and it's not already done, send the config topics first. only do this once
|
||||
if (Mqtt::ha_enabled() && (!emsdevice->ha_config_done())) {
|
||||
// if we're using HA, if done is checked for each sensor in devices
|
||||
if (Mqtt::ha_enabled()) {
|
||||
emsdevice->publish_mqtt_ha_sensor(); // create the configs for each value as a sensor
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#define EMSESP_JSON_SIZE_MEDIUM_DYN 1024 // for large json docs, using DynamicJsonDocument
|
||||
#define EMSESP_JSON_SIZE_LARGE_DYN 2048 // for very large json docs, using DynamicJsonDocument
|
||||
#define EMSESP_JSON_SIZE_XLARGE_DYN 4096 // for very very large json docs, using DynamicJsonDocument
|
||||
#define EMSESP_JSON_SIZE_XXLARGE_DYN 5120 // for extra very very large json docs, using DynamicJsonDocument
|
||||
#define EMSESP_JSON_SIZE_XXLARGE_DYN 8192 // for extra very very large json docs, using DynamicJsonDocument
|
||||
|
||||
// helpers for callback functions
|
||||
#define MAKE_PF_CB(__f) [&](std::shared_ptr<const Telegram> t) { __f(t); } // for process function callbacks to register_telegram_type()
|
||||
|
||||
119
src/locale_EN.h
119
src/locale_EN.h
@@ -184,10 +184,10 @@ MAKE_PSTR_WORD(heat)
|
||||
MAKE_PSTR_WORD(hold)
|
||||
MAKE_PSTR_WORD(cool)
|
||||
MAKE_PSTR_WORD(end)
|
||||
MAKE_PSTR_WORD(German)
|
||||
MAKE_PSTR_WORD(Dutch)
|
||||
MAKE_PSTR_WORD(French)
|
||||
MAKE_PSTR_WORD(Italian)
|
||||
MAKE_PSTR_WORD(german)
|
||||
MAKE_PSTR_WORD(dutch)
|
||||
MAKE_PSTR_WORD(french)
|
||||
MAKE_PSTR_WORD(italian)
|
||||
MAKE_PSTR_WORD(high)
|
||||
MAKE_PSTR_WORD(low)
|
||||
MAKE_PSTR_WORD(radiator)
|
||||
@@ -196,7 +196,7 @@ MAKE_PSTR_WORD(floor)
|
||||
MAKE_PSTR_WORD(summer)
|
||||
MAKE_PSTR_WORD(winter)
|
||||
MAKE_PSTR_WORD(outdoor)
|
||||
MAKE_PSTR_WORD(MPC)
|
||||
MAKE_PSTR_WORD(mpc)
|
||||
MAKE_PSTR_WORD(room)
|
||||
MAKE_PSTR_WORD(power)
|
||||
MAKE_PSTR_WORD(constant)
|
||||
@@ -208,19 +208,27 @@ MAKE_PSTR_WORD(night)
|
||||
MAKE_PSTR_WORD(day)
|
||||
MAKE_PSTR_WORD(holiday)
|
||||
MAKE_PSTR_WORD(reduce)
|
||||
MAKE_PSTR_WORD(RC3x)
|
||||
MAKE_PSTR_WORD(RC20)
|
||||
MAKE_PSTR_WORD(noreduce)
|
||||
MAKE_PSTR_WORD(offset)
|
||||
MAKE_PSTR_WORD(design)
|
||||
MAKE_PSTR_WORD(tempauto)
|
||||
MAKE_PSTR_WORD(minflow)
|
||||
MAKE_PSTR_WORD(maxflow)
|
||||
|
||||
MAKE_PSTR_WORD(rc3x)
|
||||
MAKE_PSTR_WORD(rc20)
|
||||
MAKE_PSTR_WORD(error)
|
||||
MAKE_PSTR(internal_temperature, "internal temperature")
|
||||
MAKE_PSTR(internal_setpoint, "internal setpoint")
|
||||
MAKE_PSTR(external_temperature, "external temperature")
|
||||
MAKE_PSTR(burner_temperature, "burner temperature")
|
||||
MAKE_PSTR(WW_temperature, "WW temperature")
|
||||
MAKE_PSTR(ww_temperature, "ww temperature")
|
||||
MAKE_PSTR(functioning_mode, "functioning mode")
|
||||
MAKE_PSTR(smoke_temperature, "smoke temperature")
|
||||
|
||||
// thermostat lists
|
||||
MAKE_PSTR_LIST(enum_ibaMainDisplay, F_(internal_temperature), F_(internal_setpoint), F_(external_temperature), F_(burner_temperature), F_(WW_temperature), F_(functioning_mode), F_(time), F_(date), F_(smoke_temperature))
|
||||
MAKE_PSTR_LIST(enum_ibaLanguage, F_(German), F_(Dutch), F_(French), F_(Italian))
|
||||
MAKE_PSTR_LIST(enum_ibaMainDisplay, F_(internal_temperature), F_(internal_setpoint), F_(external_temperature), F_(burner_temperature), F_(ww_temperature), F_(functioning_mode), F_(time), F_(date), F_(smoke_temperature))
|
||||
MAKE_PSTR_LIST(enum_ibaLanguage, F_(german), F_(dutch), F_(french), F_(italian))
|
||||
MAKE_PSTR_LIST(enum_floordrystatus, F_(off), F_(start), F_(heat), F_(hold), F_(cool), F_(end))
|
||||
MAKE_PSTR_LIST(enum_ibaBuildingType, F_(blank), F_(light), F_(medium), F_(heavy)) // RC300
|
||||
MAKE_PSTR_LIST(enum_wwMode, F_(off), F_(low), F_(high), F_(auto), F_(own_prog))
|
||||
@@ -243,9 +251,9 @@ MAKE_PSTR_LIST(enum_modetype4, F_(blank), F_(nofrost), F_(eco), F_(heat))
|
||||
|
||||
MAKE_PSTR_LIST(enum_reducemode, F_(nofrost), F_(reduce), F_(room), F_(outdoor))
|
||||
|
||||
MAKE_PSTR_LIST(enum_controlmode, F_(off), F_(outdoor), F_(simple), F_(MPC), F_(room), F_(power), F_(constant))
|
||||
MAKE_PSTR_LIST(enum_controlmode, F_(off), F_(outdoor), F_(simple), F_(mpc), F_(room), F_(power), F_(constant))
|
||||
MAKE_PSTR_LIST(enum_controlmode2, F_(outdoor), F_(room))
|
||||
MAKE_PSTR_LIST(enum_control, F_(off), F_(RC20), F_(RC3x))
|
||||
MAKE_PSTR_LIST(enum_control, F_(off), F_(rc20), F_(rc3x))
|
||||
|
||||
MAKE_PSTR_LIST(enum_hamode, F_(off), F_(heat), F_(auto), F_(heat), F_(off), F_(heat), F_(auto), F_(auto), F_(auto), F_(auto))
|
||||
|
||||
@@ -254,17 +262,15 @@ MAKE_PSTR_LIST(enum_hamode, F_(off), F_(heat), F_(auto), F_(heat), F_(off), F_(h
|
||||
*/
|
||||
|
||||
// Boiler
|
||||
//extra commands
|
||||
MAKE_PSTR(wwtapactivated, "wwtapactivated")
|
||||
MAKE_PSTR(maintenance, "maintenance")
|
||||
MAKE_PSTR(error, "error")
|
||||
MAKE_PSTR(reset, "reset")
|
||||
// extra commands
|
||||
MAKE_PSTR_LIST(wwtapactivated, F("wwtapactivated"))
|
||||
MAKE_PSTR_LIST(reset, F("reset"))
|
||||
|
||||
// single mqtt topics
|
||||
MAKE_PSTR(heating_active, "heating_active")
|
||||
MAKE_PSTR(tapwater_active, "tapwater_active")
|
||||
|
||||
// mqtt, commands and text
|
||||
// MAKE_PSTR_LIST(id, F("id"), F("id"))
|
||||
MAKE_PSTR_LIST(burnPeriod, F("burnperiod"), F("min burner periode"))
|
||||
MAKE_PSTR_LIST(heatingActive, F("heatingactive"), F("heating active"))
|
||||
MAKE_PSTR_LIST(tapwaterActive, F("tapwateractive"), F("warm water active"))
|
||||
MAKE_PSTR_LIST(selFlowTemp, F("selflowtemp"), F("selected flow temperature"))
|
||||
@@ -272,7 +278,7 @@ MAKE_PSTR_LIST(selBurnPow, F("selburnpow"), F("burner selected max power"))
|
||||
MAKE_PSTR_LIST(heatingPumpMod, F("heatingpumpmod"), F("heating pump modulation"))
|
||||
MAKE_PSTR_LIST(heatingPump2Mod, F("heatingpump2mod"), F("heating pump 2 modulation"))
|
||||
MAKE_PSTR_LIST(outdoorTemp, F("outdoortemp"), F("outside temperature"))
|
||||
MAKE_PSTR_LIST(curFlowTemp, F("curFlowtemp"), F("current flow temperature"))
|
||||
MAKE_PSTR_LIST(curFlowTemp, F("curflowtemp"), F("current flow temperature"))
|
||||
MAKE_PSTR_LIST(retTemp, F("rettemp"), F("return temperature"))
|
||||
MAKE_PSTR_LIST(switchTemp, F("switchtemp"), F("mixing switch temperature"))
|
||||
MAKE_PSTR_LIST(sysPress, F("syspress"), F("system pressure"))
|
||||
@@ -324,15 +330,15 @@ MAKE_PSTR_LIST(auxElecHeatNrgConsHeating, F("auxelecheatnrgconsheating"), F("aux
|
||||
MAKE_PSTR_LIST(auxElecHeatNrgConsDHW, F("auxelecheatnrgconsww"), F("auxiliary electrical heater energy consumption DHW"))
|
||||
MAKE_PSTR_LIST(maintenanceMessage, F("maintenancemessage"), F("maintenance message"))
|
||||
MAKE_PSTR_LIST(maintenanceDate, F("maintenancedate"), F("maintenance set date"))
|
||||
MAKE_PSTR_LIST(maintenanceType, F("maintenancetype"), F("maintenance scheduled"))
|
||||
MAKE_PSTR_LIST(maintenance, F("maintenance"), F("maintenance scheduled"))
|
||||
MAKE_PSTR_LIST(maintenanceTime, F("maintenancetime"), F("maintenance set time"))
|
||||
|
||||
MAKE_PSTR_LIST(wWSelTemp, F("wwseltemp"), F("selected temperature"))
|
||||
MAKE_PSTR_LIST(wWSetTemp, F("wwsettemp"), F("set temperature"))
|
||||
MAKE_PSTR_LIST(wWType, F("wwtype"), F("type"))
|
||||
MAKE_PSTR_LIST(wWComfort, F("wwcomfort"), F("comfort"))
|
||||
MAKE_PSTR_LIST(wWFlowTempOffset, F("wwFlowtempoffset"), F("flow temperature offset"))
|
||||
MAKE_PSTR_LIST(wWMaxPower, F("wwMaxpower"), F("max power"))
|
||||
MAKE_PSTR_LIST(wWFlowTempOffset, F("wwflowtempoffset"), F("flow temperature offset"))
|
||||
MAKE_PSTR_LIST(wWMaxPower, F("wwmaxpower"), F("max power"))
|
||||
MAKE_PSTR_LIST(wWCircPump, F("wwcircpump"), F("circulation pump available"))
|
||||
MAKE_PSTR_LIST(wWChargeType, F("wwchargetype"), F("charging type"))
|
||||
MAKE_PSTR_LIST(wWDisinfectionTemp, F("wwdisinfectiontemp"), F("disinfection temperature"))
|
||||
@@ -344,29 +350,27 @@ MAKE_PSTR_LIST(wWCurFlow, F("wwcurflow"), F("current tap water flow"))
|
||||
MAKE_PSTR_LIST(wWStorageTemp1, F("wwstoragetemp1"), F("storage intern temperature"))
|
||||
MAKE_PSTR_LIST(wWStorageTemp2, F("wwstoragetemp2"), F("storage extern temperature"))
|
||||
MAKE_PSTR_LIST(wWActivated, F("wwactivated"), F("activated"))
|
||||
MAKE_PSTR_LIST(wWOneTime, F("wwOnetime"), F("one time charging"))
|
||||
MAKE_PSTR_LIST(wWOneTime, F("wwonetime"), F("one time charging"))
|
||||
MAKE_PSTR_LIST(wWDisinfecting, F("wwdisinfecting"), F("disinfecting"))
|
||||
MAKE_PSTR_LIST(wWCharging, F("wwcharging"), F("charging"))
|
||||
MAKE_PSTR_LIST(wWRecharging, F("wwrecharging"), F("recharging"))
|
||||
MAKE_PSTR_LIST(wWTempOK, F("wwtempok"), F("temperature ok"))
|
||||
MAKE_PSTR_LIST(wWActive, F("wwactive"), F("active"))
|
||||
MAKE_PSTR_LIST(wWHeat, F("wwHeat"), F("heating"))
|
||||
MAKE_PSTR_LIST(wWSetPumpPower, F("wWSetPumpPower"), F("pump set power"))
|
||||
MAKE_PSTR_LIST(mixerTemp, F("mixerTemp"), F("mixer temperature"))
|
||||
MAKE_PSTR_LIST(tankMiddleTemp, F("tankMiddleTemp"), F("tank middle temperature (TS3)"))
|
||||
MAKE_PSTR_LIST(wWStarts, F("wwStarts"), F("# starts"))
|
||||
MAKE_PSTR_LIST(wWStarts2, F("wwStarts2"), F("# control starts"))
|
||||
MAKE_PSTR_LIST(wWSetPumpPower, F("wwsetpumppower"), F("pump set power"))
|
||||
MAKE_PSTR_LIST(mixerTemp, F("mixertemp"), F("mixer temperature"))
|
||||
MAKE_PSTR_LIST(tankMiddleTemp, F("tankmiddletemp"), F("tank middle temperature (TS3)"))
|
||||
MAKE_PSTR_LIST(wWStarts, F("wwstarts"), F("# starts"))
|
||||
MAKE_PSTR_LIST(wWStarts2, F("wwstarts2"), F("# control starts"))
|
||||
MAKE_PSTR_LIST(wWWorkM, F("wwworkm"), F("active time"))
|
||||
|
||||
//thermostat
|
||||
// extra commands
|
||||
MAKE_PSTR(remoteTemp, "remotetemp")
|
||||
MAKE_PSTR(pause, "pause")
|
||||
MAKE_PSTR(party, "party")
|
||||
MAKE_PSTR(switchtime, "switchtime")
|
||||
MAKE_PSTR(temp, "temp")
|
||||
|
||||
// thermostat
|
||||
// extra commands, not published yet
|
||||
MAKE_PSTR_LIST(remoteTemp, F("remotetemp"), F("remotetemp"))
|
||||
MAKE_PSTR_LIST(switchtime, F("switchtime"), F("switchtime"))
|
||||
MAKE_PSTR_LIST(temp, F("temp"), F("temporary set temperature"))
|
||||
|
||||
// mqtt values / commands
|
||||
MAKE_PSTR_LIST(dateTime, F("datetime"), F("date/time"))
|
||||
MAKE_PSTR_LIST(errorCode, F("errorcode"), F("error code"))
|
||||
|
||||
@@ -387,11 +391,10 @@ MAKE_PSTR_LIST(floordrytemp, F("floordrytemp"), F("floor drying temperature"))
|
||||
MAKE_PSTR_LIST(wwMode, F("wwmode"), F("warm water mode"))
|
||||
MAKE_PSTR_LIST(wwSetTemp, F("wwsettemp"), F("warm water set temperature"))
|
||||
MAKE_PSTR_LIST(wwSetTempLow, F("wwsettemplow"), F("warm water set temperature low"))
|
||||
// MAKE_PSTR_LIST(wwCircMode, F("wwcircmode"), F("warm water circulation mode"))
|
||||
MAKE_PSTR_LIST(wwExtra1, F("wwextra1"), F("warm water circuit 1 extra"))
|
||||
MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("warm water circuit 2 extra"))
|
||||
|
||||
MAKE_PSTR_LIST(setpoint_roomTemp, F("seltemp"), F("setpoint room temperature"))
|
||||
MAKE_PSTR_LIST(setpoint_roomTemp, F("seltemp"), F("selected room temperature"))
|
||||
MAKE_PSTR_LIST(curr_roomTemp, F("currtemp"), F("current room temperature"))
|
||||
|
||||
MAKE_PSTR_LIST(mode, F("mode"), F("mode"))
|
||||
@@ -402,6 +405,7 @@ MAKE_PSTR_LIST(heattemp, F("heattemp"), F("heat temperature"))
|
||||
MAKE_PSTR_LIST(nighttemp, F("nighttemp"), F("night temperature"))
|
||||
MAKE_PSTR_LIST(ecotemp, F("ecotemp"), F("eco temperature"))
|
||||
MAKE_PSTR_LIST(manualtemp, F("manualtemp"), F("manual temperature"))
|
||||
MAKE_PSTR_LIST(tempautotemp, F("tempautotemp"), F("temporary room temperature automode"))
|
||||
MAKE_PSTR_LIST(comforttemp, F("comforttemp"), F("comfort temperature"))
|
||||
MAKE_PSTR_LIST(summertemp, F("summertemp"), F("summer temperature"))
|
||||
MAKE_PSTR_LIST(designtemp, F("designtemp"), F("design temperature"))
|
||||
@@ -412,16 +416,19 @@ MAKE_PSTR_LIST(roominfluence, F("roominfluence"), F("room influence"))
|
||||
MAKE_PSTR_LIST(nofrosttemp, F("nofrosttemp"), F("nofrost temperature"))
|
||||
MAKE_PSTR_LIST(targetflowtemp, F("targetflowtemp"), F("target flow temperature"))
|
||||
MAKE_PSTR_LIST(heatingtype, F("heatingtype"), F("heating type"))
|
||||
MAKE_PSTR_LIST(summer_setmode, F("summermode"), F("summer mode"))
|
||||
MAKE_PSTR_LIST(summersetmode, F("summersetmode"), F("summer set mode"))
|
||||
MAKE_PSTR_LIST(controlmode, F("controlmode"), F("control mode"))
|
||||
MAKE_PSTR_LIST(control, F("control"), F("control device"))
|
||||
MAKE_PSTR_LIST(program, F("program"), F("program"))
|
||||
MAKE_PSTR_LIST(pause, F("pause"), F("pause time"))
|
||||
MAKE_PSTR_LIST(party, F("party"), F("party time"))
|
||||
|
||||
MAKE_PSTR_LIST(holidaytemp, F("holidaytemp"), F("holiday temperature"))
|
||||
MAKE_PSTR_LIST(summermode, F("summermode"), F("summer mode"))
|
||||
MAKE_PSTR_LIST(holidaymode, F("holidaymode"), F("holiday mode"))
|
||||
MAKE_PSTR_LIST(flowtempoffset, F("flowtempoffset"), F("flow temperature offset"))
|
||||
MAKE_PSTR_LIST(reducemode, F("reducemode"), F("reduce mode"))
|
||||
MAKE_PSTR_LIST(noreducetemp, F("noreducetemp"), F("no reduce below temperature"))
|
||||
|
||||
// heatpump
|
||||
MAKE_PSTR_LIST(airHumidity, F("airhumidity"), F("relative air humidity"))
|
||||
@@ -436,30 +443,28 @@ MAKE_PSTR_LIST(flowTempVf, F("flowtempvf"), F("flow temperature in header (T0/Vf
|
||||
|
||||
MAKE_PSTR_LIST(tempStatus, F("tempstatus"), F("temperature switch in assigned hc (MC1)"))
|
||||
MAKE_PSTR_LIST(wwTemp, F("wwtemp"), F("current warm water temperature"))
|
||||
// MAKE_PSTR_LIST(mixertype, F("type"), F("type"))
|
||||
|
||||
// solar
|
||||
MAKE_PSTR_LIST(collectorTemp, F("collectorTemp"), F("collector temperature (TS1)"))
|
||||
MAKE_PSTR_LIST(tankBottomTemp, F("tankBottomTemp"), F("tank bottom temperature (TS2)"))
|
||||
MAKE_PSTR_LIST(tank2BottomTemp, F("tank2BottomTemp"), F("second tank bottom temperature (TS5)"))
|
||||
MAKE_PSTR_LIST(heatExchangerTemp, F("heatExchangerTemp"), F("heat exchanger temperature (TS6)"))
|
||||
MAKE_PSTR_LIST(collectorTemp, F("collectortemp"), F("collector temperature (TS1)"))
|
||||
MAKE_PSTR_LIST(tankBottomTemp, F("tankbottomtemp"), F("tank bottom temperature (TS2)"))
|
||||
MAKE_PSTR_LIST(tank2BottomTemp, F("tank2bottomtemp"), F("second tank bottom temperature (TS5)"))
|
||||
MAKE_PSTR_LIST(heatExchangerTemp, F("heatexchangertemp"), F("heat exchanger temperature (TS6)"))
|
||||
|
||||
MAKE_PSTR_LIST(tankMaxTemp, F("tankMaxTemp"), F("maximum tank temperature"))
|
||||
MAKE_PSTR_LIST(solarPumpModulation, F("solarPumpModulation"), F("pump modulation (PS1)"))
|
||||
MAKE_PSTR_LIST(cylinderPumpModulation, F("cylinderPumpModulation"), F("cylinder pump modulation (PS5)"))
|
||||
MAKE_PSTR_LIST(tankMaxTemp, F("tankmaxtemp"), F("maximum tank temperature"))
|
||||
MAKE_PSTR_LIST(solarPumpModulation, F("solarpumpmodulation"), F("pump modulation (PS1)"))
|
||||
MAKE_PSTR_LIST(cylinderPumpModulation, F("cylinderpumpmodulation"), F("cylinder pump modulation (PS5)"))
|
||||
|
||||
MAKE_PSTR_LIST(solarPump, F("solarPump"), F("pump (PS1)"))
|
||||
MAKE_PSTR_LIST(valveStatus, F("valveStatus"), F("valve status"))
|
||||
MAKE_PSTR_LIST(tankHeated, F("tankHeated"), F("tank heated"))
|
||||
MAKE_PSTR_LIST(collectorShutdown, F("collectorShutdown"), F("collector shutdown"))
|
||||
MAKE_PSTR_LIST(solarPump, F("solarpump"), F("pump (PS1)"))
|
||||
MAKE_PSTR_LIST(valveStatus, F("valvestatus"), F("valve status"))
|
||||
MAKE_PSTR_LIST(tankHeated, F("tankheated"), F("tank heated"))
|
||||
MAKE_PSTR_LIST(collectorShutdown, F("collectorshutdown"), F("collector shutdown"))
|
||||
|
||||
MAKE_PSTR_LIST(pumpWorkTime, F("pumpWorkTime"), F("pump working time"))
|
||||
MAKE_PSTR_LIST(pumpWorkTime, F("pumpWorktime"), F("pump working time"))
|
||||
|
||||
MAKE_PSTR_LIST(energyLastHour, F("energyLastHour"), F("energy last hour"))
|
||||
MAKE_PSTR_LIST(energyTotal, F("energyTotal"), F("energy total"))
|
||||
MAKE_PSTR_LIST(energyToday, F("energyToday"), F("energy today"))
|
||||
MAKE_PSTR_LIST(energyLastHour, F("energylasthour"), F("energy last hour"))
|
||||
MAKE_PSTR_LIST(energyTotal, F("energytotal"), F("energy total"))
|
||||
MAKE_PSTR_LIST(energyToday, F("energytoday"), F("energy today"))
|
||||
|
||||
// switch
|
||||
MAKE_PSTR_LIST(activated, F("activated"), F("activated"))
|
||||
// MAKE_PSTR_LIST(flowTempHc, F("flowTempHc"), F("flow temperature in assigned hc (TC1)"))
|
||||
MAKE_PSTR_LIST(status, F("status"), F("status"))
|
||||
|
||||
@@ -56,6 +56,7 @@ void Shower::loop() {
|
||||
if (!shower_on_ && (time_now - timer_start_) > SHOWER_MIN_DURATION) {
|
||||
shower_on_ = true;
|
||||
send_mqtt_stat(true);
|
||||
publish_values();
|
||||
LOG_DEBUG(F("[Shower] hot water still running, starting shower timer"));
|
||||
}
|
||||
// check if the shower has been on too long
|
||||
|
||||
@@ -404,8 +404,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) {
|
||||
|
||||
run_test("boiler");
|
||||
|
||||
DynamicJsonDocument doc(EMSESP_JSON_SIZE_LARGE_DYN);
|
||||
JsonObject json = doc.to<JsonObject>();
|
||||
// device type, command, data
|
||||
Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "false");
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#define EMSESP_APP_VERSION "3.0.2b1"
|
||||
#define EMSESP_APP_VERSION "3.0.3b1"
|
||||
#define EMSESP_PLATFORM "ESP32"
|
||||
|
||||
Reference in New Issue
Block a user