Multi-language/I18n support #22

This commit is contained in:
Proddy
2022-08-24 21:50:19 +02:00
parent 763337db3f
commit 1a4ce643fc
84 changed files with 5506 additions and 4196 deletions

View File

@@ -31,7 +31,7 @@ jobs:
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio
platformio upgrade platformio upgrade
platformio update pio pkg update
- name: Build WebUI - name: Build WebUI
run: | run: |

View File

@@ -24,7 +24,7 @@ jobs:
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install -U platformio pip install -U platformio
platformio upgrade platformio upgrade
platformio update pio pkg update
- name: Build WebUI - name: Build WebUI
run: | run: |

View File

@@ -1,5 +1,17 @@
# Changelog # Changelog
# [3.5.0]
## Added
- Translations in Web UI and all device entity names to German. [#22](https://github.com/emsesp/EMS-ESP32/issues/22)
## Fixed
## Changed
## **BREAKING CHANGES:**
# [3.4.2] # [3.4.2]
## Added ## Added

6
esp32_partition_16M.csv Normal file
View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, , 0x2000,
app0, app, ota_0, , 0x7F0000,
app1, app, ota_1, , 0x7F0000,
spiffs, data, spiffs, , 64K,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0x2000
4 app0 app ota_0 0x7F0000
5 app1 app ota_1 0x7F0000
6 spiffs data spiffs 64K

6
esp32_partition_4M.csv Normal file
View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, , 0x2000,
app0, app, ota_0, , 0x1F0000,
app1, app, ota_1, , 0x1F0000,
spiffs, data, spiffs, , 64K,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0x2000
4 app0 app ota_0 0x1F0000
5 app1 app ota_1 0x1F0000
6 spiffs data spiffs 64K

View File

@@ -1,6 +0,0 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xE000, 0x2000,
app0, app, ota_0, 0x10000, 0x1F0000,
app1, app, ota_1, 0x200000, 0x1F0000,
spiffs, data, spiffs, 0x3F0000, 0x10000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xE000 0x2000
4 app0 app ota_0 0x10000 0x1F0000
5 app1 app ota_1 0x200000 0x1F0000
6 spiffs data spiffs 0x3F0000 0x10000

View File

@@ -0,0 +1,5 @@
{
"adapter": "react",
"baseLocale": "en",
"$schema": "https://unpkg.com/typesafe-i18n@5.12.0/schema/typesafe-i18n.json"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,18 @@
{ {
"name": "EMS-ESP", "name": "EMS-ESP",
"version": "3.4.0", "version": "3.5.0",
"private": true, "private": true,
"proxy": "http://localhost:3080", "proxy": "http://localhost:3080",
"dependencies": { "dependencies": {
"@emotion/react": "^11.10.0", "@emotion/react": "^11.10.0",
"@emotion/styled": "^11.10.0", "@emotion/styled": "^11.10.0",
"@msgpack/msgpack": "^2.7.2", "@msgpack/msgpack": "^2.7.2",
"@mui/icons-material": "^5.8.4", "@mui/icons-material": "^5.10.2",
"@mui/material": "^5.9.3", "@mui/material": "^5.10.2",
"@table-library/react-table-library": "4.0.10", "@table-library/react-table-library": "4.0.12",
"@types/lodash": "^4.14.182", "@types/lodash": "^4.14.184",
"@types/node": "^18.6.3", "@types/node": "^18.7.13",
"@types/react": "^18.0.15", "@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"async-validator": "^4.2.5", "async-validator": "^4.2.5",
@@ -30,6 +30,7 @@
"react-router-dom": "^6.3.0", "react-router-dom": "^6.3.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"sockette": "^2.0.6", "sockette": "^2.0.6",
"typesafe-i18n": "^5.12.0",
"typescript": "^4.7.4" "typescript": "^4.7.4"
}, },
"scripts": { "scripts": {
@@ -41,8 +42,9 @@
"build-hosted": "env-cmd -f .env.hosted npm run build", "build-hosted": "env-cmd -f .env.hosted npm run build",
"build-localhost": "PUBLIC_URL=/ react-app-rewired build", "build-localhost": "PUBLIC_URL=/ react-app-rewired build",
"mock-api": "nodemon --watch ../mock-api ../mock-api/server.js", "mock-api": "nodemon --watch ../mock-api ../mock-api/server.js",
"standalone": "npm-run-all -p start mock-api", "standalone": "npm-run-all -p start typesafe-i18n mock-api",
"lint": "eslint . --ext .ts,.tsx" "lint": "eslint . --ext .ts,.tsx",
"typesafe-i18n": "typesafe-i18n"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [

View File

@@ -1,4 +1,4 @@
import { FC, createRef, createContext, useContext, RefObject } from 'react'; import { FC, createRef, createContext, useContext, useEffect, useState, RefObject } from 'react';
import { SnackbarProvider } from 'notistack'; import { SnackbarProvider } from 'notistack';
import { IconButton } from '@mui/material'; import { IconButton } from '@mui/material';
@@ -9,6 +9,13 @@ import { FeaturesLoader } from './contexts/features';
import CustomTheme from './CustomTheme'; import CustomTheme from './CustomTheme';
import AppRouting from './AppRouting'; import AppRouting from './AppRouting';
import { localStorageDetector } from 'typesafe-i18n/detectors';
import TypesafeI18n from './i18n/i18n-react';
import { detectLocale } from './i18n/i18n-util';
import { loadLocaleAsync } from './i18n/i18n-util.async';
const detectedLocale = detectLocale(localStorageDetector);
const App: FC = () => { const App: FC = () => {
const notistackRef: RefObject<any> = createRef(); const notistackRef: RefObject<any> = createRef();
@@ -20,8 +27,17 @@ const App: FC = () => {
const colorMode = useContext(ColorModeContext); const colorMode = useContext(ColorModeContext);
const [wasLoaded, setWasLoaded] = useState(false);
useEffect(() => {
loadLocaleAsync(detectedLocale).then(() => setWasLoaded(true));
}, []);
if (!wasLoaded) return null;
return ( return (
<ColorModeContext.Provider value={colorMode}> <ColorModeContext.Provider value={colorMode}>
<TypesafeI18n locale={detectedLocale}>
<CustomTheme> <CustomTheme>
<SnackbarProvider <SnackbarProvider
maxSnack={3} maxSnack={3}
@@ -38,6 +54,7 @@ const App: FC = () => {
</FeaturesLoader> </FeaturesLoader>
</SnackbarProvider> </SnackbarProvider>
</CustomTheme> </CustomTheme>
</TypesafeI18n>
</ColorModeContext.Provider> </ColorModeContext.Provider>
); );
}; };

View File

@@ -2,6 +2,8 @@ import { FC, useContext, useEffect } from 'react';
import { Navigate, Routes, Route, useLocation } from 'react-router-dom'; import { Navigate, Routes, Route, useLocation } from 'react-router-dom';
import { useSnackbar, VariantType } from 'notistack'; import { useSnackbar, VariantType } from 'notistack';
import { useI18nContext } from './i18n/i18n-react';
import { Authentication, AuthenticationContext } from './contexts/authentication'; import { Authentication, AuthenticationContext } from './contexts/authentication';
import { FeaturesContext } from './contexts/features'; import { FeaturesContext } from './contexts/features';
import { RequireAuthenticated, RequireUnauthenticated } from './components'; import { RequireAuthenticated, RequireUnauthenticated } from './components';
@@ -41,13 +43,14 @@ export const RemoveTrailingSlashes = () => {
const AppRouting: FC = () => { const AppRouting: FC = () => {
const { features } = useContext(FeaturesContext); const { features } = useContext(FeaturesContext);
const { LL } = useI18nContext();
return ( return (
<Authentication> <Authentication>
<RemoveTrailingSlashes /> <RemoveTrailingSlashes />
<Routes> <Routes>
<Route path="/unauthorized" element={<RootRedirect message="Please sign in to continue" signOut />} /> <Route path="/unauthorized" element={<RootRedirect message={LL.PLEASE_SIGNIN()} signOut />} />
<Route path="/fileUpdated" element={<RootRedirect message="Upload successful" variant="success" />} /> <Route path="/fileUpdated" element={<RootRedirect message={LL.UPLOAD_SUCCESSFUL()} variant="success" />} />
{features.security && ( {features.security && (
<Route <Route
path="/" path="/"

View File

@@ -1,8 +1,8 @@
import { FC, useContext, useState } from 'react'; import { FC, useContext, useState, ChangeEventHandler } from 'react';
import { ValidateFieldsError } from 'async-validator'; import { ValidateFieldsError } from 'async-validator';
import { useSnackbar } from 'notistack'; import { useSnackbar } from 'notistack';
import { Box, Fab, Paper, Typography } from '@mui/material'; import { Box, Fab, Paper, Typography, MenuItem } from '@mui/material';
import ForwardIcon from '@mui/icons-material/Forward'; import ForwardIcon from '@mui/icons-material/Forward';
import * as AuthenticationApi from './api/authentication'; import * as AuthenticationApi from './api/authentication';
@@ -16,6 +16,11 @@ import { SignInRequest } from './types';
import { ValidatedTextField } from './components'; import { ValidatedTextField } from './components';
import { SIGN_IN_REQUEST_VALIDATOR, validate } from './validators'; import { SIGN_IN_REQUEST_VALIDATOR, validate } from './validators';
import { I18nContext } from './i18n/i18n-react';
import type { Locales } from './i18n/i18n-types';
import { locales } from './i18n/i18n-util';
import { loadLocaleAsync } from './i18n/i18n-util.async';
const SignIn: FC = () => { const SignIn: FC = () => {
const authenticationContext = useContext(AuthenticationContext); const authenticationContext = useContext(AuthenticationContext);
const { enqueueSnackbar } = useSnackbar(); const { enqueueSnackbar } = useSnackbar();
@@ -31,6 +36,9 @@ const SignIn: FC = () => {
const validateAndSignIn = async () => { const validateAndSignIn = async () => {
setProcessing(true); setProcessing(true);
SIGN_IN_REQUEST_VALIDATOR.messages({
required: '%s ' + LL.IS_REQUIRED()
});
try { try {
await validate(SIGN_IN_REQUEST_VALIDATOR, signInRequest); await validate(SIGN_IN_REQUEST_VALIDATOR, signInRequest);
signIn(); signIn();
@@ -47,7 +55,7 @@ const SignIn: FC = () => {
} catch (error: unknown) { } catch (error: unknown) {
if (error instanceof AxiosError) { if (error instanceof AxiosError) {
if (error.response?.status === 401) { if (error.response?.status === 401) {
enqueueSnackbar('Invalid login details', { variant: 'warning' }); enqueueSnackbar(LL.INVALID_LOGIN(), { variant: 'warning' });
} }
} else { } else {
enqueueSnackbar(extractErrorMessage(error, 'Unexpected error, please try again'), { variant: 'error' }); enqueueSnackbar(extractErrorMessage(error, 'Unexpected error, please try again'), { variant: 'error' });
@@ -58,6 +66,15 @@ const SignIn: FC = () => {
const submitOnEnter = onEnterCallback(signIn); const submitOnEnter = onEnterCallback(signIn);
const { locale, LL, setLocale } = useContext(I18nContext);
const onLocaleSelected: ChangeEventHandler<HTMLInputElement> = async ({ target }) => {
const loc = target.value as Locales;
localStorage.setItem('lang', loc);
await loadLocaleAsync(loc);
setLocale(loc);
};
return ( return (
<Box <Box
display="flex" display="flex"
@@ -81,11 +98,33 @@ const SignIn: FC = () => {
})} })}
> >
<Typography variant="h4">{PROJECT_NAME}</Typography> <Typography variant="h4">{PROJECT_NAME}</Typography>
<Box
sx={{
'& .MuiTextField-root': { m: 2, width: '15ch' }
}}
>
<ValidatedTextField
name="locale"
label={LL.LANGUAGE()}
variant="outlined"
value={locale || ''}
onChange={onLocaleSelected}
margin="normal"
size="small"
select
>
{locales.map((loc) => (
<MenuItem key={loc} value={loc}>
{loc}
</MenuItem>
))}
</ValidatedTextField>
</Box>
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
disabled={processing} disabled={processing}
name="username" name="username"
label="Username" label={LL.USERNAME()}
value={signInRequest.username} value={signInRequest.username}
onChange={updateLoginRequestValue} onChange={updateLoginRequestValue}
margin="normal" margin="normal"
@@ -97,7 +136,7 @@ const SignIn: FC = () => {
disabled={processing} disabled={processing}
type="password" type="password"
name="password" name="password"
label="Password" label={LL.PASSWORD()}
value={signInRequest.password} value={signInRequest.password}
onChange={updateLoginRequestValue} onChange={updateLoginRequestValue}
onKeyDown={submitOnEnter} onKeyDown={submitOnEnter}
@@ -107,7 +146,7 @@ const SignIn: FC = () => {
/> />
<Fab variant="extended" color="primary" sx={{ mt: 2 }} onClick={validateAndSignIn} disabled={processing}> <Fab variant="extended" color="primary" sx={{ mt: 2 }} onClick={validateAndSignIn} disabled={processing}>
<ForwardIcon sx={{ mr: 1 }} /> <ForwardIcon sx={{ mr: 1 }} />
Sign In {LL.SIGN_IN()}
</Fab> </Fab>
</Paper> </Paper>
</Box> </Box>

View File

@@ -15,9 +15,12 @@ import ProjectMenu from '../../project/ProjectMenu';
import LayoutMenuItem from './LayoutMenuItem'; import LayoutMenuItem from './LayoutMenuItem';
import { AuthenticatedContext } from '../../contexts/authentication'; import { AuthenticatedContext } from '../../contexts/authentication';
import { useI18nContext } from '../../i18n/i18n-react';
const LayoutMenu: FC = () => { const LayoutMenu: FC = () => {
const { features } = useContext(FeaturesContext); const { features } = useContext(FeaturesContext);
const authenticatedContext = useContext(AuthenticatedContext); const authenticatedContext = useContext(AuthenticatedContext);
const { LL } = useI18nContext();
return ( return (
<> <>
@@ -28,11 +31,11 @@ const LayoutMenu: FC = () => {
</List> </List>
)} )}
<List disablePadding component="nav"> <List disablePadding component="nav">
<LayoutMenuItem icon={SettingsEthernetIcon} label="Network Connection" to="/network" /> <LayoutMenuItem icon={SettingsEthernetIcon} label={LL.NETWORK_CONNECTION()} to="/network" />
<LayoutMenuItem icon={SettingsInputAntennaIcon} label="Access Point" to="/ap" /> <LayoutMenuItem icon={SettingsInputAntennaIcon} label="Access Point" to="/ap" />
{features.ntp && <LayoutMenuItem icon={AccessTimeIcon} label="Network Time" to="/ntp" />} {features.ntp && <LayoutMenuItem icon={AccessTimeIcon} label={LL.NETWORK_TIME()} to="/ntp" />}
{features.mqtt && <LayoutMenuItem icon={DeviceHubIcon} label="MQTT" to="/mqtt" />} {features.mqtt && <LayoutMenuItem icon={DeviceHubIcon} label="MQTT" to="/mqtt" />}
<LayoutMenuItem icon={LockIcon} label="Security" to="/security" disabled={!authenticatedContext.me.admin} /> <LayoutMenuItem icon={LockIcon} label={LL.SECURITY()} to="/security" disabled={!authenticatedContext.me.admin} />
<LayoutMenuItem icon={SettingsIcon} label="System" to="/system" /> <LayoutMenuItem icon={SettingsIcon} label="System" to="/system" />
</List> </List>
</> </>

View File

@@ -2,6 +2,8 @@ import { FC, useCallback, useContext, useEffect, useState } from 'react';
import { useSnackbar } from 'notistack'; import { useSnackbar } from 'notistack';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useI18nContext } from '../../i18n/i18n-react';
import * as AuthenticationApi from '../../api/authentication'; import * as AuthenticationApi from '../../api/authentication';
import { ACCESS_TOKEN } from '../../api/endpoints'; import { ACCESS_TOKEN } from '../../api/endpoints';
import { RequiredChildrenProps } from '../../utils'; import { RequiredChildrenProps } from '../../utils';
@@ -12,6 +14,8 @@ import { AuthenticationContext } from './context';
const Authentication: FC<RequiredChildrenProps> = ({ children }) => { const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
const { features } = useContext(FeaturesContext); const { features } = useContext(FeaturesContext);
const { LL } = useI18nContext();
const navigate = useNavigate(); const navigate = useNavigate();
const { enqueueSnackbar } = useSnackbar(); const { enqueueSnackbar } = useSnackbar();
@@ -23,7 +27,7 @@ const Authentication: FC<RequiredChildrenProps> = ({ children }) => {
AuthenticationApi.getStorage().setItem(ACCESS_TOKEN, accessToken); AuthenticationApi.getStorage().setItem(ACCESS_TOKEN, accessToken);
const decodedMe = AuthenticationApi.decodeMeJWT(accessToken); const decodedMe = AuthenticationApi.decodeMeJWT(accessToken);
setMe(decodedMe); setMe(decodedMe);
enqueueSnackbar(`Logged in as ${decodedMe.username}`, { variant: 'success' }); enqueueSnackbar(LL.LOGGED_IN({ name: decodedMe.username }), { variant: 'success' });
} catch (error: unknown) { } catch (error: unknown) {
setMe(undefined); setMe(undefined);
throw new Error('Failed to parse JWT'); throw new Error('Failed to parse JWT');

View File

@@ -1,7 +1,7 @@
import { FC, useState } from 'react'; import { FC, useState } from 'react';
import { ValidateFieldsError } from 'async-validator'; import { ValidateFieldsError } from 'async-validator';
import { Button, Checkbox, MenuItem, Grid, Typography } from '@mui/material'; import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment } from '@mui/material';
import SaveIcon from '@mui/icons-material/Save'; import SaveIcon from '@mui/icons-material/Save';
import { MQTT_SETTINGS_VALIDATOR, validate } from '../../validators'; import { MQTT_SETTINGS_VALIDATOR, validate } from '../../validators';
@@ -129,7 +129,10 @@ const MqttSettingsForm: FC = () => {
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="keep_alive" name="keep_alive"
label="Keep Alive (seconds)" label="Keep Alive"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={numberValue(data.keep_alive)} value={numberValue(data.keep_alive)}
@@ -149,7 +152,7 @@ const MqttSettingsForm: FC = () => {
margin="normal" margin="normal"
select select
> >
<MenuItem value={0}>0 (default)</MenuItem> <MenuItem value={0}>0</MenuItem>
<MenuItem value={1}>1</MenuItem> <MenuItem value={1}>1</MenuItem>
<MenuItem value={2}>2</MenuItem> <MenuItem value={2}>2</MenuItem>
</ValidatedTextField> </ValidatedTextField>
@@ -227,7 +230,7 @@ const MqttSettingsForm: FC = () => {
</Grid> </Grid>
)} )}
<Typography sx={{ pt: 2 }} variant="h6" color="primary"> <Typography sx={{ pt: 2 }} variant="h6" color="primary">
Publish Intervals (in seconds, 0=automatic) Publish Intervals (0=auto)
</Typography> </Typography>
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start"> <Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={4}> <Grid item xs={4}>
@@ -235,6 +238,9 @@ const MqttSettingsForm: FC = () => {
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="publish_time_boiler" name="publish_time_boiler"
label="Boilers and Heat Pumps" label="Boilers and Heat Pumps"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={numberValue(data.publish_time_boiler)} value={numberValue(data.publish_time_boiler)}
@@ -248,6 +254,9 @@ const MqttSettingsForm: FC = () => {
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="publish_time_thermostat" name="publish_time_thermostat"
label="Thermostats" label="Thermostats"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={numberValue(data.publish_time_thermostat)} value={numberValue(data.publish_time_thermostat)}
@@ -261,6 +270,9 @@ const MqttSettingsForm: FC = () => {
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="publish_time_solar" name="publish_time_solar"
label="Solar Modules" label="Solar Modules"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={numberValue(data.publish_time_solar)} value={numberValue(data.publish_time_solar)}
@@ -274,6 +286,9 @@ const MqttSettingsForm: FC = () => {
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="publish_time_mixer" name="publish_time_mixer"
label="Mixer Modules" label="Mixer Modules"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={numberValue(data.publish_time_mixer)} value={numberValue(data.publish_time_mixer)}
@@ -287,6 +302,9 @@ const MqttSettingsForm: FC = () => {
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="publish_time_sensor" name="publish_time_sensor"
label="Temperature Sensors" label="Temperature Sensors"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={numberValue(data.publish_time_sensor)} value={numberValue(data.publish_time_sensor)}
@@ -299,6 +317,9 @@ const MqttSettingsForm: FC = () => {
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="publish_time_other" name="publish_time_other"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
label="Default" label="Default"
fullWidth fullWidth
variant="outlined" variant="outlined"

View File

@@ -11,12 +11,16 @@ import NetworkStatusForm from './NetworkStatusForm';
import WiFiNetworkScanner from './WiFiNetworkScanner'; import WiFiNetworkScanner from './WiFiNetworkScanner';
import NetworkSettingsForm from './NetworkSettingsForm'; import NetworkSettingsForm from './NetworkSettingsForm';
import { useI18nContext } from '../../i18n/i18n-react';
const NetworkConnection: FC = () => { const NetworkConnection: FC = () => {
useLayoutTitle('Network Connection'); const { LL } = useI18nContext();
useLayoutTitle(LL.NETWORK_CONNECTION());
const { routerTab } = useRouterTab();
const authenticatedContext = useContext(AuthenticatedContext); const authenticatedContext = useContext(AuthenticatedContext);
const navigate = useNavigate(); const navigate = useNavigate();
const { routerTab } = useRouterTab();
const [selectedNetwork, setSelectedNetwork] = useState<WiFiNetwork>(); const [selectedNetwork, setSelectedNetwork] = useState<WiFiNetwork>();

View File

@@ -10,7 +10,8 @@ import {
ListItemAvatar, ListItemAvatar,
ListItemSecondaryAction, ListItemSecondaryAction,
ListItemText, ListItemText,
Typography Typography,
InputAdornment
} from '@mui/material'; } from '@mui/material';
import LockOpenIcon from '@mui/icons-material/LockOpen'; import LockOpenIcon from '@mui/icons-material/LockOpen';
@@ -135,7 +136,10 @@ const WiFiSettingsForm: FC = () => {
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="tx_power" name="tx_power"
label="WiFi Tx Power (dBm)" label="WiFi Tx Power"
InputProps={{
endAdornment: <InputAdornment position="end">dBm</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={numberValue(data.tx_power)} value={numberValue(data.tx_power)}

View File

@@ -9,8 +9,11 @@ import { AuthenticatedContext } from '../../contexts/authentication';
import NTPStatusForm from './NTPStatusForm'; import NTPStatusForm from './NTPStatusForm';
import NTPSettingsForm from './NTPSettingsForm'; import NTPSettingsForm from './NTPSettingsForm';
import { useI18nContext } from '../../i18n/i18n-react';
const NetworkTime: FC = () => { const NetworkTime: FC = () => {
useLayoutTitle('Network Time'); const { LL } = useI18nContext();
useLayoutTitle(LL.NETWORK_TIME());
const authenticatedContext = useContext(AuthenticatedContext); const authenticatedContext = useContext(AuthenticatedContext);
const { routerTab } = useRouterTab(); const { routerTab } = useRouterTab();

View File

@@ -8,8 +8,11 @@ import { RouterTabs, useRouterTab, useLayoutTitle } from '../../components';
import SecuritySettingsForm from './SecuritySettingsForm'; import SecuritySettingsForm from './SecuritySettingsForm';
import ManageUsersForm from './ManageUsersForm'; import ManageUsersForm from './ManageUsersForm';
import { useI18nContext } from '../../i18n/i18n-react';
const Security: FC = () => { const Security: FC = () => {
useLayoutTitle('Security'); const { LL } = useI18nContext();
useLayoutTitle(LL.SECURITY());
const { routerTab } = useRouterTab(); const { routerTab } = useRouterTab();

View File

@@ -72,7 +72,7 @@ const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
{!uploading && ( {!uploading && (
<Box mb={2} color="warning.main"> <Box mb={2} color="warning.main">
<Typography variant="body2"> <Typography variant="body2">
Upload a new firmware (.bin) file, settings or customizations (.json) file below. Upload a new firmware (.bin) file, settings or customizations (.json) file below
</Typography> </Typography>
</Box> </Box>
)} )}
@@ -86,7 +86,7 @@ const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
<Box color="warning.main"> <Box color="warning.main">
<Typography mb={1} variant="body2"> <Typography mb={1} variant="body2">
Download the application settings. Be careful when sharing your settings as this file contains passwords Download the application settings. Be careful when sharing your settings as this file contains passwords
and other sensitive system information. and other sensitive system information
</Typography> </Typography>
</Box> </Box>
<Button startIcon={<DownloadIcon />} variant="outlined" color="primary" onClick={() => downloadSettings()}> <Button startIcon={<DownloadIcon />} variant="outlined" color="primary" onClick={() => downloadSettings()}>
@@ -95,7 +95,7 @@ const GeneralFileUpload: FC<UploadFileProps> = ({ uploadGeneralFile }) => {
<Box color="warning.main"> <Box color="warning.main">
<Typography mt={2} mb={1} variant="body2"> <Typography mt={2} mb={1} variant="body2">
Download the entity customizations. Download the entity customizations
</Typography> </Typography>
</Box> </Box>
<Button <Button

View File

@@ -0,0 +1,49 @@
import type { Translation } from '../i18n-types';
const de: Translation = {
LANGUAGE: 'Sprache',
IS_REQUIRED: 'ist nötig',
SIGN_IN: 'Einloggen',
USERNAME: 'Nutzername',
PASSWORD: 'Passwort',
DASHBOARD: 'Armaturenbrett',
SETTINGS: 'Einstellungen',
HELP: 'Hilfe',
LOGGED_IN: 'Eingeloggt als {name}',
PLEASE_SIGNIN: 'Bitte einloggen, um fortzufahren',
UPLOAD_SUCCESSFUL: 'Hochladen erfolgreich',
INVALID_LOGIN: 'Ungültige Login Daten',
NETWORK_CONNECTION: 'Netzwerkverbindung',
SECURITY: 'Sicherheit',
NETWORK_TIME: 'Netzwerkzeit',
ONOFF_CAP: 'AN/AUS',
ONOFF: 'an/aus',
TYPE: 'Typ',
DESCRIPTION: 'Bezeichnung',
ENTITIES: 'Entitäten',
REFRESH: 'Aktualisierung',
EXPORT: 'Export',
ENTITY_NAME: 'Entitätsname',
VALUE: 'Wert',
SHOW_FAV: 'nur Favoriten anzeigen',
DEVICE_SENSOR_DATA: 'Device und Sensordaten',
DEVICES_SENSORS: 'Devices & Sensoren',
ATTACHED_SENSORS: 'Angeschlossene EMS-ESP Sensoren',
RUN_COMMAND: 'Befehl ausführen',
CHANGE_VALUE: 'Wert ändern',
CANCEL: 'Absagen',
RESET: 'Zurücksetzen',
SEND: 'Senden',
SAVE: 'Speichern',
REMOVE: 'Entfernen',
PROBLEM_UPDATING: 'Problem beim Aktualisieren',
ACCESS_DENIED: 'Zugriff abgelehnt',
ANALOG_SENSOR: 'Analoger Sensor {cmd}',
TEMP_SENSOR: 'Temperatursensor {cmd}',
WRITE_COMMAND: 'Befehl schreiben {cmd}',
EMS_BUS_WARNING:
'EMS-Bus getrennt. Wenn diese Warnung nach einigen Sekunden immer noch besteht, überprüfen Sie bitte die Einstellungen und das Board-Profil',
EMS_BUS_SCANNING: 'Scannen nach EMS devices...'
};
export default de;

View File

@@ -0,0 +1,49 @@
import type { BaseTranslation } from '../i18n-types';
const en: BaseTranslation = {
LANGUAGE: 'Language',
IS_REQUIRED: 'is required',
SIGN_IN: 'Sign In',
USERNAME: 'Username',
PASSWORD: 'Password',
DASHBOARD: 'Dashboard',
SETTINGS: 'Settings',
HELP: 'Help',
LOGGED_IN: 'Logged in as {name}',
PLEASE_SIGNIN: 'Please sign in to continue',
UPLOAD_SUCCESSFUL: 'Upload successful',
INVALID_LOGIN: 'Invalid login details',
NETWORK_CONNECTION: 'Network Connection',
SECURITY: 'Security',
NETWORK_TIME: 'Network Time',
ONOFF_CAP: 'ON/OFF',
ONOFF: 'on/off',
TYPE: 'Type',
DESCRIPTION: 'Description',
ENTITIES: 'Entities',
REFRESH: 'Refresh',
EXPORT: 'Export',
ENTITY_NAME: 'Entity Name',
VALUE: 'Value',
SHOW_FAV: 'only show favorites',
DEVICE_SENSOR_DATA: 'Device and Sensor Data',
DEVICES_SENSORS: 'Devices & Sensors',
ATTACHED_SENSORS: 'Attached EMS-ESP Sensors',
RUN_COMMAND: 'Call Command',
CHANGE_VALUE: 'Change Value',
CANCEL: 'Cancel',
RESET: 'Reset',
SEND: 'Send',
SAVE: 'Save',
REMOVE: 'Remove',
PROBLEM_UPDATING: 'Problem updating',
ACCESS_DENIED: 'Access Denied',
ANALOG_SENSOR: 'Analog Sensor {cmd}',
TEMP_SENSOR: 'Temperature Sensor {cmd}',
WRITE_COMMAND: 'Write command {cmd}',
EMS_BUS_WARNING:
'EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile',
EMS_BUS_SCANNING: 'Scanning for EMS devices...'
};
export default en;

View File

@@ -0,0 +1,11 @@
import type { FormattersInitializer } from 'typesafe-i18n';
import type { Locales, Formatters } from './i18n-types';
import { date } from 'typesafe-i18n/formatters';
export const initFormatters: FormattersInitializer<Locales, Formatters> = (locale: Locales) => {
const formatters: Formatters = {
weekday: date(locale, { weekday: 'long' })
};
return formatters;
};

View File

@@ -0,0 +1,16 @@
// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
/* eslint-disable */
import { useContext } from 'react'
import { initI18nReact } from 'typesafe-i18n/react'
import type { I18nContextType } from 'typesafe-i18n/react'
import type { Formatters, Locales, TranslationFunctions, Translations } from './i18n-types'
import { loadedFormatters, loadedLocales } from './i18n-util'
const { component: TypesafeI18n, context: I18nContext } = initI18nReact<Locales, Translations, TranslationFunctions, Formatters>(loadedLocales, loadedFormatters)
const useI18nContext = (): I18nContextType<Locales, Translations, TranslationFunctions> => useContext(I18nContext)
export { I18nContext, useI18nContext }
export default TypesafeI18n

View File

@@ -0,0 +1,362 @@
// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
/* eslint-disable */
import type { BaseTranslation as BaseTranslationType, LocalizedString, RequiredParams } from 'typesafe-i18n'
export type BaseTranslation = BaseTranslationType
export type BaseLocale = 'en'
export type Locales =
| 'de'
| 'en'
export type Translation = RootTranslation
export type Translations = RootTranslation
type RootTranslation = {
/**
* Language
*/
LANGUAGE: string
/**
* is required
*/
IS_REQUIRED: string
/**
* Sign In
*/
SIGN_IN: string
/**
* Username
*/
USERNAME: string
/**
* Password
*/
PASSWORD: string
/**
* Dashboard
*/
DASHBOARD: string
/**
* Settings
*/
SETTINGS: string
/**
* Help
*/
HELP: string
/**
* Logged in as {name}
* @param {unknown} name
*/
LOGGED_IN: RequiredParams<'name'>
/**
* Please sign in to continue
*/
PLEASE_SIGNIN: string
/**
* Upload successful
*/
UPLOAD_SUCCESSFUL: string
/**
* Invalid login details
*/
INVALID_LOGIN: string
/**
* Network Connection
*/
NETWORK_CONNECTION: string
/**
* Security
*/
SECURITY: string
/**
* Network Time
*/
NETWORK_TIME: string
/**
* ON/OFF
*/
ONOFF_CAP: string
/**
* on/off
*/
ONOFF: string
/**
* Type
*/
TYPE: string
/**
* Description
*/
DESCRIPTION: string
/**
* Entities
*/
ENTITIES: string
/**
* Refresh
*/
REFRESH: string
/**
* Export
*/
EXPORT: string
/**
* Entity Name
*/
ENTITY_NAME: string
/**
* Value
*/
VALUE: string
/**
* only show favorites
*/
SHOW_FAV: string
/**
* Device and Sensor Data
*/
DEVICE_SENSOR_DATA: string
/**
* Devices & Sensors
*/
DEVICES_SENSORS: string
/**
* Attached EMS-ESP Sensors
*/
ATTACHED_SENSORS: string
/**
* Call Command
*/
RUN_COMMAND: string
/**
* Change Value
*/
CHANGE_VALUE: string
/**
* Cancel
*/
CANCEL: string
/**
* Reset
*/
RESET: string
/**
* Send
*/
SEND: string
/**
* Save
*/
SAVE: string
/**
* Remove
*/
REMOVE: string
/**
* Problem updating
*/
PROBLEM_UPDATING: string
/**
* Access Denied
*/
ACCESS_DENIED: string
/**
* Analog Sensor {cmd}
* @param {unknown} cmd
*/
ANALOG_SENSOR: RequiredParams<'cmd'>
/**
* Temperature Sensor {cmd}
* @param {unknown} cmd
*/
TEMP_SENSOR: RequiredParams<'cmd'>
/**
* Write command {cmd}
* @param {unknown} cmd
*/
WRITE_COMMAND: RequiredParams<'cmd'>
/**
* EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile
*/
EMS_BUS_WARNING: string
/**
* Scanning for EMS devices...
*/
EMS_BUS_SCANNING: string
}
export type TranslationFunctions = {
/**
* Language
*/
LANGUAGE: () => LocalizedString
/**
* is required
*/
IS_REQUIRED: () => LocalizedString
/**
* Sign In
*/
SIGN_IN: () => LocalizedString
/**
* Username
*/
USERNAME: () => LocalizedString
/**
* Password
*/
PASSWORD: () => LocalizedString
/**
* Dashboard
*/
DASHBOARD: () => LocalizedString
/**
* Settings
*/
SETTINGS: () => LocalizedString
/**
* Help
*/
HELP: () => LocalizedString
/**
* Logged in as {name}
*/
LOGGED_IN: (arg: { name: unknown }) => LocalizedString
/**
* Please sign in to continue
*/
PLEASE_SIGNIN: () => LocalizedString
/**
* Upload successful
*/
UPLOAD_SUCCESSFUL: () => LocalizedString
/**
* Invalid login details
*/
INVALID_LOGIN: () => LocalizedString
/**
* Network Connection
*/
NETWORK_CONNECTION: () => LocalizedString
/**
* Security
*/
SECURITY: () => LocalizedString
/**
* Network Time
*/
NETWORK_TIME: () => LocalizedString
/**
* ON/OFF
*/
ONOFF_CAP: () => LocalizedString
/**
* on/off
*/
ONOFF: () => LocalizedString
/**
* Type
*/
TYPE: () => LocalizedString
/**
* Description
*/
DESCRIPTION: () => LocalizedString
/**
* Entities
*/
ENTITIES: () => LocalizedString
/**
* Refresh
*/
REFRESH: () => LocalizedString
/**
* Export
*/
EXPORT: () => LocalizedString
/**
* Entity Name
*/
ENTITY_NAME: () => LocalizedString
/**
* Value
*/
VALUE: () => LocalizedString
/**
* only show favorites
*/
SHOW_FAV: () => LocalizedString
/**
* Device and Sensor Data
*/
DEVICE_SENSOR_DATA: () => LocalizedString
/**
* Devices & Sensors
*/
DEVICES_SENSORS: () => LocalizedString
/**
* Attached EMS-ESP Sensors
*/
ATTACHED_SENSORS: () => LocalizedString
/**
* Call Command
*/
RUN_COMMAND: () => LocalizedString
/**
* Change Value
*/
CHANGE_VALUE: () => LocalizedString
/**
* Cancel
*/
CANCEL: () => LocalizedString
/**
* Reset
*/
RESET: () => LocalizedString
/**
* Send
*/
SEND: () => LocalizedString
/**
* Save
*/
SAVE: () => LocalizedString
/**
* Remove
*/
REMOVE: () => LocalizedString
/**
* Problem updating
*/
PROBLEM_UPDATING: () => LocalizedString
/**
* Access Denied
*/
ACCESS_DENIED: () => LocalizedString
/**
* Analog Sensor {cmd}
*/
ANALOG_SENSOR: (arg: { cmd: unknown }) => LocalizedString
/**
* Temperature Sensor {cmd}
*/
TEMP_SENSOR: (arg: { cmd: unknown }) => LocalizedString
/**
* Write command {cmd}
*/
WRITE_COMMAND: (arg: { cmd: unknown }) => LocalizedString
/**
* EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile
*/
EMS_BUS_WARNING: () => LocalizedString
/**
* Scanning for EMS devices...
*/
EMS_BUS_SCANNING: () => LocalizedString
}
export type Formatters = {}

View File

@@ -0,0 +1,27 @@
// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
/* eslint-disable */
import { initFormatters } from './formatters'
import type { Locales, Translations } from './i18n-types'
import { loadedFormatters, loadedLocales, locales } from './i18n-util'
const localeTranslationLoaders = {
de: () => import('./de'),
en: () => import('./en'),
}
const updateDictionary = (locale: Locales, dictionary: Partial<Translations>) =>
loadedLocales[locale] = { ...loadedLocales[locale], ...dictionary }
export const importLocaleAsync = async (locale: Locales) =>
(await localeTranslationLoaders[locale]()).default as unknown as Translations
export const loadLocaleAsync = async (locale: Locales): Promise<void> => {
updateDictionary(locale, await importLocaleAsync(locale))
loadFormatters(locale)
}
export const loadAllLocalesAsync = (): Promise<void[]> => Promise.all(locales.map(loadLocaleAsync))
export const loadFormatters = (locale: Locales): void =>
void (loadedFormatters[locale] = initFormatters(locale))

View File

@@ -0,0 +1,26 @@
// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
/* eslint-disable */
import { initFormatters } from './formatters'
import type { Locales, Translations } from './i18n-types'
import { loadedFormatters, loadedLocales, locales } from './i18n-util'
import de from './de'
import en from './en'
const localeTranslations = {
de,
en,
}
export const loadLocale = (locale: Locales): void => {
if (loadedLocales[locale]) return
loadedLocales[locale] = localeTranslations[locale] as unknown as Translations
loadFormatters(locale)
}
export const loadAllLocales = (): void => locales.forEach(loadLocale)
export const loadFormatters = (locale: Locales): void =>
void (loadedFormatters[locale] = initFormatters(locale))

View File

@@ -0,0 +1,31 @@
// This file was auto-generated by 'typesafe-i18n'. Any manual changes will be overwritten.
/* eslint-disable */
import { i18n as initI18n, i18nObject as initI18nObject, i18nString as initI18nString } from 'typesafe-i18n'
import type { LocaleDetector } from 'typesafe-i18n/detectors'
import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors'
import type { Formatters, Locales, Translations, TranslationFunctions } from './i18n-types'
export const baseLocale: Locales = 'en'
export const locales: Locales[] = [
'de',
'en'
]
export const loadedLocales = {} as Record<Locales, Translations>
export const loadedFormatters = {} as Record<Locales, Formatters>
export const i18nString = (locale: Locales) => initI18nString<Locales, Formatters>(locale, loadedFormatters[locale])
export const i18nObject = (locale: Locales) =>
initI18nObject<Locales, Translations, TranslationFunctions, Formatters>(
locale,
loadedLocales[locale],
loadedFormatters[locale]
)
export const i18n = () => initI18n<Locales, Translations, TranslationFunctions, Formatters>(loadedLocales, loadedFormatters)
export const detectLocale = (...detectors: LocaleDetector[]) => detectLocaleFn<Locales>(baseLocale, locales, ...detectors)

View File

@@ -5,17 +5,21 @@ import { Tab } from '@mui/material';
import { RouterTabs, useRouterTab, useLayoutTitle } from '../components'; import { RouterTabs, useRouterTab, useLayoutTitle } from '../components';
import { useI18nContext } from '../i18n/i18n-react';
import DashboardStatus from './DashboardStatus'; import DashboardStatus from './DashboardStatus';
import DashboardData from './DashboardData'; import DashboardData from './DashboardData';
const Dashboard: FC = () => { const Dashboard: FC = () => {
useLayoutTitle('Dashboard');
const { routerTab } = useRouterTab(); const { routerTab } = useRouterTab();
const { LL } = useI18nContext();
useLayoutTitle(LL.DASHBOARD());
return ( return (
<> <>
<RouterTabs value={routerTab}> <RouterTabs value={routerTab}>
<Tab value="data" label="Devices &amp; Sensors" /> <Tab value="data" label={LL.DEVICES_SENSORS()} />
<Tab value="status" label="Status" /> <Tab value="status" label="Status" />
</RouterTabs> </RouterTabs>
<Routes> <Routes>

View File

@@ -74,12 +74,21 @@ import {
DeviceEntityMask DeviceEntityMask
} from './types'; } from './types';
import { useI18nContext } from '../i18n/i18n-react';
const DashboardData: FC = () => { const DashboardData: FC = () => {
const { me } = useContext(AuthenticatedContext); const { me } = useContext(AuthenticatedContext);
const { LL } = useI18nContext();
const { enqueueSnackbar } = useSnackbar(); const { enqueueSnackbar } = useSnackbar();
const [coreData, setCoreData] = useState<CoreData>({ connected: true, devices: [], active_sensors: 0, analog_enabled: false }); const [coreData, setCoreData] = useState<CoreData>({
connected: true,
devices: [],
active_sensors: 0,
analog_enabled: false
});
const [deviceData, setDeviceData] = useState<DeviceData>({ label: '', data: [] }); const [deviceData, setDeviceData] = useState<DeviceData>({ label: '', data: [] });
const [sensorData, setSensorData] = useState<SensorData>({ sensors: [], analogs: [] }); const [sensorData, setSensorData] = useState<SensorData>({ sensors: [], analogs: [] });
const [deviceValue, setDeviceValue] = useState<DeviceValue>(); const [deviceValue, setDeviceValue] = useState<DeviceValue>();
@@ -134,7 +143,7 @@ const DashboardData: FC = () => {
common_theme, common_theme,
{ {
Table: ` Table: `
--data-table-library_grid-template-columns: 40px 100px repeat(1, minmax(0, 1fr)) 80px 40px; --data-table-library_grid-template-columns: 40px 100px repeat(1, minmax(0, 1fr)) 90px 40px;
`, `,
BaseRow: ` BaseRow: `
.td { .td {
@@ -429,15 +438,15 @@ const DashboardData: FC = () => {
devicevalue: deviceValue devicevalue: deviceValue
}); });
if (response.status === 204) { if (response.status === 204) {
enqueueSnackbar('Write command failed', { variant: 'error' }); enqueueSnackbar(LL.WRITE_COMMAND({ cmd: 'failed' }), { variant: 'error' });
} else if (response.status === 403) { } else if (response.status === 403) {
enqueueSnackbar('Write access denied', { variant: 'error' }); enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
} else { } else {
enqueueSnackbar('Write command sent', { variant: 'success' }); enqueueSnackbar(LL.WRITE_COMMAND({ cmd: 'send' }), { variant: 'success' });
} }
setDeviceValue(undefined); setDeviceValue(undefined);
} catch (error: unknown) { } catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem writing value'), { variant: 'error' }); enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
} finally { } finally {
refreshData(); refreshData();
setDeviceValue(undefined); setDeviceValue(undefined);
@@ -449,7 +458,7 @@ const DashboardData: FC = () => {
if (deviceValue) { if (deviceValue) {
return ( return (
<Dialog open={deviceValue !== undefined} onClose={() => setDeviceValue(undefined)}> <Dialog open={deviceValue !== undefined} onClose={() => setDeviceValue(undefined)}>
<DialogTitle>{isCmdOnly(deviceValue) ? 'Run Command' : 'Change Value'}</DialogTitle> <DialogTitle>{isCmdOnly(deviceValue) ? LL.RUN_COMMAND() : LL.CHANGE_VALUE()}</DialogTitle>
<DialogContent dividers> <DialogContent dividers>
{deviceValue.l && ( {deviceValue.l && (
<ValidatedTextField <ValidatedTextField
@@ -491,7 +500,7 @@ const DashboardData: FC = () => {
onClick={() => setDeviceValue(undefined)} onClick={() => setDeviceValue(undefined)}
color="secondary" color="secondary"
> >
Cancel {LL.CANCEL()}
</Button> </Button>
<Button <Button
startIcon={<SendIcon />} startIcon={<SendIcon />}
@@ -500,7 +509,7 @@ const DashboardData: FC = () => {
onClick={() => sendDeviceValue()} onClick={() => sendDeviceValue()}
color="warning" color="warning"
> >
Send {LL.SEND()}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
@@ -521,15 +530,15 @@ const DashboardData: FC = () => {
offset: sensor.o offset: sensor.o
}); });
if (response.status === 204) { if (response.status === 204) {
enqueueSnackbar('Sensor change failed', { variant: 'error' }); enqueueSnackbar(LL.TEMP_SENSOR({ cmd: 'change failed' }), { variant: 'error' });
} else if (response.status === 403) { } else if (response.status === 403) {
enqueueSnackbar('Access denied', { variant: 'error' }); enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
} else { } else {
enqueueSnackbar('Sensor updated', { variant: 'success' }); enqueueSnackbar(LL.TEMP_SENSOR({ cmd: 'removed' }), { variant: 'success' });
} }
setSensor(undefined); setSensor(undefined);
} catch (error: unknown) { } catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem updating sensor'), { variant: 'error' }); enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
} finally { } finally {
setSensor(undefined); setSensor(undefined);
fetchSensorData(); fetchSensorData();
@@ -581,7 +590,7 @@ const DashboardData: FC = () => {
onClick={() => setSensor(undefined)} onClick={() => setSensor(undefined)}
color="secondary" color="secondary"
> >
Cancel {LL.CANCEL()}
</Button> </Button>
<Button <Button
startIcon={<SaveIcon />} startIcon={<SaveIcon />}
@@ -590,7 +599,7 @@ const DashboardData: FC = () => {
onClick={() => sendSensor()} onClick={() => sendSensor()}
color="warning" color="warning"
> >
Save {LL.SAVE()}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
@@ -640,17 +649,20 @@ const DashboardData: FC = () => {
const renderCoreData = () => ( const renderCoreData = () => (
<IconContext.Provider value={{ color: 'lightblue', size: '24', style: { verticalAlign: 'middle' } }}> <IconContext.Provider value={{ color: 'lightblue', size: '24', style: { verticalAlign: 'middle' } }}>
{!coreData.connected && <MessageBox my={2} level="error" message="EMSbus disconnected, check settings and board profile" />} {!coreData.connected && <MessageBox my={2} level="error" message={LL.EMS_BUS_WARNING()} />}
{coreData.connected && coreData.devices.length === 0 && <MessageBox my={2} level="warning" message="Scanning for EMS devices..." />} {coreData.connected && coreData.devices.length === 0 && (
<MessageBox my={2} level="warning" message={LL.EMS_BUS_SCANNING()} />
)}
<Table data={{ nodes: coreData.devices }} select={device_select} theme={device_theme} layout={{ custom: true }}> <Table data={{ nodes: coreData.devices }} select={device_select} theme={device_theme} layout={{ custom: true }}>
{(tableList: any) => ( {(tableList: any) => (
<> <>
<Header> <Header>
<HeaderRow> <HeaderRow>
<HeaderCell stiff /> <HeaderCell stiff />
<HeaderCell stiff>TYPE</HeaderCell> <HeaderCell stiff>{LL.TYPE()}</HeaderCell>
<HeaderCell resize>DESCRIPTION</HeaderCell> <HeaderCell resize>{LL.DESCRIPTION()}</HeaderCell>
<HeaderCell stiff>ENTITIES</HeaderCell> <HeaderCell stiff>{LL.ENTITIES()}</HeaderCell>
<HeaderCell stiff /> <HeaderCell stiff />
</HeaderRow> </HeaderRow>
</Header> </Header>
@@ -676,7 +688,7 @@ const DashboardData: FC = () => {
<DeviceIcon type="Sensor" /> <DeviceIcon type="Sensor" />
</Cell> </Cell>
<Cell>Sensors</Cell> <Cell>Sensors</Cell>
<Cell>Attached EMS-ESP Sensors</Cell> <Cell>{LL.ATTACHED_SENSORS()}</Cell>
<Cell>{coreData.active_sensors}</Cell> <Cell>{coreData.active_sensors}</Cell>
<Cell> <Cell>
<IconButton size="small" onClick={() => addAnalogSensor()}> <IconButton size="small" onClick={() => addAnalogSensor()}>
@@ -723,7 +735,7 @@ const DashboardData: FC = () => {
control={<Checkbox size="small" name="onlyFav" checked={onlyFav} onChange={() => setOnlyFav(!onlyFav)} />} control={<Checkbox size="small" name="onlyFav" checked={onlyFav} onChange={() => setOnlyFav(!onlyFav)} />}
label={ label={
<span style={{ fontSize: '12px' }}> <span style={{ fontSize: '12px' }}>
only show favorites&nbsp; {LL.SHOW_FAV()}&nbsp;
<StarIcon color="primary" sx={{ fontSize: 12 }} /> <StarIcon color="primary" sx={{ fontSize: 12 }} />
</span> </span>
} }
@@ -749,7 +761,7 @@ const DashboardData: FC = () => {
endIcon={getSortIcon(dv_sort.state, 'NAME')} endIcon={getSortIcon(dv_sort.state, 'NAME')}
onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'NAME' })} onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'NAME' })}
> >
ENTITY NAME {LL.ENTITY_NAME()}
</Button> </Button>
</HeaderCell> </HeaderCell>
<HeaderCell resize> <HeaderCell resize>
@@ -759,7 +771,7 @@ const DashboardData: FC = () => {
endIcon={getSortIcon(dv_sort.state, 'VALUE')} endIcon={getSortIcon(dv_sort.state, 'VALUE')}
onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'VALUE' })} onClick={() => dv_sort.fns.onToggleSort({ sortKey: 'VALUE' })}
> >
VALUE {LL.VALUE()}
</Button> </Button>
</HeaderCell> </HeaderCell>
<HeaderCell stiff /> <HeaderCell stiff />
@@ -943,14 +955,14 @@ const DashboardData: FC = () => {
}); });
if (response.status === 204) { if (response.status === 204) {
enqueueSnackbar('Analog deletion failed', { variant: 'error' }); enqueueSnackbar(LL.ANALOG_SENSOR({ cmd: 'deletion failed' }), { variant: 'error' });
} else if (response.status === 403) { } else if (response.status === 403) {
enqueueSnackbar('Access denied', { variant: 'error' }); enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
} else { } else {
enqueueSnackbar('Analog sensor removed', { variant: 'success' }); enqueueSnackbar(LL.ANALOG_SENSOR({ cmd: 'removed' }), { variant: 'success' });
} }
} catch (error: unknown) { } catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem updating analog sensor'), { variant: 'error' }); enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
} finally { } finally {
setAnalog(undefined); setAnalog(undefined);
fetchSensorData(); fetchSensorData();
@@ -971,14 +983,14 @@ const DashboardData: FC = () => {
}); });
if (response.status === 204) { if (response.status === 204) {
enqueueSnackbar('Analog sensor update failed', { variant: 'error' }); enqueueSnackbar(LL.ANALOG_SENSOR({ cmd: 'update failed' }), { variant: 'error' });
} else if (response.status === 403) { } else if (response.status === 403) {
enqueueSnackbar('Access denied', { variant: 'error' }); enqueueSnackbar(LL.ACCESS_DENIED(), { variant: 'error' });
} else { } else {
enqueueSnackbar('Analog sensor updated', { variant: 'success' }); enqueueSnackbar(LL.ANALOG_SENSOR({ cmd: 'updated' }), { variant: 'success' });
} }
} catch (error: unknown) { } catch (error: unknown) {
enqueueSnackbar(extractErrorMessage(error, 'Problem updating analog'), { variant: 'error' }); enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
} finally { } finally {
setAnalog(undefined); setAnalog(undefined);
fetchSensorData(); fetchSensorData();
@@ -1131,7 +1143,7 @@ const DashboardData: FC = () => {
<Grid item> <Grid item>
<ValidatedTextField <ValidatedTextField
name="o" name="o"
label="Dutycycle" label="Duty Cycle"
value={numberValue(analog.o)} value={numberValue(analog.o)}
sx={{ width: '20ch' }} sx={{ width: '20ch' }}
type="number" type="number"
@@ -1153,7 +1165,7 @@ const DashboardData: FC = () => {
<DialogActions> <DialogActions>
<Box flexGrow={1} sx={{ '& button': { mt: 0 } }}> <Box flexGrow={1} sx={{ '& button': { mt: 0 } }}>
<Button startIcon={<RemoveIcon />} variant="outlined" color="error" onClick={() => sendRemoveAnalog()}> <Button startIcon={<RemoveIcon />} variant="outlined" color="error" onClick={() => sendRemoveAnalog()}>
Remove {LL.REMOVE()}
</Button> </Button>
</Box> </Box>
<Button <Button
@@ -1162,7 +1174,7 @@ const DashboardData: FC = () => {
onClick={() => setAnalog(undefined)} onClick={() => setAnalog(undefined)}
color="secondary" color="secondary"
> >
Cancel {LL.CANCEL()}
</Button> </Button>
<Button <Button
startIcon={<SaveIcon />} startIcon={<SaveIcon />}
@@ -1171,7 +1183,7 @@ const DashboardData: FC = () => {
onClick={() => sendAnalog()} onClick={() => sendAnalog()}
color="warning" color="warning"
> >
Save {LL.SAVE()}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
@@ -1180,7 +1192,7 @@ const DashboardData: FC = () => {
}; };
return ( return (
<SectionContent title="Device and Sensor Data" titleGutter> <SectionContent title={LL.DEVICE_SENSOR_DATA()} titleGutter>
{renderCoreData()} {renderCoreData()}
{renderDeviceData()} {renderDeviceData()}
{renderDeviceDialog()} {renderDeviceDialog()}
@@ -1191,11 +1203,11 @@ const DashboardData: FC = () => {
{renderAnalogDialog()} {renderAnalogDialog()}
<ButtonRow> <ButtonRow>
<Button startIcon={<RefreshIcon />} variant="outlined" color="secondary" onClick={refreshData}> <Button startIcon={<RefreshIcon />} variant="outlined" color="secondary" onClick={refreshData}>
Refresh {LL.REFRESH()}
</Button> </Button>
{device_select.state.id && device_select.state.id !== 'sensor' && ( {device_select.state.id && device_select.state.id !== 'sensor' && (
<Button startIcon={<DownloadIcon />} variant="outlined" onClick={handleDownloadCsv}> <Button startIcon={<DownloadIcon />} variant="outlined" onClick={handleDownloadCsv}>
Export {LL.EXPORT()}
</Button> </Button>
)} )}
</ButtonRow> </ButtonRow>

View File

@@ -5,12 +5,16 @@ import { Tab } from '@mui/material';
import { RouterTabs, useRouterTab, useLayoutTitle } from '../components'; import { RouterTabs, useRouterTab, useLayoutTitle } from '../components';
import { useI18nContext } from '../i18n/i18n-react';
import HelpInformation from './HelpInformation'; import HelpInformation from './HelpInformation';
const Help: FC = () => { const Help: FC = () => {
useLayoutTitle('Help'); const { LL } = useI18nContext();
const { routerTab } = useRouterTab(); const { routerTab } = useRouterTab();
useLayoutTitle(LL.HELP());
return ( return (
<> <>
<RouterTabs value={routerTab}> <RouterTabs value={routerTab}>

View File

@@ -6,6 +6,8 @@ import { AuthenticatedContext } from '../contexts/authentication';
import { PROJECT_PATH } from '../api/env'; import { PROJECT_PATH } from '../api/env';
import { useI18nContext } from '../i18n/i18n-react';
import TuneIcon from '@mui/icons-material/Tune'; import TuneIcon from '@mui/icons-material/Tune';
import DashboardIcon from '@mui/icons-material/Dashboard'; import DashboardIcon from '@mui/icons-material/Dashboard';
import LayoutMenuItem from '../components/layout/LayoutMenuItem'; import LayoutMenuItem from '../components/layout/LayoutMenuItem';
@@ -13,17 +15,18 @@ import InfoIcon from '@mui/icons-material/Info';
const ProjectMenu: FC = () => { const ProjectMenu: FC = () => {
const authenticatedContext = useContext(AuthenticatedContext); const authenticatedContext = useContext(AuthenticatedContext);
const { LL } = useI18nContext();
return ( return (
<List> <List>
<LayoutMenuItem icon={DashboardIcon} label="Dashboard" to={`/${PROJECT_PATH}/dashboard`} /> <LayoutMenuItem icon={DashboardIcon} label={LL.DASHBOARD()} to={`/${PROJECT_PATH}/dashboard`} />
<LayoutMenuItem <LayoutMenuItem
icon={TuneIcon} icon={TuneIcon}
label="Settings" label={LL.SETTINGS()}
to={`/${PROJECT_PATH}/settings`} to={`/${PROJECT_PATH}/settings`}
disabled={!authenticatedContext.me.admin} disabled={!authenticatedContext.me.admin}
/> />
<LayoutMenuItem icon={InfoIcon} label="Help" to={`/${PROJECT_PATH}/help`} /> <LayoutMenuItem icon={InfoIcon} label={LL.HELP()} to={`/${PROJECT_PATH}/help`} />
</List> </List>
); );
}; };

View File

@@ -5,13 +5,17 @@ import { Tab } from '@mui/material';
import { RouterTabs, useRouterTab, useLayoutTitle } from '../components'; import { RouterTabs, useRouterTab, useLayoutTitle } from '../components';
import { useI18nContext } from '../i18n/i18n-react';
import SettingsApplication from './SettingsApplication'; import SettingsApplication from './SettingsApplication';
import SettingsCustomization from './SettingsCustomization'; import SettingsCustomization from './SettingsCustomization';
const Settings: FC = () => { const Settings: FC = () => {
useLayoutTitle('Settings'); const { LL } = useI18nContext();
const { routerTab } = useRouterTab(); const { routerTab } = useRouterTab();
useLayoutTitle(LL.SETTINGS());
return ( return (
<> <>
<RouterTabs value={routerTab}> <RouterTabs value={routerTab}>

View File

@@ -3,7 +3,7 @@ import { ValidateFieldsError } from 'async-validator';
import { useSnackbar } from 'notistack'; import { useSnackbar } from 'notistack';
import { Box, Button, Checkbox, MenuItem, Grid, Typography, Divider } from '@mui/material'; import { Box, Button, Checkbox, MenuItem, Grid, Typography, Divider, InputAdornment } from '@mui/material';
import SaveIcon from '@mui/icons-material/Save'; import SaveIcon from '@mui/icons-material/Save';
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
@@ -24,6 +24,8 @@ import { numberValue, extractErrorMessage, updateValue, useRest } from '../utils
import * as EMSESP from './api'; import * as EMSESP from './api';
import { Settings, BOARD_PROFILES } from './types'; import { Settings, BOARD_PROFILES } from './types';
import { useI18nContext } from '../i18n/i18n-react';
export function boardProfileSelectItems() { export function boardProfileSelectItems() {
return Object.keys(BOARD_PROFILES).map((code) => ( return Object.keys(BOARD_PROFILES).map((code) => (
<MenuItem key={code} value={code}> <MenuItem key={code} value={code}>
@@ -38,6 +40,8 @@ const SettingsApplication: FC = () => {
update: EMSESP.writeSettings update: EMSESP.writeSettings
}); });
const { LL } = useI18nContext();
const { enqueueSnackbar } = useSnackbar(); const { enqueueSnackbar } = useSnackbar();
const updateFormValue = updateValue(setData); const updateFormValue = updateValue(setData);
@@ -116,7 +120,7 @@ const SettingsApplication: FC = () => {
<Box color="warning.main"> <Box color="warning.main">
<Typography variant="body2"> <Typography variant="body2">
Select a pre-configured interface board profile from the list below or choose "Custom" to configure your own Select a pre-configured interface board profile from the list below or choose "Custom" to configure your own
hardware settings. hardware settings
</Typography> </Typography>
</Box> </Box>
<ValidatedTextField <ValidatedTextField
@@ -321,6 +325,26 @@ const SettingsApplication: FC = () => {
<Typography sx={{ pt: 2 }} variant="h6" color="primary"> <Typography sx={{ pt: 2 }} variant="h6" color="primary">
General Options General Options
</Typography> </Typography>
<Box
sx={{
'& .MuiTextField-root': { width: '25ch' }
}}
>
<ValidatedTextField
name="locale"
label="Language (for device entities)"
disabled={saving}
value={data.locale}
variant="outlined"
onChange={updateFormValue}
margin="normal"
size="small"
select
>
<MenuItem value="en">English</MenuItem>
<MenuItem value="de">Deutsch</MenuItem>
</ValidatedTextField>
</Box>
{data.led_gpio !== 0 && ( {data.led_gpio !== 0 && (
<BlockFormControlLabel <BlockFormControlLabel
control={<Checkbox checked={data.hide_led} onChange={updateFormValue} name="hide_led" />} control={<Checkbox checked={data.hide_led} onChange={updateFormValue} name="hide_led" />}
@@ -350,7 +374,7 @@ const SettingsApplication: FC = () => {
/> />
<BlockFormControlLabel <BlockFormControlLabel
control={<Checkbox checked={data.readonly_mode} onChange={updateFormValue} name="readonly_mode" />} control={<Checkbox checked={data.readonly_mode} onChange={updateFormValue} name="readonly_mode" />}
label="Enable Read only mode (blocks all outgoing EMS Tx write commands)" label="Enable read-only mode (blocks all outgoing EMS Tx Write commands)"
disabled={saving} disabled={saving}
/> />
<BlockFormControlLabel <BlockFormControlLabel
@@ -371,11 +395,14 @@ const SettingsApplication: FC = () => {
/> />
{data.shower_alert && ( {data.shower_alert && (
<> <>
<Grid item xs={2}> <Grid item xs={4}>
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="shower_alert_trigger" name="shower_alert_trigger"
label="Trigger Time (minutes)" label="Trigger Time"
InputProps={{
endAdornment: <InputAdornment position="end">minutes</InputAdornment>
}}
variant="outlined" variant="outlined"
value={data.shower_alert_trigger} value={data.shower_alert_trigger}
type="number" type="number"
@@ -383,11 +410,14 @@ const SettingsApplication: FC = () => {
disabled={!data.shower_timer} disabled={!data.shower_timer}
/> />
</Grid> </Grid>
<Grid item xs={2}> <Grid item xs={4}>
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="shower_alert_coldshot" name="shower_alert_coldshot"
label="Cold Shot Time (seconds)" label="Cold Shot Duration"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
variant="outlined" variant="outlined"
value={data.shower_alert_coldshot} value={data.shower_alert_coldshot}
type="number" type="number"
@@ -413,8 +443,8 @@ const SettingsApplication: FC = () => {
margin="normal" margin="normal"
select select
> >
<MenuItem value={1}>on/off</MenuItem> <MenuItem value={1}>{LL.ONOFF()}</MenuItem>
<MenuItem value={2}>ON/OFF</MenuItem> <MenuItem value={2}>{LL.ONOFF_CAP()}</MenuItem>
<MenuItem value={3}>true/false</MenuItem> <MenuItem value={3}>true/false</MenuItem>
<MenuItem value={5}>1/0</MenuItem> <MenuItem value={5}>1/0</MenuItem>
</ValidatedTextField> </ValidatedTextField>
@@ -430,8 +460,8 @@ const SettingsApplication: FC = () => {
margin="normal" margin="normal"
select select
> >
<MenuItem value={1}>"on"/"off"</MenuItem> <MenuItem value={1}>{LL.ONOFF()}</MenuItem>
<MenuItem value={2}>"ON"/"OFF"</MenuItem> <MenuItem value={2}>{LL.ONOFF_CAP()}</MenuItem>
<MenuItem value={3}>"true"/"false"</MenuItem> <MenuItem value={3}>"true"/"false"</MenuItem>
<MenuItem value={4}>true/false</MenuItem> <MenuItem value={4}>true/false</MenuItem>
<MenuItem value={5}>"1"/"0"</MenuItem> <MenuItem value={5}>"1"/"0"</MenuItem>
@@ -487,7 +517,7 @@ const SettingsApplication: FC = () => {
/> />
{data.syslog_enabled && ( {data.syslog_enabled && (
<Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start"> <Grid container spacing={1} direction="row" justifyContent="flex-start" alignItems="flex-start">
<Grid item xs={5}> <Grid item xs={4}>
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="syslog_host" name="syslog_host"
@@ -500,7 +530,7 @@ const SettingsApplication: FC = () => {
disabled={saving} disabled={saving}
/> />
</Grid> </Grid>
<Grid item xs={6}> <Grid item xs={4}>
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="syslog_port" name="syslog_port"
@@ -514,7 +544,7 @@ const SettingsApplication: FC = () => {
disabled={saving} disabled={saving}
/> />
</Grid> </Grid>
<Grid item xs={5}> <Grid item xs={4}>
<ValidatedTextField <ValidatedTextField
name="syslog_level" name="syslog_level"
label="Log Level" label="Log Level"
@@ -534,11 +564,14 @@ const SettingsApplication: FC = () => {
<MenuItem value={9}>ALL</MenuItem> <MenuItem value={9}>ALL</MenuItem>
</ValidatedTextField> </ValidatedTextField>
</Grid> </Grid>
<Grid item xs={6}> <Grid item xs={4}>
<ValidatedTextField <ValidatedTextField
fieldErrors={fieldErrors} fieldErrors={fieldErrors}
name="syslog_mark_interval" name="syslog_mark_interval"
label="Mark Interval (seconds, 0=off)" label="Mark Interval"
InputProps={{
endAdornment: <InputAdornment position="end">seconds</InputAdornment>
}}
fullWidth fullWidth
variant="outlined" variant="outlined"
value={data.syslog_mark_interval} value={data.syslog_mark_interval}

View File

@@ -294,7 +294,7 @@ const SettingsCustomization: FC = () => {
return ( return (
<> <>
<Box mb={2} color="warning.main"> <Box mb={2} color="warning.main">
<Typography variant="body2">Select a device and customize each of its entities using the options:</Typography> <Typography variant="body2">Select a device and customize the entities using the options:</Typography>
<Typography variant="body2"> <Typography variant="body2">
<OptionIcon type="favorite" isSet={true} /> <OptionIcon type="favorite" isSet={true} />
=mark as favorite&nbsp;&nbsp; =mark as favorite&nbsp;&nbsp;

View File

@@ -1,4 +1,5 @@
export interface Settings { export interface Settings {
locale: string;
tx_mode: number; tx_mode: number;
ems_bus_id: number; ems_bus_id: number;
syslog_enabled: boolean; syslog_enabled: boolean;

View File

@@ -3,10 +3,8 @@ import Schema from 'async-validator';
export const SIGN_IN_REQUEST_VALIDATOR = new Schema({ export const SIGN_IN_REQUEST_VALIDATOR = new Schema({
username: { username: {
required: true, required: true,
message: 'Please provide a username'
}, },
password: { password: {
required: true, required: true,
message: 'Please provide a password'
} }
}); });

View File

@@ -704,8 +704,13 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){
} else if(_pinfo.opcode == WS_PING){ } else if(_pinfo.opcode == WS_PING){
_queueControl(new AsyncWebSocketControl(WS_PONG, data, datalen)); _queueControl(new AsyncWebSocketControl(WS_PONG, data, datalen));
} else if(_pinfo.opcode == WS_PONG){ } else if(_pinfo.opcode == WS_PONG){
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
if(datalen != AWSC_PING_PAYLOAD_LEN || memcmp_P(data, AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN) != 0) if(datalen != AWSC_PING_PAYLOAD_LEN || memcmp_P(data, AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN) != 0)
_server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen);
#pragma GCC diagnostic pop
} else if(_pinfo.opcode < 8){//continuation or text/binary frame } else if(_pinfo.opcode < 8){//continuation or text/binary frame
_server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, data, datalen); _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, data, datalen);
} }

View File

@@ -143,6 +143,7 @@ sample code bearing this copyright.
#include "OneWire.h" #include "OneWire.h"
#include "util/OneWire_direct_gpio.h" #include "util/OneWire_direct_gpio.h"
#pragma GCC diagnostic ignored "-Wunused-variable"
void OneWire::begin(uint8_t pin) void OneWire::begin(uint8_t pin)
{ {
@@ -154,7 +155,6 @@ void OneWire::begin(uint8_t pin)
#endif #endif
} }
// Perform the onewire reset function. We will wait up to 250uS for // Perform the onewire reset function. We will wait up to 250uS for
// the bus to come high, if it doesn't then it is broken or shorted // the bus to come high, if it doesn't then it is broken or shorted
// and we return a 0; // and we return a 0;
@@ -578,3 +578,6 @@ uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc)
#endif #endif
#endif #endif
#pragma GCC diagnostic pop

View File

@@ -68,11 +68,28 @@ class FSPersistence {
JsonObject jsonObject = jsonDocument.to<JsonObject>(); JsonObject jsonObject = jsonDocument.to<JsonObject>();
_statefulService->read(jsonObject, _stateReader); _statefulService->read(jsonObject, _stateReader);
// make directories if required, for new IDF4.2 & LittleFS
String path(_filePath);
int index = 0;
while ((index = path.indexOf('/', index + 1)) != -1) {
String segment = path.substring(0, index);
if (!_fs->exists(segment)) {
_fs->mkdir(segment);
}
}
// serialize it to filesystem // serialize it to filesystem
File settingsFile = _fs->open(_filePath, "w"); File settingsFile = _fs->open(_filePath, "w");
// failed to open file, return false // failed to open file, return false
if (!settingsFile) { if (!settingsFile) {
#if defined(EMSESP_DEBUG)
#if defined(EMSESP_USE_SERIAL)
Serial.println();
Serial.printf("Cannot write to file system.");
Serial.println();
#endif
#endif
return false; return false;
} }

View File

@@ -26,6 +26,7 @@
class DummySettings { class DummySettings {
public: public:
String locale = "en";
uint8_t tx_mode = 1; uint8_t tx_mode = 1;
uint8_t ems_bus_id = 0x0B; uint8_t ems_bus_id = 0x0B;
bool syslog_enabled = false; bool syslog_enabled = false;

View File

@@ -253,7 +253,7 @@ const UPLOAD_FILE_ENDPOINT = REST_ENDPOINT_ROOT + 'uploadFile'
const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn' const SIGN_IN_ENDPOINT = REST_ENDPOINT_ROOT + 'signIn'
const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken' const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'
const system_status = { const system_status = {
emsesp_version: '3.4demo', emsesp_version: '3.5demo',
esp_platform: 'ESP32', esp_platform: 'ESP32',
max_alloc_heap: 113792, max_alloc_heap: 113792,
psram_size: 0, psram_size: 0,
@@ -306,7 +306,8 @@ const EMSESP_MASKED_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'maskedEntities'
const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations' const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations'
settings = { settings = {
tx_mode: 1, locale: 'en',
tx_mode: 4,
ems_bus_id: 11, ems_bus_id: 11,
syslog_enabled: false, syslog_enabled: false,
syslog_level: 3, syslog_level: 3,
@@ -344,29 +345,24 @@ const emsesp_devices = {
devices: [ devices: [
{ {
i: 1, i: 1,
d: 23,
p: 77,
s: 'Thermostat (RC20/Moduline 300)', s: 'Thermostat (RC20/Moduline 300)',
t: 'thermostat1', t: 'thermostat',
}, },
{ {
i: 2, i: 2,
d: 8,
p: 123,
s: 'Boiler (Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i)', s: 'Boiler (Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i)',
t: 'boiler', t: 'boiler',
}, },
{ {
i: 4, i: 4,
d: 16,
p: 165,
s: 'Thermostat (RC100/Moduline 1000/1010)', s: 'Thermostat (RC100/Moduline 1000/1010)',
t: 'thermostat2', t: 'thermostat',
}, },
], ],
} }
const emsesp_coredata = { const emsesp_coredata = {
connected: true,
// devices: [], // devices: [],
devices: [ devices: [
{ {
@@ -852,6 +848,7 @@ rest_server.post(UPLOAD_FILE_ENDPOINT, (req, res) => {
res.sendStatus(200) res.sendStatus(200)
}) })
rest_server.post(SIGN_IN_ENDPOINT, (req, res) => { rest_server.post(SIGN_IN_ENDPOINT, (req, res) => {
console.log('Signed in as ' + req.body.username)
res.json(signin) res.json(signin)
}) })
rest_server.get(GENERATE_TOKEN_ENDPOINT, (req, res) => { rest_server.get(GENERATE_TOKEN_ENDPOINT, (req, res) => {
@@ -1135,7 +1132,7 @@ rest_server.post(EMSESP_BOARDPROFILE_ENDPOINT, (req, res) => {
// EMS-ESP API specific // EMS-ESP API specific
const emsesp_info = { const emsesp_info = {
System: { System: {
version: '3.4.2', version: '3.5.0',
uptime: '001+06:40:34.018', uptime: '001+06:40:34.018',
'uptime (seconds)': 110434, 'uptime (seconds)': 110434,
freemem: 131, freemem: 131,

View File

@@ -8,16 +8,27 @@
; my_build_flags = -DEMSESP_DEBUG -DEMSESP_USE_SERIAL ; my_build_flags = -DEMSESP_DEBUG -DEMSESP_USE_SERIAL
; my_build_flags = -DEMSESP_DEBUG -DCORE_DEBUG_LEVEL=5 ; 5=verbose, 4=debug, 3=info ; my_build_flags = -DEMSESP_DEBUG -DCORE_DEBUG_LEVEL=5 ; 5=verbose, 4=debug, 3=info
[env:esp32] [env:esp32_4M]
; if using OTA enter your details below ; if using OTA enter your details below
; upload_protocol = espota ; upload_protocol = espota
; upload_flags = ; upload_flags =
; --port=8266 ; --port=8266
; --auth=ems-esp-neo ; --auth=ems-esp-neo
; upload_port = ems-esp.local ; upload_port = ems-esp.local
; for USB use
upload_port = /dev/ttyUSB*
; upload_port = COM3
extra_scripts = extra_scripts =
pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time ; pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time
scripts/rename_fw.py
[env:esp32_16M]
upload_port = /dev/ttyUSB*
; upload_port = COM3
extra_scripts =
; pre:scripts/build_interface.py ; comment out if you don't want to re-build the WebUI each time
scripts/rename_fw.py scripts/rename_fw.py
; pio run -e debug ; pio run -e debug

View File

@@ -2,7 +2,8 @@
; override any settings with your own local ones in pio_local.ini ; override any settings with your own local ones in pio_local.ini
[platformio] [platformio]
default_envs = esp32 default_envs = esp32_4M
; default_envs = esp32_16M
extra_configs = extra_configs =
factory_settings.ini factory_settings.ini
@@ -37,9 +38,11 @@ unbuild_flags =
[env] [env]
framework = arduino framework = arduino
monitor_speed = 115200 monitor_speed = 115200
monitor_raw = yes
upload_speed = 921600 upload_speed = 921600
build_type = release build_type = release
lib_ldf_mode = chain+ lib_ldf_mode = chain+
debug_build_flags = -Os # optimize for size
check_tool = cppcheck, clangtidy check_tool = cppcheck, clangtidy
check_severity = high, medium check_severity = high, medium
@@ -53,16 +56,28 @@ check_flags =
extra_scripts = scripts/rename_fw.py extra_scripts = scripts/rename_fw.py
board = esp32dev board = esp32dev
platform = espressif32 platform = espressif32
board_build.partitions = esp32_partition_app1984k_spiffs64k.csv board_build.partitions = esp32_partition_4M.csv
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
build_unflags = ${common.unbuild_flags} build_unflags = ${common.unbuild_flags}
[env:esp32] [env:esp32_4M]
extra_scripts = extra_scripts =
pre:scripts/build_interface.py pre:scripts/build_interface.py
scripts/rename_fw.py scripts/rename_fw.py
board = esp32dev board = esp32dev
platform = espressif32 platform = espressif32
board_build.partitions = esp32_partition_app1984k_spiffs64k.csv board_upload.flash_size = 4MB
board_build.partitions = esp32_partition_4M.csv
build_flags = ${common.build_flags}
build_unflags = ${common.unbuild_flags}
[env:esp32_16M]
extra_scripts =
pre:scripts/build_interface.py
scripts/rename_fw.py
board = esp32dev
platform = espressif32
board_upload.flash_size = 16MB
board_build.partitions = esp32_partition_16M.csv
build_flags = ${common.build_flags} build_flags = ${common.build_flags}
build_unflags = ${common.unbuild_flags} build_unflags = ${common.unbuild_flags}

View File

@@ -5,7 +5,6 @@ Import("env")
OUTPUT_DIR = "build{}".format(os.path.sep) OUTPUT_DIR = "build{}".format(os.path.sep)
def bin_copy(source, target, env): def bin_copy(source, target, env):
# get the build info # get the build info
@@ -21,20 +20,23 @@ def bin_copy(source, target, env):
app_version = bag.get('app_version') app_version = bag.get('app_version')
platform = "ESP32" platform = "ESP32"
flash_size = env["PIOENV"].split('_')[1]
# print(env.Dump()) # print(env.Dump())
# my_flags = env.ParseFlags(env['BUILD_FLAGS']) # my_flags = env.ParseFlags(env['BUILD_FLAGS'])
# defines = {k: v for (k, v) in my_flags.get("CPPDEFINES")} # defines = {k: v for (k, v) in my_flags.get("CPPDEFINES")}
# print(my_flags) # print(my_flags)
# print((my_flags.get("CPPDEFINES")) # print((my_flags.get("CPPDEFINES"))
# alternatively take platfrom from the pio target # alternatively take platform from the pio target
# platform = str(target[0]).split(os.path.sep)[2] # platform = str(target[0]).split(os.path.sep)[2]
print("app version: "+app_version) print("app version: "+app_version)
print("platform: "+platform) print("platform: "+platform)
print("flash size: "+flash_size)
# convert . to _ so Windows doesn't complain # convert . to _ so Windows doesn't complain
variant = "EMS-ESP-" + app_version.replace(".", "_") + "-" + platform variant = "EMS-ESP-" + app_version.replace(".", "_") + "-" + platform + "_" + flash_size
# check if output directories exist and create if necessary # check if output directories exist and create if necessary
if not os.path.isdir(OUTPUT_DIR): if not os.path.isdir(OUTPUT_DIR):
@@ -52,10 +54,9 @@ def bin_copy(source, target, env):
if os.path.isfile(f): if os.path.isfile(f):
os.remove(f) os.remove(f)
print("renaming file to "+bin_file) print("Renaming file to "+bin_file)
# copy firmware.bin to firmware/<variant>.bin # copy firmware.bin to firmware/<variant>.bin
shutil.copy(str(target[0]), bin_file) shutil.copy(str(target[0]), bin_file)
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_copy]) env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_copy])

0
scripts/run_sonar.sh Executable file → Normal file
View File

View File

@@ -1,7 +1,7 @@
sonar.organization=emsesp sonar.organization=emsesp
sonar.projectKey=emsesp_EMS-ESP32 sonar.projectKey=emsesp_EMS-ESP32
sonar.projectName=EMS-ESP32 sonar.projectName=EMS-ESP32
sonar.projectVersion=3.4 sonar.projectVersion=3.5.0
sonar.sources=./src sonar.sources=./src
sonar.cfamily.build-wrapper-output=build_wrapper_output_directory sonar.cfamily.build-wrapper-output=build_wrapper_output_directory
sonar.sourceEncoding=UTF-8 sonar.sourceEncoding=UTF-8

View File

@@ -459,7 +459,7 @@ bool AnalogSensor::get_value_info(JsonObject & output, const char * cmd, const i
output["gpio"] = sensor.gpio(); output["gpio"] = sensor.gpio();
output["name"] = sensor.name(); output["name"] = sensor.name();
output["type"] = F_(number); output["type"] = F_(number);
output["analog"] = FL_(enum_sensortype)[sensor.type()]; output["analog"] = FL_(list_sensortype)[sensor.type()];
output["uom"] = EMSdevice::uom_to_string(sensor.uom()); output["uom"] = EMSdevice::uom_to_string(sensor.uom());
output["offset"] = sensor.offset(); output["offset"] = sensor.offset();
output["factor"] = sensor.factor(); output["factor"] = sensor.factor();
@@ -497,7 +497,7 @@ bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject
JsonObject dataSensor = output.createNestedObject(sensor.name()); JsonObject dataSensor = output.createNestedObject(sensor.name());
dataSensor["gpio"] = sensor.gpio(); dataSensor["gpio"] = sensor.gpio();
dataSensor["type"] = F_(number); dataSensor["type"] = F_(number);
dataSensor["analog"] = FL_(enum_sensortype)[sensor.type()]; dataSensor["analog"] = FL_(list_sensortype)[sensor.type()];
if (sensor.type() == AnalogType::ADC) { if (sensor.type() == AnalogType::ADC) {
dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom()); dataSensor["uom"] = EMSdevice::uom_to_string(sensor.uom());
dataSensor["offset"] = sensor.offset(); dataSensor["offset"] = sensor.offset();

64
src/common.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EMSESP_COMMON_H
#define EMSESP_COMMON_H
// logging
#include <uuid/log.h>
using uuid::log::Level;
#define LOG_DEBUG(...) logger_.debug(__VA_ARGS__)
#define LOG_INFO(...) logger_.info(__VA_ARGS__)
#define LOG_TRACE(...) logger_.trace(__VA_ARGS__)
#define LOG_NOTICE(...) logger_.notice(__VA_ARGS__)
#define LOG_WARNING(...) logger_.warning(__VA_ARGS__)
#define LOG_ERROR(...) logger_.err(__VA_ARGS__)
// flash strings
using uuid::flash_string_vector;
using uuid::read_flash_string;
#ifdef FPSTR
#undef FPSTR
#endif
#define FJSON(x) x
// #define FJSON(x) F(x)
// clang-format off
#define MAKE_STR(string_name, string_literal) static constexpr const char * __str__##string_name = string_literal;
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F_(string_name) FPSTR(__pstr__##string_name)
#define MAKE_PSTR(string_name, string_literal) static const char __pstr__##string_name[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = string_literal;
#define MAKE_PSTR_WORD(string_name) MAKE_PSTR(string_name, #string_name)
#define FL_(list_name) (__pstr__L_##list_name)
#define MAKE_PSTR_LIST(list_name, ...) static const __FlashStringHelper * const __pstr__L_##list_name[] PROGMEM = {__VA_ARGS__, nullptr};
#define MAKE_PSTR_ENUM(enum_name, ...) static const __FlashStringHelper * const * __pstr__L_##enum_name[] PROGMEM = {__VA_ARGS__, nullptr};
// clang-format on
// load translations
#include "locale_translations.h"
#include "locale_common.h"
#endif

View File

@@ -225,6 +225,7 @@ void EMSESPShell::add_console_commands() {
flash_string_vector{F_(set)}, flash_string_vector{F_(set)},
[](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { [](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
EMSESP::webSettingsService.read([&](WebSettings & settings) { EMSESP::webSettingsService.read([&](WebSettings & settings) {
shell.printfln(F("Language: %s"), settings.locale.c_str());
shell.printfln(F_(tx_mode_fmt), settings.tx_mode); shell.printfln(F_(tx_mode_fmt), settings.tx_mode);
shell.printfln(F_(bus_id_fmt), settings.ems_bus_id); shell.printfln(F_(bus_id_fmt), settings.ems_bus_id);
shell.printfln(F_(board_profile_fmt), settings.board_profile.c_str()); shell.printfln(F_(board_profile_fmt), settings.board_profile.c_str());
@@ -280,11 +281,11 @@ void EMSESPShell::add_console_commands() {
// get raw/pretty // get raw/pretty
if (arguments[0] == read_flash_string(F_(raw))) { if (arguments[0] == read_flash_string(F_(raw))) {
EMSESP::watch(EMSESP::WATCH_RAW); // raw EMSESP::watch(EMSESP::WATCH_RAW); // raw
} else if (arguments[0] == read_flash_string(F_(on))) { } else if (arguments[0] == Helpers::translated_word(FL_(on))) {
EMSESP::watch(EMSESP::WATCH_ON); // on EMSESP::watch(EMSESP::WATCH_ON); // on
} else if (arguments[0] == read_flash_string(F_(off))) { } else if (arguments[0] == Helpers::translated_word(FL_(off))) {
EMSESP::watch(EMSESP::WATCH_OFF); // off EMSESP::watch(EMSESP::WATCH_OFF); // off
} else if (arguments[0] == read_flash_string(F_(unknown))) { } else if (arguments[0] == Helpers::translated_word(FL_(unknown))) {
EMSESP::watch(EMSESP::WATCH_UNKNOWN); // unknown EMSESP::watch(EMSESP::WATCH_UNKNOWN); // unknown
watch_id = WATCH_ID_NONE; watch_id = WATCH_ID_NONE;
} else { } else {

View File

@@ -26,36 +26,8 @@
#include "system.h" #include "system.h"
#include "mqtt.h" #include "mqtt.h"
using uuid::flash_string_vector;
using uuid::read_flash_string;
using uuid::console::Commands; using uuid::console::Commands;
using uuid::console::Shell; using uuid::console::Shell;
using uuid::log::Level;
#define LOG_DEBUG(...) logger_.debug(__VA_ARGS__)
#define LOG_INFO(...) logger_.info(__VA_ARGS__)
#define LOG_TRACE(...) logger_.trace(__VA_ARGS__)
#define LOG_NOTICE(...) logger_.notice(__VA_ARGS__)
#define LOG_WARNING(...) logger_.warning(__VA_ARGS__)
#define LOG_ERROR(...) logger_.err(__VA_ARGS__)
// clang-format off
// strings stored 32 bit aligned on ESP8266/ESP32
#define MAKE_STR(string_name, string_literal) static constexpr const char * __str__##string_name = string_literal;
#define MAKE_PSTR(string_name, string_literal) static const char __pstr__##string_name[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = string_literal;
#define MAKE_PSTR_WORD(string_name) MAKE_PSTR(string_name, #string_name)
#define F_(string_name) FPSTR(__pstr__##string_name)
#define FSTR_(string_name) __str__##string_name
#define MAKE_PSTR_LIST(list_name, ...) static const __FlashStringHelper * const __pstr__##list_name[] PROGMEM = {__VA_ARGS__, nullptr};
#define FL_(list_name) (__pstr__##list_name)
// clang-format on
// localizations
#include "locale_EN.h"
#ifdef LOCAL
#undef LOCAL
#endif
static constexpr uint32_t INVALID_PASSWORD_DELAY_MS = 2000; static constexpr uint32_t INVALID_PASSWORD_DELAY_MS = 2000;
@@ -64,19 +36,14 @@ namespace emsesp {
using LogLevel = ::uuid::log::Level; using LogLevel = ::uuid::log::Level;
using LogFacility = ::uuid::log::Facility; using LogFacility = ::uuid::log::Facility;
enum CommandFlags : uint8_t { #ifdef LOCAL
#undef LOCAL
USER = 0, #endif
ADMIN = (1 << 0), enum CommandFlags : uint8_t { USER = 0, ADMIN = (1 << 0), LOCAL = (1 << 1) };
LOCAL = (1 << 1)
};
enum ShellContext : uint8_t { enum ShellContext : uint8_t {
MAIN = 0, MAIN = 0,
SYSTEM, SYSTEM,
}; };
class EMSESPShell : virtual public uuid::console::Shell { class EMSESPShell : virtual public uuid::console::Shell {

View File

@@ -363,10 +363,10 @@ bool DallasSensor::command_info(const char * value, const int8_t id, JsonObject
JsonObject dataSensor = output.createNestedObject(sensor.name()); JsonObject dataSensor = output.createNestedObject(sensor.name());
dataSensor["id"] = sensor.id(); dataSensor["id"] = sensor.id();
if (Helpers::hasValue(sensor.temperature_c)) { if (Helpers::hasValue(sensor.temperature_c)) {
dataSensor["temp"] = Helpers::round2((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0); dataSensor["temp"] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
} }
} else if (Helpers::hasValue(sensor.temperature_c)) { } else if (Helpers::hasValue(sensor.temperature_c)) {
output[sensor.name()] = Helpers::round2((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0); output[sensor.name()] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
} }
} }
@@ -392,11 +392,11 @@ bool DallasSensor::get_value_info(JsonObject & output, const char * cmd, const i
output["id"] = sensor.id(); output["id"] = sensor.id();
output["name"] = sensor.name(); output["name"] = sensor.name();
if (Helpers::hasValue(sensor.temperature_c)) { if (Helpers::hasValue(sensor.temperature_c)) {
output["value"] = Helpers::round2((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0); output["value"] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
} }
output["type"] = F_(number); output["type"] = F_(number);
output["min"] = Helpers::round2(-55, 0, EMSESP::system_.fahrenheit() ? 2 : 0); output["min"] = Helpers::transformNumFloat(-55, 0, EMSESP::system_.fahrenheit() ? 2 : 0);
output["max"] = Helpers::round2(125, 0, EMSESP::system_.fahrenheit() ? 2 : 0); output["max"] = Helpers::transformNumFloat(125, 0, EMSESP::system_.fahrenheit() ? 2 : 0);
output["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES); output["uom"] = EMSdevice::uom_to_string(DeviceValueUOM::DEGREES);
output["writeable"] = false; output["writeable"] = false;
// if we're filtering on an attribute, go find it // if we're filtering on an attribute, go find it
@@ -472,10 +472,10 @@ void DallasSensor::publish_values(const bool force) {
JsonObject dataSensor = doc.createNestedObject(sensor.id()); JsonObject dataSensor = doc.createNestedObject(sensor.id());
dataSensor["name"] = sensor.name(); dataSensor["name"] = sensor.name();
if (has_value) { if (has_value) {
dataSensor["temp"] = Helpers::round2((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0); dataSensor["temp"] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
} }
} else if (has_value) { } else if (has_value) {
doc[sensor.name()] = Helpers::round2((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0); doc[sensor.name()] = Helpers::transformNumFloat((float)(sensor.temperature_c), 10, EMSESP::system_.fahrenheit() ? 2 : 0);
} }
// create the HA MQTT config // create the HA MQTT config

View File

@@ -15,11 +15,20 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef EMSESP_DEFAULT_SETTINGS_H #ifndef EMSESP_DEFAULT_SETTINGS_H
#define EMSESP_DEFAULT_SETTINGS_H #define EMSESP_DEFAULT_SETTINGS_H
// GENERAL SETTINGS // GENERAL SETTINGS
#ifndef EMSESP_STANDALONE
#define EMSESP_DEFAULT_LOCALE EMSESP_LOCALE_EN // English
#else
// this is for debugging different languages in standalone version
#define EMSESP_DEFAULT_LOCALE EMSESP_LOCALE_DE // German
// #define EMSESP_DEFAULT_LOCALE EMSESP_LOCALE_EN // English
#endif
#ifndef EMSESP_DEFAULT_TX_MODE #ifndef EMSESP_DEFAULT_TX_MODE
#define EMSESP_DEFAULT_TX_MODE 1 // EMS1.0 #define EMSESP_DEFAULT_TX_MODE 1 // EMS1.0
#endif #endif
@@ -199,18 +208,18 @@
// matches Web UI settings // matches Web UI settings
enum { enum {
BOOL_FORMAT_ONOFF_STR = 1, BOOL_FORMAT_ONOFF_STR = 1, // 1
BOOL_FORMAT_ONOFF_STR_CAP, BOOL_FORMAT_ONOFF_STR_CAP, // 2
BOOL_FORMAT_TRUEFALSE_STR, BOOL_FORMAT_TRUEFALSE_STR, // 3
BOOL_FORMAT_TRUEFALSE, BOOL_FORMAT_TRUEFALSE, // 4
BOOL_FORMAT_10_STR, BOOL_FORMAT_10_STR, // 5
BOOL_FORMAT_10 BOOL_FORMAT_10 // 6
}; };
enum { enum {
ENUM_FORMAT_VALUE = 1, ENUM_FORMAT_VALUE = 1, // 1
ENUM_FORMAT_INDEX // 2 ENUM_FORMAT_INDEX // 2
}; };

View File

@@ -27,6 +27,7 @@ uuid::log::Logger Boiler::logger_{F_(boiler), uuid::log::Facility::CONSOLE};
Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand) Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) { : EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
// alternative heatsource special messages // alternative heatsource special messages
if (device_id == EMSdevice::EMS_DEVICE_ID_AM200) { if (device_id == EMSdevice::EMS_DEVICE_ID_AM200) {
register_telegram_type(0x54D, F("AmTemperatures"), false, MAKE_PF_CB(process_amTempMessage)); register_telegram_type(0x54D, F("AmTemperatures"), false, MAKE_PF_CB(process_amTempMessage));
register_telegram_type(0x54E, F("AmStatus"), false, MAKE_PF_CB(process_amStatusMessage)); register_telegram_type(0x54E, F("AmStatus"), false, MAKE_PF_CB(process_amStatusMessage));
@@ -34,25 +35,43 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_telegram_type(0x550, F("AmExtra"), false, MAKE_PF_CB(process_amExtraMessage)); register_telegram_type(0x550, F("AmExtra"), false, MAKE_PF_CB(process_amExtraMessage));
register_telegram_type(0x54C, F("AmSettings"), true, MAKE_PF_CB(process_amSettingMessage)); // not broadcasted register_telegram_type(0x54C, F("AmSettings"), true, MAKE_PF_CB(process_amSettingMessage)); // not broadcasted
register_device_value(DeviceValueTAG::TAG_AHS, &curFlowTemp_, DeviceValueType::SHORT, FL_(div10), FL_(sysFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_AHS,
register_device_value(DeviceValueTAG::TAG_AHS, &retTemp_, DeviceValueType::SHORT, FL_(div10), FL_(sysRetTemp), DeviceValueUOM::DEGREES); &curFlowTemp_,
register_device_value(DeviceValueTAG::TAG_AHS, &aFlowTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aFlowTemp), DeviceValueUOM::DEGREES); DeviceValueType::SHORT,
register_device_value(DeviceValueTAG::TAG_AHS, &aRetTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aRetTemp), DeviceValueUOM::DEGREES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_AHS, &cylTopTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aCylTopTemp), DeviceValueUOM::DEGREES); FL_(sysFlowTemp),
register_device_value(DeviceValueTAG::TAG_AHS, &cylCenterTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aCylCenterTemp), DeviceValueUOM::DEGREES); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_AHS, &cylBottomTemp_, DeviceValueType::SHORT, FL_(div10), FL_(aCylBottomTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_AHS, &retTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysRetTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_AHS, &aFlowTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aFlowTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_AHS, &aRetTemp_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(aRetTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_AHS,
&cylTopTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(aCylTopTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_AHS,
&cylCenterTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(aCylCenterTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_AHS,
&cylBottomTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(aCylBottomTemp),
DeviceValueUOM::DEGREES);
// register_device_value(DeviceValueTAG::TAG_AHS, &valveByPass_, DeviceValueType::BOOL, nullptr, FL_(valveByPass), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_AHS, &valveByPass_, DeviceValueType::BOOL, nullptr, FL_(valveByPass), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_AHS, &valveBuffer_, DeviceValueType::UINT, nullptr, FL_(valveBuffer), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_AHS, &valveBuffer_, DeviceValueType::UINT, FL_(valveBuffer), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_AHS, &valveReturn_, DeviceValueType::UINT, nullptr, FL_(valveReturn), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_AHS, &valveReturn_, DeviceValueType::UINT, FL_(valveReturn), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_AHS, &aPumpMod_, DeviceValueType::UINT, nullptr, FL_(aPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_AHS, &aPumpMod_, DeviceValueType::UINT, FL_(aPumpMod), DeviceValueUOM::PERCENT);
// register_device_value(DeviceValueTAG::TAG_AHS, &heatSource_, DeviceValueType::BOOL, nullptr, FL_(heatSource), DeviceValueUOM::NONE); // register_device_value(DeviceValueTAG::TAG_AHS, &heatSource_, DeviceValueType::BOOL, nullptr, FL_(heatSource), DeviceValueUOM::NONE);
// Settings: // Settings:
register_device_value( register_device_value(
DeviceValueTAG::TAG_AHS, &vr2Config_, DeviceValueType::ENUM, FL_(enum_vr2Config), FL_(vr2Config), DeviceValueUOM::NONE, MAKE_CF_CB(set_vr2Config)); DeviceValueTAG::TAG_AHS, &vr2Config_, DeviceValueType::ENUM, FL_(enum_vr2Config), FL_(vr2Config), DeviceValueUOM::NONE, MAKE_CF_CB(set_vr2Config));
register_device_value( register_device_value(DeviceValueTAG::TAG_AHS, &ahsActivated_, DeviceValueType::BOOL, FL_(ahsActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_ahsActivated));
DeviceValueTAG::TAG_AHS, &ahsActivated_, DeviceValueType::BOOL, nullptr, FL_(ahsActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_ahsActivated)); register_device_value(DeviceValueTAG::TAG_AHS, &aPumpConfig_, DeviceValueType::BOOL, FL_(aPumpConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_aPumpConfig));
register_device_value(
DeviceValueTAG::TAG_AHS, &aPumpConfig_, DeviceValueType::BOOL, nullptr, FL_(aPumpConfig), DeviceValueUOM::NONE, MAKE_CF_CB(set_aPumpConfig));
register_device_value(DeviceValueTAG::TAG_AHS, register_device_value(DeviceValueTAG::TAG_AHS,
&aPumpSignal_, &aPumpSignal_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -60,35 +79,19 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
FL_(aPumpSignal), FL_(aPumpSignal),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_aPumpSignal)); MAKE_CF_CB(set_aPumpSignal));
register_device_value(DeviceValueTAG::TAG_AHS, &aPumpMin_, DeviceValueType::UINT, FL_(aPumpMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_aPumpMin), 12, 50);
register_device_value(DeviceValueTAG::TAG_AHS, &tempRise_, DeviceValueType::BOOL, FL_(tempRise), DeviceValueUOM::NONE, MAKE_CF_CB(set_tempRise));
register_device_value( register_device_value(
DeviceValueTAG::TAG_AHS, &aPumpMin_, DeviceValueType::UINT, nullptr, FL_(aPumpMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_aPumpMin), 12, 50); DeviceValueTAG::TAG_AHS, &setReturnTemp_, DeviceValueType::UINT, FL_(setReturnTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setReturnTemp), 40, 75);
register_device_value(DeviceValueTAG::TAG_AHS, &tempRise_, DeviceValueType::BOOL, nullptr, FL_(tempRise), DeviceValueUOM::NONE, MAKE_CF_CB(set_tempRise));
register_device_value(DeviceValueTAG::TAG_AHS,
&setReturnTemp_,
DeviceValueType::UINT,
nullptr,
FL_(setReturnTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_setReturnTemp),
40,
75);
register_device_value( register_device_value(
DeviceValueTAG::TAG_AHS, &mixRuntime_, DeviceValueType::USHORT, nullptr, FL_(mixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_mixRuntime), 0, 600); DeviceValueTAG::TAG_AHS, &mixRuntime_, DeviceValueType::USHORT, FL_(mixRuntime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_mixRuntime), 0, 600);
register_device_value(DeviceValueTAG::TAG_AHS, register_device_value(
&setFlowTemp_, DeviceValueTAG::TAG_AHS, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_setFlowTemp), 40, 75);
DeviceValueType::UINT,
nullptr,
FL_(setFlowTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_setFlowTemp),
40,
75);
register_device_value( register_device_value(
DeviceValueTAG::TAG_AHS, &bufBypass_, DeviceValueType::ENUM, FL_(enum_bufBypass), FL_(bufBypass), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufBypass)); DeviceValueTAG::TAG_AHS, &bufBypass_, DeviceValueType::ENUM, FL_(enum_bufBypass), FL_(bufBypass), DeviceValueUOM::NONE, MAKE_CF_CB(set_bufBypass));
register_device_value(DeviceValueTAG::TAG_AHS, register_device_value(DeviceValueTAG::TAG_AHS,
&bufMixRuntime_, &bufMixRuntime_,
DeviceValueType::USHORT, DeviceValueType::USHORT,
nullptr,
FL_(bufMixRuntime), FL_(bufMixRuntime),
DeviceValueUOM::SECONDS, DeviceValueUOM::SECONDS,
MAKE_CF_CB(set_bufMixRuntime), MAKE_CF_CB(set_bufMixRuntime),
@@ -100,33 +103,31 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
DeviceValueTAG::TAG_AHS, &blockMode_, DeviceValueType::ENUM, FL_(enum_blockMode), FL_(blockMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockMode)); DeviceValueTAG::TAG_AHS, &blockMode_, DeviceValueType::ENUM, FL_(enum_blockMode), FL_(blockMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockMode));
register_device_value( register_device_value(
DeviceValueTAG::TAG_AHS, &blockTerm_, DeviceValueType::ENUM, FL_(enum_blockTerm), FL_(blockTerm), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockTerm)); DeviceValueTAG::TAG_AHS, &blockTerm_, DeviceValueType::ENUM, FL_(enum_blockTerm), FL_(blockTerm), DeviceValueUOM::NONE, MAKE_CF_CB(set_blockTerm));
register_device_value(DeviceValueTAG::TAG_AHS, &blockHyst_, DeviceValueType::INT, FL_(blockHyst), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_blockHyst), 0, 50);
register_device_value( register_device_value(
DeviceValueTAG::TAG_AHS, &blockHyst_, DeviceValueType::INT, nullptr, FL_(blockHyst), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_blockHyst), 0, 50); DeviceValueTAG::TAG_AHS, &releaseWait_, DeviceValueType::UINT, FL_(releaseWait), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_releaseWait), 0, 240);
register_device_value(DeviceValueTAG::TAG_AHS,
&releaseWait_,
DeviceValueType::UINT,
nullptr,
FL_(releaseWait),
DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_releaseWait),
0,
240);
return; return;
} }
// cascaded heatingsources, only some values per individual heatsource (hs)
// cascaded heating sources, only some values per individual heatsource (hs)
if (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1) { if (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1) {
uint8_t hs = device_id - EMSdevice::EMS_DEVICE_ID_BOILER_1; // heating source id, count from 0 uint8_t hs = device_id - EMSdevice::EMS_DEVICE_ID_BOILER_1; // heating source id, count from 0
// Runtime of each heatingsource in 0x06DC, ff // Runtime of each heatingsource in 0x06DC, ff
register_telegram_type(0x6DC + hs, F("CascadeMessage"), false, MAKE_PF_CB(process_CascadeMessage)); register_telegram_type(0x6DC + hs, F("CascadeMessage"), false, MAKE_PF_CB(process_CascadeMessage));
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &burnWorkMin_, DeviceValueType::TIME, nullptr, FL_(burnWorkMin), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_HS1 + hs, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES);
// selBurnpower in D2 and E4 // selBurnpower in D2 and E4
// register_telegram_type(0xD2, F("CascadePowerMessage"), false, MAKE_PF_CB(process_CascadePowerMessage)); // register_telegram_type(0xD2, F("CascadePowerMessage"), false, MAKE_PF_CB(process_CascadePowerMessage));
// individual Flowtemps and powervalues for each heatingsource in E4 // individual Flowtemps and powervalues for each heatingsource in E4
register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, MAKE_PF_CB(process_UBAMonitorFastPlus)); register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, MAKE_PF_CB(process_UBAMonitorFastPlus));
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selFlowTemp_, DeviceValueType::UINT, nullptr, FL_(selFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT, nullptr, FL_(selBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_HS1 + hs, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curFlowTemp_, DeviceValueType::USHORT, FL_(div10), FL_(curFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_HS1 + hs,
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curBurnPow_, DeviceValueType::UINT, nullptr, FL_(curBurnPow), DeviceValueUOM::PERCENT); &curFlowTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(curFlowTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_HS1 + hs, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT);
return; return;
} }
@@ -142,15 +143,18 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_telegram_type(0x14, F("UBATotalUptime"), true, MAKE_PF_CB(process_UBATotalUptime)); 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(0x15, F("UBAMaintenanceData"), false, MAKE_PF_CB(process_UBAMaintenanceData));
register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, MAKE_PF_CB(process_UBAMaintenanceStatus)); register_telegram_type(0x1C, F("UBAMaintenanceStatus"), false, MAKE_PF_CB(process_UBAMaintenanceStatus));
// EMS1.0 and maybe EMS+? // EMS1.0 and maybe EMS+?
register_telegram_type(0x18, F("UBAMonitorFast"), false, MAKE_PF_CB(process_UBAMonitorFast)); register_telegram_type(0x18, F("UBAMonitorFast"), false, MAKE_PF_CB(process_UBAMonitorFast));
register_telegram_type(0x19, F("UBAMonitorSlow"), false, MAKE_PF_CB(process_UBAMonitorSlow)); register_telegram_type(0x19, F("UBAMonitorSlow"), false, MAKE_PF_CB(process_UBAMonitorSlow));
register_telegram_type(0x1A, F("UBASetPoints"), false, MAKE_PF_CB(process_UBASetPoints)); register_telegram_type(0x1A, F("UBASetPoints"), false, MAKE_PF_CB(process_UBASetPoints));
register_telegram_type(0x35, F("UBAFlags"), false, MAKE_PF_CB(process_UBAFlags)); register_telegram_type(0x35, F("UBAFlags"), false, MAKE_PF_CB(process_UBAFlags));
// only EMS 1.0 // only EMS 1.0
register_telegram_type(0x16, F("UBAParameters"), true, MAKE_PF_CB(process_UBAParameters)); 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(0x33, F("UBAParameterWW"), true, MAKE_PF_CB(process_UBAParameterWW));
register_telegram_type(0x34, F("UBAMonitorWW"), false, MAKE_PF_CB(process_UBAMonitorWW)); register_telegram_type(0x34, F("UBAMonitorWW"), false, MAKE_PF_CB(process_UBAMonitorWW));
// not ems1.0, but HT3 // not ems1.0, but HT3
if (model() != EMSdevice::EMS_DEVICE_FLAG_EMS) { if (model() != EMSdevice::EMS_DEVICE_FLAG_EMS) {
register_telegram_type(0x26, F("UBASettingsWW"), true, MAKE_PF_CB(process_UBASettingsWW)); register_telegram_type(0x26, F("UBASettingsWW"), true, MAKE_PF_CB(process_UBASettingsWW));
@@ -185,93 +189,100 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_telegram_type(0xBB, F("HybridHp"), true, MAKE_PF_CB(process_HybridHp)); register_telegram_type(0xBB, F("HybridHp"), true, MAKE_PF_CB(process_HybridHp));
} }
*/ */
// reset is a command uses a dummy variable which is always zero, shown as blank, but provides command enum options // reset is a command uses a dummy variable which is always zero, shown as blank, but provides command enum options
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &reset_, DeviceValueType::CMD, FL_(enum_reset), FL_(reset), DeviceValueUOM::NONE, MAKE_CF_CB(set_reset)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &reset_, DeviceValueType::CMD, FL_(enum_reset), FL_(reset), DeviceValueUOM::NONE, MAKE_CF_CB(set_reset));
has_update(reset_, 0); has_update(reset_, 0);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActive_, DeviceValueType::BOOL, nullptr, FL_(heatingActive), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingActive_, DeviceValueType::BOOL, FL_(heatingActive), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tapwaterActive_, DeviceValueType::BOOL, nullptr, FL_(tapwaterActive), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tapwaterActive_, DeviceValueType::BOOL, FL_(tapwaterActive), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &selFlowTemp_, DeviceValueType::UINT, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp));
register_device_value( register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &selFlowTemp_, DeviceValueType::UINT, nullptr, FL_(selFlowTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flow_temp)); DeviceValueTAG::TAG_DEVICE_DATA, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_burn_power), 0, 254);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT, FL_(heatingPumpMod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump2Mod_, DeviceValueType::UINT, FL_(heatingPump2Mod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&selBurnPow_, &outdoorTemp_,
DeviceValueType::UINT, DeviceValueType::SHORT,
nullptr, DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(selBurnPow), FL_(outdoorTemp),
DeviceValueUOM::PERCENT, DeviceValueUOM::DEGREES);
MAKE_CF_CB(set_burn_power), register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
0, &curFlowTemp_,
254); DeviceValueType::USHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPumpMod_, DeviceValueType::UINT, nullptr, FL_(heatingPumpMod), DeviceValueUOM::PERCENT); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump2Mod_, DeviceValueType::UINT, nullptr, FL_(heatingPump2Mod), DeviceValueUOM::PERCENT); FL_(curFlowTemp),
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outdoorTemp_, DeviceValueType::SHORT, FL_(div10), FL_(outdoorTemp), DeviceValueUOM::DEGREES); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curFlowTemp_, DeviceValueType::USHORT, FL_(div10), FL_(curFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(retTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retTemp_, DeviceValueType::USHORT, FL_(div10), FL_(retTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &switchTemp_, DeviceValueType::USHORT, FL_(div10), FL_(switchTemp), DeviceValueUOM::DEGREES); &switchTemp_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &sysPress_, DeviceValueType::UINT, FL_(div10), FL_(sysPress), DeviceValueUOM::BAR); DeviceValueType::USHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &boilTemp_, DeviceValueType::USHORT, FL_(div10), FL_(boilTemp), DeviceValueUOM::DEGREES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &exhaustTemp_, DeviceValueType::USHORT, FL_(div10), FL_(exhaustTemp), DeviceValueUOM::DEGREES); FL_(switchTemp),
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas_, DeviceValueType::BOOL, nullptr, FL_(burnGas), DeviceValueUOM::NONE); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas2_, DeviceValueType::BOOL, nullptr, FL_(burnGas2), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &sysPress_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(sysPress), DeviceValueUOM::BAR);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flameCurr_, DeviceValueType::USHORT, FL_(div10), FL_(flameCurr), DeviceValueUOM::UA); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump_, DeviceValueType::BOOL, nullptr, FL_(heatingPump), DeviceValueUOM::NONE); &boilTemp_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fanWork_, DeviceValueType::BOOL, nullptr, FL_(fanWork), DeviceValueUOM::NONE); DeviceValueType::USHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ignWork_, DeviceValueType::BOOL, nullptr, FL_(ignWork), DeviceValueUOM::NONE); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &oilPreHeat_, DeviceValueType::BOOL, nullptr, FL_(oilPreHeat), DeviceValueUOM::NONE); FL_(boilTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&exhaustTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(exhaustTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas_, DeviceValueType::BOOL, FL_(burnGas), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas2_, DeviceValueType::BOOL, FL_(burnGas2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flameCurr_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flameCurr), DeviceValueUOM::UA);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump_, DeviceValueType::BOOL, FL_(heatingPump), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fanWork_, DeviceValueType::BOOL, FL_(fanWork), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ignWork_, DeviceValueType::BOOL, FL_(ignWork), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &oilPreHeat_, DeviceValueType::BOOL, FL_(oilPreHeat), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatingActivated_, &heatingActivated_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(heatingActivated), FL_(heatingActivated),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_heating_activated)); MAKE_CF_CB(set_heating_activated));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatingTemp_, &heatingTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(heatingTemp), FL_(heatingTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_heating_temp)); MAKE_CF_CB(set_heating_temp));
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMax_, DeviceValueType::UINT, FL_(pumpModMax), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_pump));
DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMax_, DeviceValueType::UINT, nullptr, FL_(pumpModMax), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_pump)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMin_, DeviceValueType::UINT, FL_(pumpModMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_pump));
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpDelay_, DeviceValueType::UINT, FL_(pumpDelay), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_pump_delay));
DeviceValueTAG::TAG_DEVICE_DATA, &pumpModMin_, DeviceValueType::UINT, nullptr, FL_(pumpModMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_pump));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &pumpDelay_, DeviceValueType::UINT, nullptr, FL_(pumpDelay), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_pump_delay));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&burnMinPeriod_, &burnMinPeriod_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(burnMinPeriod), FL_(burnMinPeriod),
DeviceValueUOM::MINUTES, DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_burn_period)); MAKE_CF_CB(set_burn_period));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &burnMinPower_, DeviceValueType::UINT, nullptr, FL_(burnMinPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_power));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&burnMaxPower_, &burnMinPower_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr, FL_(burnMinPower),
FL_(burnMaxPower),
DeviceValueUOM::PERCENT, DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_max_power), MAKE_CF_CB(set_min_power));
0,
254);
register_device_value( register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT, nullptr, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on)); DeviceValueTAG::TAG_DEVICE_DATA, &burnMaxPower_, DeviceValueType::UINT, FL_(burnMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_power), 0, 254);
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on));
DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT, nullptr, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, nullptr, FL_(setFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, nullptr, FL_(setBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT, nullptr, FL_(curBurnPow), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnStarts_, DeviceValueType::ULONG, nullptr, FL_(burnStarts), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnStarts_, DeviceValueType::ULONG, FL_(burnStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnWorkMin_, DeviceValueType::TIME, nullptr, FL_(burnWorkMin), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnWorkMin_, DeviceValueType::TIME, FL_(burnWorkMin), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burn2WorkMin_, DeviceValueType::TIME, nullptr, FL_(burn2WorkMin), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burn2WorkMin_, DeviceValueType::TIME, FL_(burn2WorkMin), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatWorkMin_, DeviceValueType::TIME, nullptr, FL_(heatWorkMin), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatWorkMin_, DeviceValueType::TIME, FL_(heatWorkMin), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &UBAuptime_, DeviceValueType::TIME, nullptr, FL_(UBAuptime), DeviceValueUOM::MINUTES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &UBAuptime_, DeviceValueType::TIME, FL_(UBAuptime), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, nullptr, FL_(lastCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &serviceCode_, DeviceValueType::STRING, nullptr, FL_(serviceCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &serviceCode_, DeviceValueType::STRING, FL_(serviceCode), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &serviceCodeNumber_, DeviceValueType::USHORT, nullptr, FL_(serviceCodeNumber), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &serviceCodeNumber_, DeviceValueType::USHORT, FL_(serviceCodeNumber), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maintenanceMessage_, DeviceValueType::STRING, nullptr, FL_(maintenanceMessage), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &maintenanceMessage_, DeviceValueType::STRING, FL_(maintenanceMessage), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&maintenanceType_, &maintenanceType_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -282,7 +293,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&maintenanceTime_, &maintenanceTime_,
DeviceValueType::USHORT, DeviceValueType::USHORT,
nullptr,
FL_(maintenanceTime), FL_(maintenanceTime),
DeviceValueUOM::HOURS, DeviceValueUOM::HOURS,
MAKE_CF_CB(set_maintenancetime)); MAKE_CF_CB(set_maintenancetime));
@@ -296,14 +306,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&emergencyOps_, &emergencyOps_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(emergencyOps), FL_(emergencyOps),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_emergency_ops)); MAKE_CF_CB(set_emergency_ops));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&emergencyTemp_, &emergencyTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(emergencyTemp), FL_(emergencyTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_emergency_temp), MAKE_CF_CB(set_emergency_temp),
@@ -336,7 +344,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&energyCostRatio_, &energyCostRatio_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(energyCostRatio), FL_(energyCostRatio),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_energyCostRatio), MAKE_CF_CB(set_energyCostRatio),
@@ -345,7 +353,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&fossileFactor_, &fossileFactor_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(fossileFactor), FL_(fossileFactor),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_fossileFactor), MAKE_CF_CB(set_fossileFactor),
@@ -354,7 +362,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&electricFactor_, &electricFactor_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(electricFactor), FL_(electricFactor),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_electricFactor), MAKE_CF_CB(set_electricFactor),
@@ -382,81 +390,110 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
*/ */
// heatpump info // heatpump info
if (model() == EMS_DEVICE_FLAG_HEATPUMP) { if (model() == EMS_DEVICE_FLAG_HEATPUMP) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeControl_, DeviceValueType::TIME, FL_(div60), FL_(upTimeControl), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeCompHeating_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompHeating), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeCompCooling_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompCooling), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeCompWw_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompWw), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &upTimeCompPool_, DeviceValueType::TIME, FL_(div60), FL_(upTimeCompPool), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &totalCompStarts_, DeviceValueType::ULONG, nullptr, FL_(totalCompStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingStarts_, DeviceValueType::ULONG, nullptr, FL_(heatingStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &coolingStarts_, DeviceValueType::ULONG, nullptr, FL_(coolingStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStarts2_, DeviceValueType::ULONG, nullptr, FL_(wwStarts2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolStarts_, DeviceValueType::ULONG, nullptr, FL_(poolStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsTotal), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompTotal), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompHeating_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompHeating), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompWw_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompWw), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompCooling), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompPool_, DeviceValueType::ULONG, nullptr, FL_(nrgConsCompPool), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&auxElecHeatNrgConsTotal_, &upTimeControl_,
DeviceValueType::ULONG, DeviceValueType::TIME,
nullptr, DeviceValueNumOp::DV_NUMOP_DIV60,
FL_(auxElecHeatNrgConsTotal), FL_(upTimeControl),
DeviceValueUOM::KWH); DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&upTimeCompHeating_,
DeviceValueType::TIME,
DeviceValueNumOp::DV_NUMOP_DIV60,
FL_(upTimeCompHeating),
DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&upTimeCompCooling_,
DeviceValueType::TIME,
DeviceValueNumOp::DV_NUMOP_DIV60,
FL_(upTimeCompCooling),
DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&upTimeCompWw_,
DeviceValueType::TIME,
DeviceValueNumOp::DV_NUMOP_DIV60,
FL_(upTimeCompWw),
DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&upTimeCompPool_,
DeviceValueType::TIME,
DeviceValueNumOp::DV_NUMOP_DIV60,
FL_(upTimeCompPool),
DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &totalCompStarts_, DeviceValueType::ULONG, FL_(totalCompStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingStarts_, DeviceValueType::ULONG, FL_(heatingStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &coolingStarts_, DeviceValueType::ULONG, FL_(coolingStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStarts2_, DeviceValueType::ULONG, FL_(wwStarts2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolStarts_, DeviceValueType::ULONG, FL_(poolStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsTotal_, DeviceValueType::ULONG, FL_(nrgConsTotal), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompTotal_, DeviceValueType::ULONG, FL_(nrgConsCompTotal), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompHeating_, DeviceValueType::ULONG, FL_(nrgConsCompHeating), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompWw_, DeviceValueType::ULONG, FL_(nrgConsCompWw), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompCooling_, DeviceValueType::ULONG, FL_(nrgConsCompCooling), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgConsCompPool_, DeviceValueType::ULONG, FL_(nrgConsCompPool), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsTotal_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsTotal), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&auxElecHeatNrgConsHeating_, &auxElecHeatNrgConsHeating_,
DeviceValueType::ULONG, DeviceValueType::ULONG,
nullptr,
FL_(auxElecHeatNrgConsHeating), FL_(auxElecHeatNrgConsHeating),
DeviceValueUOM::KWH); DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH);
&auxElecHeatNrgConsWW_, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsPool_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsPool), DeviceValueUOM::KWH);
DeviceValueType::ULONG, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, FL_(nrgSuppTotal), DeviceValueUOM::KWH);
nullptr, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, FL_(nrgSuppHeating), DeviceValueUOM::KWH);
FL_(auxElecHeatNrgConsWW), register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH);
DeviceValueUOM::KWH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, FL_(nrgSuppCooling), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::ULONG, FL_(nrgSuppPool), DeviceValueUOM::KWH);
&auxElecHeatNrgConsPool_, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW);
DeviceValueType::ULONG, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompOn_, DeviceValueType::BOOL, FL_(hpCompOn), DeviceValueUOM::NONE);
nullptr,
FL_(auxElecHeatNrgConsPool),
DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppTotal), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppHeating), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppWw_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppWw), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppCooling), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::ULONG, nullptr, FL_(nrgSuppPool), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, FL_(div10), FL_(hpPower), DeviceValueUOM::KW);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompOn_, DeviceValueType::BOOL, nullptr, FL_(hpCompOn), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpActivity_, DeviceValueType::ENUM, FL_(enum_hpactivity), FL_(hpActivity), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, nullptr, FL_(hpHeatingOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHeatingOn_, DeviceValueType::BOOL, FL_(hpHeatingOn), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCoolingOn_, DeviceValueType::BOOL, nullptr, FL_(hpCoolingOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCoolingOn_, DeviceValueType::BOOL, FL_(hpCoolingOn), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpWwOn_, DeviceValueType::BOOL, nullptr, FL_(hpWwOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPoolOn_, DeviceValueType::BOOL, nullptr, FL_(hpPoolOn), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPoolOn_, DeviceValueType::BOOL, FL_(hpPoolOn), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, nullptr, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrinePumpSpd_, DeviceValueType::UINT, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSwitchValve_, DeviceValueType::BOOL, nullptr, FL_(hpSwitchValve), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSwitchValve_, DeviceValueType::BOOL, FL_(hpSwitchValve), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompSpd_, DeviceValueType::UINT, nullptr, FL_(hpCompSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCompSpd_, DeviceValueType::UINT, FL_(hpCompSpd), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCircSpd_, DeviceValueType::UINT, nullptr, FL_(hpCircSpd), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpCircSpd_, DeviceValueType::UINT, FL_(hpCircSpd), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrineIn_, DeviceValueType::SHORT, FL_(div10), FL_(hpBrineIn), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpBrineOut_, DeviceValueType::SHORT, FL_(div10), FL_(hpBrineOut), DeviceValueUOM::DEGREES); &hpBrineIn_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSuctionGas_, DeviceValueType::SHORT, FL_(div10), FL_(hpSuctionGas), DeviceValueUOM::DEGREES); DeviceValueType::SHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpHotGas_, DeviceValueType::SHORT, FL_(div10), FL_(hpHotGas), DeviceValueUOM::DEGREES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc0_, DeviceValueType::SHORT, FL_(div10), FL_(hpTc0), DeviceValueUOM::DEGREES); FL_(hpBrineIn),
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc1_, DeviceValueType::SHORT, FL_(div10), FL_(hpTc1), DeviceValueUOM::DEGREES); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc3_, DeviceValueType::SHORT, FL_(div10), FL_(hpTc3), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr3_, DeviceValueType::SHORT, FL_(div10), FL_(hpTr3), DeviceValueUOM::DEGREES); &hpBrineOut_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr4_, DeviceValueType::SHORT, FL_(div10), FL_(hpTr4), DeviceValueUOM::DEGREES); DeviceValueType::SHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr5_, DeviceValueType::SHORT, FL_(div10), FL_(hpTr5), DeviceValueUOM::DEGREES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr6_, DeviceValueType::SHORT, FL_(div10), FL_(hpTr6), DeviceValueUOM::DEGREES); FL_(hpBrineOut),
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr7_, DeviceValueType::SHORT, FL_(div10), FL_(hpTr7), DeviceValueUOM::DEGREES); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTl2_, DeviceValueType::SHORT, FL_(div10), FL_(hpTl2), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPl1_, DeviceValueType::SHORT, FL_(div10), FL_(hpPl1), DeviceValueUOM::DEGREES); &hpSuctionGas_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPh1_, DeviceValueType::SHORT, FL_(div10), FL_(hpPh1), DeviceValueUOM::DEGREES); DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(hpSuctionGas),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&hpHotGas_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(hpHotGas),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc0_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc0), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc1), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTc3_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTc3), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr3_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr3), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr4_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr4), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr5_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr5), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr6_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr6), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTr7_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTr7), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpTl2_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpTl2), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPl1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPl1), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPh1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPh1), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&poolSetTemp_, &poolSetTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div2), DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(poolSetTemp), FL_(poolSetTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_pool_temp)); MAKE_CF_CB(set_pool_temp));
@@ -466,25 +503,21 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwTapActivated_, &wwTapActivated_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwtapactivated), FL_(wwtapactivated),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_tapwarmwater_activated)); MAKE_CF_CB(set_tapwarmwater_activated));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES);
register_device_value( register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp));
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTemp_, DeviceValueType::UINT, nullptr, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_temp));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwSelTempLow_, &wwSelTempLow_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwSelTempLow), FL_(wwSelTempLow),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_ww_temp_low)); MAKE_CF_CB(set_ww_temp_low));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTempOff_, DeviceValueType::UINT, nullptr, FL_(wwSelTempOff), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSelTempOff_, DeviceValueType::UINT, FL_(wwSelTempOff), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwSelTempSingle_, &wwSelTempSingle_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwSelTempSingle), FL_(wwSelTempSingle),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_ww_temp_single)); MAKE_CF_CB(set_ww_temp_single));
@@ -506,7 +539,6 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwFlowTempOffset_, &wwFlowTempOffset_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwFlowTempOffset), FL_(wwFlowTempOffset),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_ww_flowTempOffset), MAKE_CF_CB(set_ww_flowTempOffset),
@@ -515,44 +547,30 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwChargeOptimization_, &wwChargeOptimization_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwChargeOptimization), FL_(wwChargeOptimization),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_ww_chargeOptimization)); MAKE_CF_CB(set_ww_chargeOptimization));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(
&wwMaxPower_, DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254);
DeviceValueType::UINT, register_device_value(
nullptr, DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 70);
FL_(wwMaxPower),
DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_ww_maxpower),
0,
254);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwMaxTemp_,
DeviceValueType::UINT,
nullptr,
FL_(wwMaxTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_ww_maxtemp),
0,
70);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwCircPump_, &wwCircPump_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwCircPump), FL_(wwCircPump),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_ww_circulation_pump)); MAKE_CF_CB(set_ww_circulation_pump));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwChargeType_, DeviceValueType::ENUM, FL_(enum_charge), FL_(wwChargeType), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwChargeType_, DeviceValueType::ENUM, FL_(enum_charge), FL_(wwChargeType), DeviceValueUOM::NONE);
register_device_value( register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_on));
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwHystOn_, DeviceValueType::INT, nullptr, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_on)); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
register_device_value( &wwHystOff_,
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwHystOff_, DeviceValueType::INT, nullptr, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_ww_hyst_off)); DeviceValueType::INT,
FL_(wwHystOff),
DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_ww_hyst_off));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwDisinfectionTemp_, &wwDisinfectionTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectionTemp), FL_(wwDisinfectionTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_ww_disinfect_temp)); MAKE_CF_CB(set_ww_disinfect_temp));
@@ -563,45 +581,76 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
FL_(wwCircMode), FL_(wwCircMode),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_ww_circulation_mode)); MAKE_CF_CB(set_ww_circulation_mode));
register_device_value( register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation));
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCirc_, DeviceValueType::BOOL, nullptr, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_circulation)); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCurTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp), DeviceValueUOM::DEGREES); &wwCurTemp_,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCurTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp2), DeviceValueUOM::DEGREES); DeviceValueType::USHORT,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCurFlow_, DeviceValueType::UINT, FL_(div10), FL_(wwCurFlow), DeviceValueUOM::LMIN); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStorageTemp1_, DeviceValueType::USHORT, FL_(div10), FL_(wwStorageTemp1), DeviceValueUOM::DEGREES); FL_(wwCurTemp),
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStorageTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wwStorageTemp2), DeviceValueUOM::DEGREES); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwCurTemp2_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwCurTemp2),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwCurFlow_,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwCurFlow),
DeviceValueUOM::LMIN);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwStorageTemp1_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwStorageTemp1),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwStorageTemp2_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwStorageTemp2),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwActivated_, &wwActivated_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwActivated), FL_(wwActivated),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_ww_activated)); MAKE_CF_CB(set_ww_activated));
register_device_value( register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwOneTime_, DeviceValueType::BOOL, FL_(wwOneTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_onetime));
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwOneTime_, DeviceValueType::BOOL, nullptr, FL_(wwOneTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_ww_onetime));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwDisinfect_, &wwDisinfect_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwDisinfecting), FL_(wwDisinfecting),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_ww_disinfect)); MAKE_CF_CB(set_ww_disinfect));
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCharging_, DeviceValueType::BOOL, nullptr, FL_(wwCharging), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCharging_, DeviceValueType::BOOL, FL_(wwCharging), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwRecharging_, DeviceValueType::BOOL, nullptr, FL_(wwRecharging), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwRecharging_, DeviceValueType::BOOL, FL_(wwRecharging), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwTempOK_, DeviceValueType::BOOL, nullptr, FL_(wwTempOK), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwTempOK_, DeviceValueType::BOOL, FL_(wwTempOK), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwActive_, DeviceValueType::BOOL, nullptr, FL_(wwActive), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwActive_, DeviceValueType::BOOL, FL_(wwActive), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &ww3wayValve_, DeviceValueType::BOOL, nullptr, FL_(ww3wayValve), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &ww3wayValve_, DeviceValueType::BOOL, FL_(ww3wayValve), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSetPumpPower_, DeviceValueType::UINT, nullptr, FL_(wwSetPumpPower), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwSetPumpPower_, DeviceValueType::UINT, FL_(wwSetPumpPower), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMixerTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wwMixerTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwCylMiddleTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wwCylMiddleTemp), DeviceValueUOM::DEGREES); &wwMixerTemp_,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStarts_, DeviceValueType::ULONG, nullptr, FL_(wwStarts), DeviceValueUOM::NONE); DeviceValueType::USHORT,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwWorkM_, DeviceValueType::TIME, nullptr, FL_(wwWorkM), DeviceValueUOM::MINUTES); DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwMixerTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwCylMiddleTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwCylMiddleTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwStarts_, DeviceValueType::ULONG, FL_(wwStarts), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &wwWorkM_, DeviceValueType::TIME, FL_(wwWorkM), DeviceValueUOM::MINUTES);
// fetch some initial data // fetch some initial data
EMSESP::send_read_request(0x10, device_id); // read last errorcode on start (only published on errors) EMSESP::send_read_request(0x10, device_id); // read last errorcode on start (only published on errors)
EMSESP::send_read_request(0x11, device_id); // read last errorcode on start (only published on errors) EMSESP::send_read_request(0x11, device_id); // read last errorcode on start (only published on errors)
EMSESP::send_read_request(0x15, device_id); // read maintenace data on start (only published on change) EMSESP::send_read_request(0x15, device_id); // read maintenance data on start (only published on change)
EMSESP::send_read_request(0x1C, device_id); // read maintenace status on start (only published on change) EMSESP::send_read_request(0x1C, device_id); // read maintenance status on start (only published on change)
EMSESP::send_read_request(0xC2, device_id); // read last errorcode on start (only published on errors) EMSESP::send_read_request(0xC2, device_id); // read last errorcode on start (only published on errors)
} }
@@ -1286,9 +1335,6 @@ void Boiler::process_amCommandMessage(std::shared_ptr<const Telegram> telegram)
// pos 6: boiler blocking 0-off, 1-on // pos 6: boiler blocking 0-off, 1-on
} }
// 0x0550 AM200 broadcasted message, all 27 bytes unkown
// Rx: 60 00 FF 00 04 50 00 FF 00 FF FF 00 0D 00 01 00 00 00 00 01 03 01 00 03 00 2D 19 C8 02 94 00 4A
// Rx: 60 00 FF 19 04 50 00 FF FF 39
void Boiler::process_amExtraMessage(std::shared_ptr<const Telegram> telegram) { void Boiler::process_amExtraMessage(std::shared_ptr<const Telegram> telegram) {
} }
@@ -1458,6 +1504,11 @@ bool Boiler::set_releaseWait(const char * value, const int8_t id) {
return true; return true;
} }
// 0x0550 AM200 broadcasted message, all 27 bytes unkown
// Rx: 60 00 FF 00 04 50 00 FF 00 FF FF 00 0D 00 01 00 00 00 00 01 03 01 00 03 00 2D 19 C8 02 94 00 4A
// Rx: 60 00 FF 19 04 50 00 FF FF 39
/* /*
* Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat * Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat
* thermostat always overwrites settings in boiler * thermostat always overwrites settings in boiler
@@ -2079,7 +2130,7 @@ bool Boiler::set_maintenance(const char * value, const int8_t id) {
std::string s; std::string s;
if (Helpers::value2string(value, s)) { if (Helpers::value2string(value, s)) {
if (s == Helpers::toLower(read_flash_string(F_(reset)))) { if (s == Helpers::translated_word(FL_(reset))) {
// LOG_INFO(F("Reset boiler maintenance message")); // LOG_INFO(F("Reset boiler maintenance message"));
write_command(0x05, 0x08, 0xFF, 0x1C); write_command(0x05, 0x08, 0xFF, 0x1C);
return true; return true;

View File

@@ -227,15 +227,11 @@ class Boiler : public EMSdevice {
int8_t blockHyst_; // pos 14?: Hyst. for bolier block (K) int8_t blockHyst_; // pos 14?: Hyst. for bolier block (K)
uint8_t releaseWait_; // pos 15: Boiler release wait time (min) uint8_t releaseWait_; // pos 15: Boiler release wait time (min)
/* /*
* Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat // Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat
* thermostat always overwrites settings in boiler // thermostat always overwrites settings in boiler
* enable settings here if no thermostat is used in system //enable settings here if no thermostat is used in system
* // HybridHP
// HybridHP
uint8_t hybridStrategy_; // cost = 2, temperature = 3, mix = 4 uint8_t hybridStrategy_; // cost = 2, temperature = 3, mix = 4
int8_t switchOverTemp_; // degrees int8_t switchOverTemp_; // degrees
uint8_t energyCostRatio_; // is *10 uint8_t energyCostRatio_; // is *10

View File

@@ -27,7 +27,7 @@ Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_i
// IVT broadcasts Thermostat time from controller (0x09) if display is off. // IVT broadcasts Thermostat time from controller (0x09) if display is off.
if ((flags & 0x0F) == EMS_DEVICE_FLAG_IVT) { if ((flags & 0x0F) == EMS_DEVICE_FLAG_IVT) {
register_telegram_type(0x06, F("RCTime"), false, MAKE_PF_CB(process_dateTime)); register_telegram_type(0x06, F("RCTime"), false, MAKE_PF_CB(process_dateTime));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE);
} }
} }

View File

@@ -29,7 +29,12 @@ Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, con
// RF-Sensor 0x40 sending temperature in telegram 0x435, see https://github.com/emsesp/EMS-ESP32/issues/103 // RF-Sensor 0x40 sending temperature in telegram 0x435, see https://github.com/emsesp/EMS-ESP32/issues/103
if (device_id == 0x40) { if (device_id == 0x40) {
register_telegram_type(0x435, F("RFSensorMessage"), false, MAKE_PF_CB(process_RFSensorMessage)); register_telegram_type(0x435, F("RFSensorMessage"), false, MAKE_PF_CB(process_RFSensorMessage));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &rfTemp_, DeviceValueType::SHORT, FL_(div10), FL_(RFTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&rfTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(RFTemp),
DeviceValueUOM::DEGREES);
} }
} }

View File

@@ -29,8 +29,8 @@ Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, c
register_telegram_type(0x047B, F("HP2"), false, MAKE_PF_CB(process_HPMonitor2)); register_telegram_type(0x047B, F("HP2"), false, MAKE_PF_CB(process_HPMonitor2));
// device values // device values
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &airHumidity_, DeviceValueType::UINT, nullptr, FL_(airHumidity), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &airHumidity_, DeviceValueType::UINT, FL_(airHumidity), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dewTemperature_, DeviceValueType::UINT, nullptr, FL_(dewTemperature), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dewTemperature_, DeviceValueType::UINT, FL_(dewTemperature), DeviceValueUOM::DEGREES);
} }
/* /*

View File

@@ -30,9 +30,14 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) { if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) {
register_telegram_type(0x5BA, F("HpPoolStatus"), true, MAKE_PF_CB(process_HpPoolStatus)); register_telegram_type(0x5BA, F("HpPoolStatus"), true, MAKE_PF_CB(process_HpPoolStatus));
type_ = Type::MP; type_ = Type::MP;
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&poolTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(poolTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT, FL_(poolShunt), DeviceValueUOM::PERCENT);
} }
// EMS+ // EMS+
@@ -43,10 +48,10 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
type_ = Type::HC; type_ = Type::HC;
hc_ = device_id - 0x20 + 1; hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT);
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
} else if (device_id >= 0x28 && device_id <= 0x29) { } else if (device_id >= 0x28 && device_id <= 0x29) {
register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC)); register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
register_telegram_type(device_id - 0x28 + 0x0313, F("MMPLUSConfigMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC)); register_telegram_type(device_id - 0x28 + 0x0313, F("MMPLUSConfigMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC));
@@ -54,25 +59,23 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
type_ = Type::WWC; type_ = Type::WWC;
hc_ = device_id - 0x28 + 1; hc_ = device_id - 0x28 + 1;
uint8_t tag = DeviceValueTAG::TAG_WWC1 + hc_ - 1; uint8_t tag = DeviceValueTAG::TAG_WWC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(wwPumpStatus), DeviceValueUOM::NONE); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(wwPumpStatus), DeviceValueUOM::NONE);
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(wwTempStatus), DeviceValueUOM::NONE); register_device_value(tag, &status_, DeviceValueType::INT, FL_(wwTempStatus), DeviceValueUOM::NONE);
register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, nullptr, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp)); register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp));
register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, nullptr, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp)); register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp));
register_device_value(tag, register_device_value(tag,
&wwDisinfectionTemp_, &wwDisinfectionTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectionTemp), FL_(wwDisinfectionTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDisinfectionTemp)); MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(tag, &wwReducedTemp_, DeviceValueType::UINT, nullptr, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwReducedTemp)); register_device_value(tag, &wwReducedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwReducedTemp));
register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, nullptr, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp)); register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwCircPump_, &wwCircPump_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwCircPump), FL_(wwCircPump),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwCircPump)); MAKE_CF_CB(set_wwCircPump));
@@ -88,13 +91,20 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
type_ = Type::HC; type_ = Type::HC;
hc_ = device_id - 0x20 + 1; hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT);
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
register_device_value(tag, &activated_, DeviceValueType::BOOL, nullptr, FL_(activated), DeviceValueUOM::NONE, MAKE_CF_CB(set_activated)); register_device_value(tag, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE, MAKE_CF_CB(set_activated));
register_device_value( register_device_value(tag,
tag, &setValveTime_, DeviceValueType::UINT, FL_(mul10), FL_(mixerSetTime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_setValveTime), 10, 120); &setValveTime_,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_MUL10,
FL_(mixerSetTime),
DeviceValueUOM::SECONDS,
MAKE_CF_CB(set_setValveTime),
10,
120);
} }
// HT3 // HT3
@@ -107,26 +117,23 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
type_ = Type::WWC; type_ = Type::WWC;
hc_ = device_id - 0x40 + 1; hc_ = device_id - 0x40 + 1;
uint8_t tag = DeviceValueTAG::TAG_WWC9 + hc_ - 1; uint8_t tag = DeviceValueTAG::TAG_WWC9 + hc_ - 1;
register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, nullptr, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp)); register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp));
register_device_value(tag, &wwCurTemp_1_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &wwCurTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwCurTemp_2_, DeviceValueType::USHORT, FL_(div10), FL_(wwCurTemp2), DeviceValueUOM::DEGREES); register_device_value(tag, &wwCurTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES);
register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, FL_(div10), FL_(hydrTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::NONE); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE);
register_device_value( register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset));
tag, &wwFlowTempOffset_, DeviceValueType::UINT, nullptr, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset)); register_device_value(tag, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn));
register_device_value(tag, &wwHystOn_, DeviceValueType::INT, nullptr, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn)); register_device_value(tag, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff));
register_device_value(tag, &wwHystOff_, DeviceValueType::INT, nullptr, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff));
register_device_value(tag, register_device_value(tag,
&wwDisinfectionTemp_, &wwDisinfectionTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectionTemp), FL_(wwDisinfectionTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDisinfectionTemp)); MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwCircPump_, &wwCircPump_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwCircPump), FL_(wwCircPump),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwCircPump)); MAKE_CF_CB(set_wwCircPump));
@@ -138,11 +145,11 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
type_ = Type::HC; type_ = Type::HC;
hc_ = device_id - 0x20 + 1; hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1; uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT); register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT);
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp)); register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump)); register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempVf), DeviceValueUOM::DEGREES); register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES);
} }
} }
} }

View File

@@ -71,48 +71,68 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
// device values... // device values...
// special case for a SM100 DHW device_id with 0x2A where it's not actual a solar module // special case for a SM100 DHW device_id with 0x2A where it's not actual a solar module
if (device_id == 0x2A) { if (device_id == 0x2A) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_1_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_3_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp3), DeviceValueUOM::DEGREES); &wwTemp_1_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_4_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp4), DeviceValueUOM::DEGREES); DeviceValueType::USHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_5_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp5), DeviceValueUOM::DEGREES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwTemp_7_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp7), DeviceValueUOM::DEGREES); FL_(wwTemp1),
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPump_, DeviceValueType::BOOL, nullptr, FL_(wwPump), DeviceValueUOM::NONE); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_3_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp3),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_4_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp4),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_5_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp5),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_7_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp7),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwMaxTemp_, &wwMaxTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwMaxTemp), FL_(wwMaxTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwMaxTemp)); MAKE_CF_CB(set_wwMaxTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwSelTemp_, &wwSelTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwSelTemp), FL_(wwSelTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwSelTemp)); MAKE_CF_CB(set_wwSelTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwRedTemp_, &wwRedTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwRedTemp), FL_(wwRedTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwRedTemp)); MAKE_CF_CB(set_wwRedTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDailyTemp_, &wwDailyTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDailyTemp), FL_(wwDailyTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDailyTemp)); MAKE_CF_CB(set_wwDailyTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectionTemp_, &wwDisinfectionTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectionTemp), FL_(wwDisinfectionTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDisinfectionTemp)); MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCirc_, DeviceValueType::BOOL, nullptr, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwCircMode_, &wwCircMode_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -123,65 +143,83 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwKeepWarm_, &wwKeepWarm_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwKeepWarm), FL_(wwKeepWarm),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwKeepWarm)); MAKE_CF_CB(set_wwKeepWarm));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPumpMod_, DeviceValueType::UINT, nullptr, FL_(wwPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwFlow_, DeviceValueType::UINT, FL_(div10), FL_(wwFlow), DeviceValueUOM::LMIN); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwFlow_,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwFlow),
DeviceValueUOM::LMIN);
return; return;
} }
// common solar values for all modules (except dhw) // common solar values for all modules (except dhw)
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorTemp_, DeviceValueType::SHORT, FL_(div10), FL_(collectorTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylBottomTemp_, DeviceValueType::SHORT, FL_(div10), FL_(cylBottomTemp), DeviceValueUOM::DEGREES); &collectorTemp_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump_, DeviceValueType::BOOL, nullptr, FL_(solarPump), DeviceValueUOM::NONE); DeviceValueType::SHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpWorkTime_, DeviceValueType::TIME, nullptr, FL_(pumpWorkTime), DeviceValueUOM::MINUTES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value( FL_(collectorTemp),
DeviceValueTAG::TAG_DEVICE_DATA, &cylMaxTemp_, DeviceValueType::UINT, nullptr, FL_(cylMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cylMaxTemp)); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylHeated_, DeviceValueType::BOOL, nullptr, FL_(cylHeated), DeviceValueUOM::NONE); &cylBottomTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(cylBottomTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump_, DeviceValueType::BOOL, FL_(solarPump), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pumpWorkTime_, DeviceValueType::TIME, FL_(pumpWorkTime), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylMaxTemp_, DeviceValueType::UINT, FL_(cylMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cylMaxTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorShutdown_, DeviceValueType::BOOL, FL_(collectorShutdown), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylHeated_, DeviceValueType::BOOL, FL_(cylHeated), DeviceValueUOM::NONE);
// values per device flag // values per device flag
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) { if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT, nullptr, FL_(solarPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT, FL_(solarPumpMod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPumpMinMod_, &solarPumpMinMod_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(pumpMinMod), FL_(pumpMinMod),
DeviceValueUOM::PERCENT, DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_PumpMinMod)); MAKE_CF_CB(set_PumpMinMod));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPumpTurnonDiff_, &solarPumpTurnonDiff_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(solarPumpTurnonDiff), FL_(solarPumpTurnonDiff),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_TurnonDiff)); MAKE_CF_CB(set_TurnonDiff));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPumpTurnoffDiff_, &solarPumpTurnoffDiff_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(solarPumpTurnoffDiff), FL_(solarPumpTurnoffDiff),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_TurnoffDiff)); MAKE_CF_CB(set_TurnoffDiff));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPower_, DeviceValueType::SHORT, nullptr, FL_(solarPower), DeviceValueUOM::W); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPower_, DeviceValueType::SHORT, FL_(solarPower), DeviceValueUOM::W);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value( &energyLastHour_,
DeviceValueTAG::TAG_DEVICE_DATA, &maxFlow_, DeviceValueType::UINT, FL_(div10), FL_(maxFlow), DeviceValueUOM::LMIN, MAKE_CF_CB(set_SM10MaxFlow)); DeviceValueType::ULONG,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(energyLastHour),
DeviceValueUOM::WH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&maxFlow_,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(maxFlow),
DeviceValueUOM::LMIN,
MAKE_CF_CB(set_SM10MaxFlow));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwMinTemp_, &wwMinTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwMinTemp), FL_(wwMinTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwMinTemp)); MAKE_CF_CB(set_wwMinTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarIsEnabled_, &solarIsEnabled_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(solarIsEnabled), FL_(solarIsEnabled),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_solarEnabled)); MAKE_CF_CB(set_solarEnabled));
@@ -198,106 +236,144 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
*/ */
} }
if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylMiddleTemp_, DeviceValueType::SHORT, FL_(div10), FL_(cylMiddleTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retHeatAssist_, DeviceValueType::SHORT, FL_(div10), FL_(retHeatAssist), DeviceValueUOM::DEGREES); &cylMiddleTemp_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Valve_, DeviceValueType::BOOL, nullptr, FL_(m1Valve), DeviceValueUOM::NONE); DeviceValueType::SHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(cylMiddleTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&retHeatAssist_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(retHeatAssist),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Valve_, DeviceValueType::BOOL, FL_(m1Valve), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&energyLastHour_,
DeviceValueType::ULONG,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(energyLastHour),
DeviceValueUOM::WH);
} }
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) { if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT, nullptr, FL_(solarPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPumpMod_, DeviceValueType::UINT, FL_(solarPumpMod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPumpMinMod_, &solarPumpMinMod_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(mul5), DeviceValueNumOp::DV_NUMOP_MUL5,
FL_(pumpMinMod), FL_(pumpMinMod),
DeviceValueUOM::PERCENT, DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_PumpMinMod)); MAKE_CF_CB(set_PumpMinMod));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPumpTurnonDiff_, &solarPumpTurnonDiff_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(solarPumpTurnonDiff), FL_(solarPumpTurnonDiff),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_TurnonDiff)); MAKE_CF_CB(set_TurnonDiff));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPumpTurnoffDiff_, &solarPumpTurnoffDiff_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(solarPumpTurnoffDiff), FL_(solarPumpTurnoffDiff),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_TurnoffDiff)); MAKE_CF_CB(set_TurnoffDiff));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collector2Temp_, DeviceValueType::SHORT, FL_(div10), FL_(collector2Temp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylMiddleTemp_, DeviceValueType::SHORT, FL_(div10), FL_(cylMiddleTemp), DeviceValueUOM::DEGREES); &collector2Temp_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &retHeatAssist_, DeviceValueType::SHORT, FL_(div10), FL_(retHeatAssist), DeviceValueUOM::DEGREES); DeviceValueType::SHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Valve_, DeviceValueType::BOOL, nullptr, FL_(m1Valve), DeviceValueUOM::NONE); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Power_, DeviceValueType::UINT, nullptr, FL_(m1Power), DeviceValueUOM::PERCENT); FL_(collector2Temp),
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2_, DeviceValueType::BOOL, nullptr, FL_(solarPump2), DeviceValueUOM::NONE); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2Mod_, DeviceValueType::UINT, nullptr, FL_(solarPump2Mod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylBottomTemp2_, DeviceValueType::SHORT, FL_(div10), FL_(cyl2BottomTemp), DeviceValueUOM::DEGREES); &cylMiddleTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(cylMiddleTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&retHeatAssist_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(retHeatAssist),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Valve_, DeviceValueType::BOOL, FL_(m1Valve), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1Power_, DeviceValueType::UINT, FL_(m1Power), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2_, DeviceValueType::BOOL, FL_(solarPump2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &solarPump2Mod_, DeviceValueType::UINT, FL_(solarPump2Mod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&cylBottomTemp2_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(cyl2BottomTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatExchangerTemp_, &heatExchangerTemp_,
DeviceValueType::SHORT, DeviceValueType::SHORT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(heatExchangerTemp), FL_(heatExchangerTemp),
DeviceValueUOM::DEGREES); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylPumpMod_, DeviceValueType::UINT, nullptr, FL_(cylPumpMod), DeviceValueUOM::PERCENT); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylPumpMod_, DeviceValueType::UINT, FL_(cylPumpMod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveStatus_, DeviceValueType::BOOL, nullptr, FL_(valveStatus), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &valveStatus_, DeviceValueType::BOOL, FL_(valveStatus), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylHeated_, DeviceValueType::BOOL, nullptr, FL_(cylHeated), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cylHeated_, DeviceValueType::BOOL, FL_(cylHeated), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &collectorShutdown_, DeviceValueType::BOOL, FL_(collectorShutdown), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&collectorMaxTemp_, &collectorMaxTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(collectorMaxTemp), FL_(collectorMaxTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_CollectorMaxTemp)); MAKE_CF_CB(set_CollectorMaxTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&collectorMinTemp_, &collectorMinTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(collectorMinTemp), FL_(collectorMinTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_CollectorMinTemp)); MAKE_CF_CB(set_CollectorMinTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyToday_, DeviceValueType::ULONG, nullptr, FL_(energyToday), DeviceValueUOM::WH); &energyLastHour_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyTotal_, DeviceValueType::ULONG, FL_(div10), FL_(energyTotal), DeviceValueUOM::KWH); DeviceValueType::ULONG,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pump2WorkTime_, DeviceValueType::TIME, nullptr, FL_(pump2WorkTime), DeviceValueUOM::MINUTES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1WorkTime_, DeviceValueType::TIME, nullptr, FL_(m1WorkTime), DeviceValueUOM::MINUTES); FL_(energyLastHour),
DeviceValueUOM::WH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &energyToday_, DeviceValueType::ULONG, FL_(energyToday), DeviceValueUOM::WH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&energyTotal_,
DeviceValueType::ULONG,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(energyTotal),
DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &pump2WorkTime_, DeviceValueType::TIME, FL_(pump2WorkTime), DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &m1WorkTime_, DeviceValueType::TIME, FL_(m1WorkTime), DeviceValueUOM::MINUTES);
// register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cyl2MaxTemp_, DeviceValueType::UINT, nullptr, FL_(cyl2MaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cyl2MaxTemp)); // register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &cyl2MaxTemp_, DeviceValueType::UINT, nullptr, FL_(cyl2MaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_cyl2MaxTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatTransferSystem_, &heatTransferSystem_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(heatTransferSystem), FL_(heatTransferSystem),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_heatTransferSystem)); MAKE_CF_CB(set_heatTransferSystem));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&externalCyl_, &externalCyl_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(externalCyl), FL_(externalCyl),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_externalCyl)); MAKE_CF_CB(set_externalCyl));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&thermalDisinfect_, &thermalDisinfect_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(thermalDisinfect), FL_(thermalDisinfect),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_thermalDisinfect)); MAKE_CF_CB(set_thermalDisinfect));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatMetering_, &heatMetering_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(heatMetering), FL_(heatMetering),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_heatMetering)); MAKE_CF_CB(set_heatMetering));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarIsEnabled_, &solarIsEnabled_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(activated), FL_(activated),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_solarEnabled)); MAKE_CF_CB(set_solarEnabled));
@@ -314,7 +390,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
DeviceValueTAG::TAG_DEVICE_DATA, DeviceValueTAG::TAG_DEVICE_DATA,
&solarPumpKick_, &solarPumpKick_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(solarPumpKick), FL_(solarPumpKick),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_solarPumpKick)); MAKE_CF_CB(set_solarPumpKick));
@@ -322,7 +397,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
DeviceValueTAG::TAG_DEVICE_DATA, DeviceValueTAG::TAG_DEVICE_DATA,
&plainWaterMode_, &plainWaterMode_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(plainWaterMode), FL_(plainWaterMode),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_plainWaterMode)); MAKE_CF_CB(set_plainWaterMode));
@@ -330,7 +404,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
DeviceValueTAG::TAG_DEVICE_DATA, DeviceValueTAG::TAG_DEVICE_DATA,
&doubleMatchFlow_, &doubleMatchFlow_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(doubleMatchFlow), FL_(doubleMatchFlow),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_doubleMatchFlow)); MAKE_CF_CB(set_doubleMatchFlow));
@@ -338,21 +411,20 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPump2MinMod_, &solarPump2MinMod_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(pump2MinMod), FL_(pump2MinMod),
DeviceValueUOM::PERCENT, DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_Pump2MinMod)); MAKE_CF_CB(set_Pump2MinMod));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPump2TurnonDiff_, &solarPump2TurnonDiff_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(solarPump2TurnonDiff), FL_(solarPump2TurnonDiff),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_TurnonDiff2)); MAKE_CF_CB(set_TurnonDiff2));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&solarPump2TurnoffDiff_, &solarPump2TurnoffDiff_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(solarPump2TurnoffDiff), FL_(solarPump2TurnoffDiff),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_TurnoffDiff2)); MAKE_CF_CB(set_TurnoffDiff2));
@@ -360,7 +432,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
DeviceValueTAG::TAG_DEVICE_DATA, DeviceValueTAG::TAG_DEVICE_DATA,
&solarPump2Kick_, &solarPump2Kick_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(solarPump2Kick), FL_(solarPump2Kick),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_solarPump2Kick)); MAKE_CF_CB(set_solarPump2Kick));
@@ -369,14 +440,13 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&climateZone_, &climateZone_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(climateZone), FL_(climateZone),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_climateZone)); // climate zone identifier MAKE_CF_CB(set_climateZone)); // climate zone identifier
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&collector1Area_, &collector1Area_,
DeviceValueType::USHORT, DeviceValueType::USHORT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(collector1Area), FL_(collector1Area),
DeviceValueUOM::SQM, DeviceValueUOM::SQM,
MAKE_CF_CB(set_collector1Area)); // Area of collector field 1 MAKE_CF_CB(set_collector1Area)); // Area of collector field 1
@@ -390,7 +460,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&collector2Area_, &collector2Area_,
DeviceValueType::USHORT, DeviceValueType::USHORT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(collector2Area), FL_(collector2Area),
DeviceValueUOM::SQM, DeviceValueUOM::SQM,
MAKE_CF_CB(set_collector2Area)); // Area of collector field 2 MAKE_CF_CB(set_collector2Area)); // Area of collector field 2
@@ -408,11 +478,31 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
FL_(cylPriority), FL_(cylPriority),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_cylPriority)); MAKE_CF_CB(set_cylPriority));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCntFlowTemp_, DeviceValueType::USHORT, FL_(div10), FL_(heatCntFlowTemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCntRetTemp_, DeviceValueType::USHORT, FL_(div10), FL_(heatCntRetTemp), DeviceValueUOM::DEGREES); &heatCntFlowTemp_,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCnt_, DeviceValueType::UINT, nullptr, FL_(heatCnt), DeviceValueUOM::NONE); DeviceValueType::USHORT,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &swapFlowTemp_, DeviceValueType::USHORT, FL_(div10), FL_(swapFlowTemp), DeviceValueUOM::DEGREES); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &swapRetTemp_, DeviceValueType::USHORT, FL_(div10), FL_(swapRetTemp), DeviceValueUOM::DEGREES); FL_(heatCntFlowTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatCntRetTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(heatCntRetTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatCnt_, DeviceValueType::UINT, FL_(heatCnt), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&swapFlowTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(swapFlowTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&swapRetTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(swapRetTemp),
DeviceValueUOM::DEGREES);
} }
} }

View File

@@ -29,9 +29,14 @@ 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(0x9D, F("WM10SetMessage"), false, MAKE_PF_CB(process_WM10SetMessage));
register_telegram_type(0x1E, F("WM10TempMessage"), false, MAKE_PF_CB(process_WM10TempMessage)); register_telegram_type(0x1E, F("WM10TempMessage"), false, MAKE_PF_CB(process_WM10TempMessage));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &activated_, DeviceValueType::BOOL, nullptr, FL_(activated), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &activated_, DeviceValueType::BOOL, FL_(activated), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &status_, DeviceValueType::INT, nullptr, FL_(status), DeviceValueUOM::NONE); &flowTempHc_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(flowTempHc),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &status_, DeviceValueType::INT, FL_(status), DeviceValueUOM::NONE);
} }
// message 0x9D switch on/off // message 0x9D switch on/off

View File

@@ -36,6 +36,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
register_device_values(); // register device values for common values (not heating circuit) register_device_values(); // register device values for common values (not heating circuit)
return; // no values to add return; // no values to add
} }
// common telegram handlers // common telegram handlers
register_telegram_type(EMS_TYPE_RCOutdoorTemp, F("RCOutdoorTemp"), false, MAKE_PF_CB(process_RCOutdoorTemp)); register_telegram_type(EMS_TYPE_RCOutdoorTemp, F("RCOutdoorTemp"), false, MAKE_PF_CB(process_RCOutdoorTemp));
register_telegram_type(EMS_TYPE_RCTime, F("RCTime"), false, MAKE_PF_CB(process_RCTime)); register_telegram_type(EMS_TYPE_RCTime, F("RCTime"), false, MAKE_PF_CB(process_RCTime));
@@ -347,6 +348,7 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
// set the flag saying we want its data during the next auto fetch // set the flag saying we want its data during the next auto fetch
// monitor is broadcasted, but not frequently in some thermostats (IVT, #356) // monitor is broadcasted, but not frequently in some thermostats (IVT, #356)
if (monitor_typeids.size()) { if (monitor_typeids.size()) {
toggle_fetch(monitor_typeids[hc_num - 1], toggle_); toggle_fetch(monitor_typeids[hc_num - 1], toggle_);
} }
@@ -494,45 +496,45 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const {
std::string Thermostat::mode_tostring(uint8_t mode) { std::string Thermostat::mode_tostring(uint8_t mode) {
switch (mode) { switch (mode) {
case HeatingCircuit::Mode::OFF: case HeatingCircuit::Mode::OFF:
return read_flash_string(F_(off)); return Helpers::translated_word(FL_(off));
case HeatingCircuit::Mode::MANUAL: case HeatingCircuit::Mode::MANUAL:
return read_flash_string(F_(manual)); return Helpers::translated_word(FL_(manual));
case HeatingCircuit::Mode::DAY: case HeatingCircuit::Mode::DAY:
return read_flash_string(F_(day)); return Helpers::translated_word(FL_(day));
case HeatingCircuit::Mode::NIGHT: case HeatingCircuit::Mode::NIGHT:
return read_flash_string(F_(night)); return Helpers::translated_word(FL_(night));
case HeatingCircuit::Mode::ECO: case HeatingCircuit::Mode::ECO:
return read_flash_string(F_(eco)); return Helpers::translated_word(FL_(eco));
case HeatingCircuit::Mode::COMFORT: case HeatingCircuit::Mode::COMFORT:
return read_flash_string(F_(comfort)); return Helpers::translated_word(FL_(comfort));
case HeatingCircuit::Mode::HEAT: case HeatingCircuit::Mode::HEAT:
return read_flash_string(F_(heat)); return Helpers::translated_word(FL_(heat));
case HeatingCircuit::Mode::HOLIDAY: case HeatingCircuit::Mode::HOLIDAY:
return read_flash_string(F_(holiday)); return Helpers::translated_word(FL_(holiday));
case HeatingCircuit::Mode::NOFROST: case HeatingCircuit::Mode::NOFROST:
return read_flash_string(F_(nofrost)); return Helpers::translated_word(FL_(nofrost));
case HeatingCircuit::Mode::AUTO: case HeatingCircuit::Mode::AUTO:
return read_flash_string(F_(auto)); return Helpers::translated_word(FL_(auto));
case HeatingCircuit::Mode::SUMMER: case HeatingCircuit::Mode::SUMMER:
return read_flash_string(F_(summer)); return Helpers::translated_word(FL_(summer));
case HeatingCircuit::Mode::OFFSET: case HeatingCircuit::Mode::OFFSET:
return read_flash_string(F_(offset)); return Helpers::translated_word(FL_(offset));
case HeatingCircuit::Mode::DESIGN: case HeatingCircuit::Mode::DESIGN:
return read_flash_string(F_(design)); return Helpers::translated_word(FL_(design));
case HeatingCircuit::Mode::MINFLOW: case HeatingCircuit::Mode::MINFLOW:
return read_flash_string(F_(minflow)); return Helpers::translated_word(FL_(minflow));
case HeatingCircuit::Mode::MAXFLOW: case HeatingCircuit::Mode::MAXFLOW:
return read_flash_string(F_(maxflow)); return Helpers::translated_word(FL_(maxflow));
case HeatingCircuit::Mode::ROOMINFLUENCE: case HeatingCircuit::Mode::ROOMINFLUENCE:
return read_flash_string(F_(roominfluence[0])); return Helpers::translated_word(FL_(roominfluence));
case HeatingCircuit::Mode::FLOWOFFSET: case HeatingCircuit::Mode::FLOWOFFSET:
return read_flash_string(F_(flowtempoffset[0])); return Helpers::translated_word(FL_(flowtempoffset));
case HeatingCircuit::Mode::TEMPAUTO: case HeatingCircuit::Mode::TEMPAUTO:
return read_flash_string(F_(tempauto)); return Helpers::translated_word(FL_(tempauto));
case HeatingCircuit::Mode::NOREDUCE: case HeatingCircuit::Mode::NOREDUCE:
return read_flash_string(F_(noreduce)); return Helpers::translated_word(FL_(noreduce));
default: default:
return read_flash_string(F_(unknown)); return Helpers::translated_word(FL_(unknown));
} }
} }
@@ -630,7 +632,8 @@ void Thermostat::process_RC20Timer(std::shared_ptr<const Telegram> telegram) {
uint8_t temp = telegram->message_data[0] & 7; uint8_t temp = telegram->message_data[0] & 7;
uint8_t time = telegram->message_data[1]; uint8_t time = telegram->message_data[1];
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day]); std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
if (day == 7) { if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no); snprintf(data, sizeof(data), "%02d not_set", no);
} else { } else {
@@ -828,12 +831,18 @@ void Thermostat::process_RC35wwTimer(std::shared_ptr<const Telegram> telegram) {
uint8_t on = telegram->message_data[0] & 1; uint8_t on = telegram->message_data[0] & 1;
uint8_t time = telegram->message_data[1]; uint8_t time = telegram->message_data[1];
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day]);
char data[sizeof(wwSwitchTime_)]; char data[sizeof(wwSwitchTime_)];
if (day == 7) { if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no); snprintf(data, sizeof(data), "%02d not_set", no);
} else { } else {
snprintf(data, sizeof(data), "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), on ? "on" : "off"); snprintf(data,
sizeof(data),
"%02d %s %02d:%02d %s",
no,
Helpers::translated_word(FL_(enum_dayOfWeek)[day]).c_str(),
time / 6,
10 * (time % 6),
on ? (Helpers::translated_word(FL_(on))).c_str() : (Helpers::translated_word(FL_(on))).c_str());
} }
if (telegram->type_id == 0x38) { if (telegram->type_id == 0x38) {
strlcpy(wwSwitchTime_, data, sizeof(wwSwitchTime_)); strlcpy(wwSwitchTime_, data, sizeof(wwSwitchTime_));
@@ -1217,7 +1226,8 @@ void Thermostat::process_RC30Timer(std::shared_ptr<const Telegram> telegram) {
uint8_t temp = telegram->message_data[0] & 7; uint8_t temp = telegram->message_data[0] & 7;
uint8_t time = telegram->message_data[1]; uint8_t time = telegram->message_data[1];
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day]); std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
if (day == 7) { if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no); snprintf(data, sizeof(data), "%02d not_set", no);
} else { } else {
@@ -1352,11 +1362,17 @@ void Thermostat::process_RC35Timer(std::shared_ptr<const Telegram> telegram) {
uint8_t on = telegram->message_data[0] & 1; uint8_t on = telegram->message_data[0] & 1;
uint8_t time = telegram->message_data[1]; uint8_t time = telegram->message_data[1];
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day]);
if (day == 7) { if (day == 7) {
snprintf(data, sizeof(data), "%02d not_set", no); snprintf(data, sizeof(data), "%02d not_set", no);
} else { } else {
snprintf(data, sizeof(data), "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), on ? "on" : "off"); snprintf(data,
sizeof(data),
"%02d %s %02d:%02d %s",
no,
Helpers::translated_word(FL_(enum_dayOfWeek)[day]).c_str(),
time / 6,
10 * (time % 6),
on ? Helpers::translated_word(FL_(on)).c_str() : Helpers::translated_word(FL_(on)).c_str());
} }
if (!prog) { if (!prog) {
strlcpy(hc->switchtime1, data, sizeof(hc->switchtime1)); strlcpy(hc->switchtime1, data, sizeof(hc->switchtime1));
@@ -2264,27 +2280,27 @@ bool Thermostat::set_mode(const char * value, const int8_t id) {
uint8_t num = value[0] - '0'; uint8_t num = value[0] - '0';
switch (model()) { switch (model()) {
case EMSdevice::EMS_DEVICE_FLAG_RC10: case EMSdevice::EMS_DEVICE_FLAG_RC10:
mode = read_flash_string(FL_(enum_mode6)[num]); mode = Helpers::translated_word(FL_(enum_mode6)[num]);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC20: case EMSdevice::EMS_DEVICE_FLAG_RC20:
case EMSdevice::EMS_DEVICE_FLAG_RC20_N: case EMSdevice::EMS_DEVICE_FLAG_RC20_N:
mode = read_flash_string(FL_(enum_mode2)[num]); mode = Helpers::translated_word(FL_(enum_mode2)[num]);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC25: case EMSdevice::EMS_DEVICE_FLAG_RC25:
case EMSdevice::EMS_DEVICE_FLAG_RC30: case EMSdevice::EMS_DEVICE_FLAG_RC30:
case EMSdevice::EMS_DEVICE_FLAG_RC35: case EMSdevice::EMS_DEVICE_FLAG_RC35:
case EMSdevice::EMS_DEVICE_FLAG_RC30_N: case EMSdevice::EMS_DEVICE_FLAG_RC30_N:
mode = read_flash_string(FL_(enum_mode3)[num]); mode = Helpers::translated_word(FL_(enum_mode3)[num]);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_RC300: case EMSdevice::EMS_DEVICE_FLAG_RC300:
case EMSdevice::EMS_DEVICE_FLAG_RC100: case EMSdevice::EMS_DEVICE_FLAG_RC100:
mode = read_flash_string(FL_(enum_mode)[num]); mode = Helpers::translated_word(FL_(enum_mode)[num]);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_JUNKERS: case EMSdevice::EMS_DEVICE_FLAG_JUNKERS:
mode = read_flash_string(FL_(enum_mode4)[num]); mode = Helpers::translated_word(FL_(enum_mode4)[num]);
break; break;
case EMSdevice::EMS_DEVICE_FLAG_CRF: case EMSdevice::EMS_DEVICE_FLAG_CRF:
mode = read_flash_string(FL_(enum_mode5)[num]); mode = Helpers::translated_word(FL_(enum_mode5)[num]);
break; break;
default: default:
return false; return false;
@@ -2294,6 +2310,7 @@ bool Thermostat::set_mode(const char * value, const int8_t id) {
} }
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
if (mode_tostring(HeatingCircuit::Mode::OFF) == mode) { if (mode_tostring(HeatingCircuit::Mode::OFF) == mode) {
return set_mode_n(HeatingCircuit::Mode::OFF, hc_num); return set_mode_n(HeatingCircuit::Mode::OFF, hc_num);
} }
@@ -2707,9 +2724,15 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char
} }
if (strlen(value) > 4) { if (strlen(value) > 4) {
for (uint8_t i = 0; i < 7; i++) { for (uint8_t i = 0; i < 7; i++) {
if (!strncmp(&value[3], read_flash_string(FL_(enum_dayOfWeek)[i]).c_str(), 2)) { // we use EN settings for the day abbreviation
if (!strncmp(&value[3], read_flash_string(FL_(enum_dayOfWeek)[i][0]).c_str(), 2)) {
day = i; day = i;
} }
// auto translated_dow = Helpers::translated_word(FL_(enum_dayOfWeek)[i]);
// if (!strncmp(&value[3], translated_dow.c_str(), translated_dow.length())) {
// day = i;
// }
} }
} }
if (strlen(value) > 10) { if (strlen(value) > 10) {
@@ -2747,13 +2770,20 @@ bool Thermostat::set_switchtime(const char * value, const uint16_t type_id, char
return false; return false;
} }
if (data[0] != 0xE7) { if (data[0] != 0xE7) {
std::string sday = read_flash_string(FL_(enum_dayOfWeek)[day]); std::string sday = Helpers::translated_word(FL_(enum_dayOfWeek)[day]);
if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) { if (model() == EMS_DEVICE_FLAG_RC35 || model() == EMS_DEVICE_FLAG_RC30_N) {
snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), on ? "on" : "off"); snprintf(out,
len,
"%02d %s %02d:%02d %s",
no,
sday.c_str(),
time / 6,
10 * (time % 6),
on ? Helpers::translated_word(FL_(on)).c_str() : Helpers::translated_word(FL_(on)).c_str());
} else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) { } else if ((model() == EMS_DEVICE_FLAG_RC20) || (model() == EMS_DEVICE_FLAG_RC30)) {
snprintf(out, len, "%02d %s %02d:%02d T%d", no, sday.c_str(), time / 6, 10 * (time % 6), on); snprintf(out, len, "%02d %s %02d:%02d T%d", no, sday.c_str(), time / 6, 10 * (time % 6), on);
} else { } else {
std::string son = read_flash_string(FL_(enum_switchmode)[on]); std::string son = Helpers::translated_word(FL_(enum_switchmode)[on]);
snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), son.c_str()); snprintf(out, len, "%02d %s %02d:%02d %s", no, sday.c_str(), time / 6, 10 * (time % 6), son.c_str());
} }
} else { } else {
@@ -3378,17 +3408,22 @@ void Thermostat::register_device_values() {
if (device_id() >= 0x38 && device_id() <= 0x3F) { if (device_id() >= 0x38 && device_id() <= 0x3F) {
// each device controls only one hc, so we tag the values // each device controls only one hc, so we tag the values
uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x38; uint8_t tag = DeviceValueTAG::TAG_HC1 + device_id() - 0x38;
register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, FL_(div10), FL_(remotetemp), DeviceValueUOM::DEGREES); register_device_value(tag, &tempsensor1_, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &dewtemperature_, DeviceValueType::INT, nullptr, FL_(dewTemperature), DeviceValueUOM::DEGREES); register_device_value(tag, &dewtemperature_, DeviceValueType::INT, FL_(dewTemperature), DeviceValueUOM::DEGREES);
register_device_value(tag, &humidity_, DeviceValueType::INT, nullptr, FL_(airHumidity), DeviceValueUOM::PERCENT); register_device_value(tag, &humidity_, DeviceValueType::INT, FL_(airHumidity), DeviceValueUOM::PERCENT);
register_device_value( register_device_value(tag,
tag, &ibaCalIntTemperature_, DeviceValueType::INT, FL_(div10), FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_calinttemp)); &ibaCalIntTemperature_,
DeviceValueType::INT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(ibaCalIntTemperature),
DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_calinttemp));
return; return;
} }
// Common for all thermostats // Common for all thermostats
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &errorCode_, DeviceValueType::STRING, nullptr, FL_(errorCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &errorCode_, DeviceValueType::STRING, FL_(errorCode), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, nullptr, FL_(lastCode), DeviceValueUOM::NONE); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &lastCode_, DeviceValueType::STRING, FL_(lastCode), DeviceValueUOM::NONE);
switch (this->model()) { switch (this->model()) {
case EMS_DEVICE_FLAG_RC100: case EMS_DEVICE_FLAG_RC100:
@@ -3409,10 +3444,10 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&dampedoutdoortemp2_, &dampedoutdoortemp2_,
DeviceValueType::SHORT, DeviceValueType::SHORT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(dampedoutdoortemp), FL_(dampedoutdoortemp),
DeviceValueUOM::DEGREES); DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &floordrytemp_, DeviceValueType::UINT, nullptr, FL_(floordrytemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &floordrytemp_, DeviceValueType::UINT, FL_(floordrytemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaBuildingType_, &ibaBuildingType_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -3423,20 +3458,16 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaMinExtTemperature_, &ibaMinExtTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
nullptr,
FL_(ibaMinExtTemperature), FL_(ibaMinExtTemperature),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_minexttemp)); MAKE_CF_CB(set_minexttemp));
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping));
DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, nullptr, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp));
register_device_value( register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwSetTempLow_, &wwSetTempLow_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwSetTempLow), FL_(wwSetTempLow),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwtemplow)); MAKE_CF_CB(set_wwtemplow));
@@ -3450,18 +3481,16 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwChargeDuration_, &wwChargeDuration_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(mul15), DeviceValueNumOp::DV_NUMOP_MUL15,
FL_(wwChargeDuration), FL_(wwChargeDuration),
DeviceValueUOM::MINUTES, DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_wwchargeduration)); MAKE_CF_CB(set_wwchargeduration));
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCharge_, DeviceValueType::BOOL, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge));
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCharge_, DeviceValueType::BOOL, nullptr, FL_(wwCharge), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcharge)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwExtra1_, DeviceValueType::UINT, FL_(wwExtra1), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwExtra1_, DeviceValueType::UINT, nullptr, FL_(wwExtra1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwExtra2_, DeviceValueType::UINT, FL_(wwExtra2), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwExtra2_, DeviceValueType::UINT, nullptr, FL_(wwExtra2), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfecting_, &wwDisinfecting_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwDisinfecting), FL_(wwDisinfecting),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfect)); MAKE_CF_CB(set_wwDisinfect));
@@ -3475,7 +3504,7 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectHour_, &wwDisinfectHour_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(mul15), DeviceValueNumOp::DV_NUMOP_MUL15,
FL_(wwDisinfectTime), FL_(wwDisinfectTime),
DeviceValueUOM::MINUTES, DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_wwDisinfectHour), MAKE_CF_CB(set_wwDisinfectHour),
@@ -3486,7 +3515,7 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaCalIntTemperature_, &ibaCalIntTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(ibaCalIntTemperature), FL_(ibaCalIntTemperature),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_calinttemp)); MAKE_CF_CB(set_calinttemp));
@@ -3497,35 +3526,32 @@ void Thermostat::register_device_values() {
FL_(heatingPID), FL_(heatingPID),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_heatingpid)); MAKE_CF_CB(set_heatingpid));
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight));
DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, nullptr, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight));
register_device_value( register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
break; break;
case EMS_DEVICE_FLAG_RC20_N: case EMS_DEVICE_FLAG_RC20_N:
case EMS_DEVICE_FLAG_RC25: case EMS_DEVICE_FLAG_RC25:
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaMinExtTemperature_, &ibaMinExtTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
nullptr,
FL_(ibaMinExtTemperature), FL_(ibaMinExtTemperature),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_minexttemp)); MAKE_CF_CB(set_minexttemp));
break; break;
case EMS_DEVICE_FLAG_RC20: case EMS_DEVICE_FLAG_RC20:
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
break; break;
case EMS_DEVICE_FLAG_RC30: case EMS_DEVICE_FLAG_RC30:
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaClockOffset_, &ibaClockOffset_,
DeviceValueType::INT, DeviceValueType::INT,
nullptr,
FL_(ibaClockOffset), FL_(ibaClockOffset),
DeviceValueUOM::SECONDS, DeviceValueUOM::SECONDS,
MAKE_CF_CB(set_clockoffset)); // offset (in sec) to clock, 0xff=-1s, 0x02=2s MAKE_CF_CB(set_clockoffset)); // offset (in sec) to clock, 0xff=-1s, 0x02=2s
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &autodst_, DeviceValueType::BOOL, nullptr, FL_(autodst), DeviceValueUOM::NONE, MAKE_CF_CB(set_autodst)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &autodst_, DeviceValueType::BOOL, FL_(autodst), DeviceValueUOM::NONE, MAKE_CF_CB(set_autodst));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaLanguage_, &ibaLanguage_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -3539,26 +3565,11 @@ void Thermostat::register_device_values() {
FL_(enum_ibaMainDisplay), FL_(enum_ibaMainDisplay),
FL_(ibaMainDisplay), FL_(ibaMainDisplay),
DeviceValueUOM::NONE); DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight));
register_device_value( register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &backlight_, DeviceValueType::BOOL, nullptr, FL_(backlight), DeviceValueUOM::NONE, MAKE_CF_CB(set_backlight)); DeviceValueTAG::TAG_DEVICE_DATA, &brightness_, DeviceValueType::INT, FL_(brightness), DeviceValueUOM::NONE, MAKE_CF_CB(set_brightness), -15, 15);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(
&brightness_, DeviceValueTAG::TAG_DEVICE_DATA, &mixingvalves_, DeviceValueType::UINT, FL_(mixingvalves), DeviceValueUOM::NONE, MAKE_CF_CB(set_mixingvalves), 0, 2);
DeviceValueType::INT,
nullptr,
FL_(brightness),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_brightness),
-15,
15);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&mixingvalves_,
DeviceValueType::UINT,
nullptr,
FL_(mixingvalves),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_mixingvalves),
0,
2);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaBuildingType_, &ibaBuildingType_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -3573,30 +3584,34 @@ void Thermostat::register_device_values() {
FL_(heatingPID), FL_(heatingPID),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_heatingpid)); MAKE_CF_CB(set_heatingpid));
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &preheating_, DeviceValueType::BOOL, FL_(preheating), DeviceValueUOM::NONE, MAKE_CF_CB(set_preheating));
DeviceValueTAG::TAG_DEVICE_DATA, &preheating_, DeviceValueType::BOOL, nullptr, FL_(preheating), DeviceValueUOM::NONE, MAKE_CF_CB(set_preheating));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaCalIntTemperature_, &ibaCalIntTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(ibaCalIntTemperature), FL_(ibaCalIntTemperature),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_calinttemp)); MAKE_CF_CB(set_calinttemp));
register_device_value( register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
DeviceValueTAG::TAG_DEVICE_DATA, &offtemp_, DeviceValueType::UINT, FL_(div2), FL_(offtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_offtemp), 5, 30); &offtemp_,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(offtemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_offtemp),
5,
30);
register_device_value( register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode3), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwWhenModeOff_, &wwWhenModeOff_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwWhenModeOff), FL_(wwWhenModeOff),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwwhenmodeoff)); MAKE_CF_CB(set_wwwhenmodeoff));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfecting_, &wwDisinfecting_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwDisinfecting), FL_(wwDisinfecting),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfect)); MAKE_CF_CB(set_wwDisinfect));
@@ -3610,7 +3625,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectHour_, &wwDisinfectHour_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectHour), FL_(wwDisinfectHour),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfectHour), MAKE_CF_CB(set_wwDisinfectHour),
@@ -3632,7 +3646,7 @@ void Thermostat::register_device_values() {
MAKE_CF_CB(set_wwVacation)); MAKE_CF_CB(set_wwVacation));
break; break;
case EMS_DEVICE_FLAG_RC30_N: case EMS_DEVICE_FLAG_RC30_N:
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaMainDisplay_, &ibaMainDisplay_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -3643,24 +3657,22 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaClockOffset_, &ibaClockOffset_,
DeviceValueType::INT, DeviceValueType::INT,
nullptr,
FL_(ibaClockOffset), FL_(ibaClockOffset),
DeviceValueUOM::SECONDS); // offset (in sec) to clock, 0xff=-1s, 0x02=2s DeviceValueUOM::SECONDS); // offset (in sec) to clock, 0xff=-1s, 0x02=2s
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaCalIntTemperature_, &ibaCalIntTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(ibaCalIntTemperature), FL_(ibaCalIntTemperature),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_calinttemp)); MAKE_CF_CB(set_calinttemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaMinExtTemperature_, &ibaMinExtTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
nullptr,
FL_(ibaMinExtTemperature), FL_(ibaMinExtTemperature),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_minexttemp)); MAKE_CF_CB(set_minexttemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT, nullptr, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaBuildingType_, &ibaBuildingType_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -3694,7 +3706,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfecting_, &wwDisinfecting_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwDisinfecting), FL_(wwDisinfecting),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfect)); MAKE_CF_CB(set_wwDisinfect));
@@ -3708,7 +3719,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectHour_, &wwDisinfectHour_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectHour), FL_(wwDisinfectHour),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfectHour), MAKE_CF_CB(set_wwDisinfectHour),
@@ -3717,14 +3727,12 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwMaxTemp_, &wwMaxTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwMaxTemp), FL_(wwMaxTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwMaxTemp)); MAKE_CF_CB(set_wwMaxTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwOneTimeKey_, &wwOneTimeKey_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwOneTimeKey), FL_(wwOneTimeKey),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwOneTimeKey)); MAKE_CF_CB(set_wwOneTimeKey));
@@ -3768,7 +3776,7 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaCalIntTemperature_, &ibaCalIntTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(ibaCalIntTemperature), FL_(ibaCalIntTemperature),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_calinttemp), MAKE_CF_CB(set_calinttemp),
@@ -3777,15 +3785,23 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaMinExtTemperature_, &ibaMinExtTemperature_,
DeviceValueType::INT, DeviceValueType::INT,
nullptr,
FL_(ibaMinExtTemperature), FL_(ibaMinExtTemperature),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_minexttemp)); MAKE_CF_CB(set_minexttemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempsensor1_, DeviceValueType::SHORT, FL_(div10), FL_(tempsensor1), DeviceValueUOM::DEGREES); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &tempsensor2_, DeviceValueType::SHORT, FL_(div10), FL_(tempsensor2), DeviceValueUOM::DEGREES); &tempsensor1_,
register_device_value( DeviceValueType::SHORT,
DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, nullptr, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping)); DeviceValueNumOp::DV_NUMOP_DIV10,
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT, nullptr, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); FL_(tempsensor1),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&tempsensor2_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(tempsensor2),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dampedoutdoortemp_, DeviceValueType::INT, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&ibaBuildingType_, &ibaBuildingType_,
DeviceValueType::ENUM, DeviceValueType::ENUM,
@@ -3819,7 +3835,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfecting_, &wwDisinfecting_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwDisinfecting), FL_(wwDisinfecting),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfect)); MAKE_CF_CB(set_wwDisinfect));
@@ -3833,7 +3848,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectHour_, &wwDisinfectHour_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwDisinfectHour), FL_(wwDisinfectHour),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwDisinfectHour), MAKE_CF_CB(set_wwDisinfectHour),
@@ -3842,14 +3856,12 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwMaxTemp_, &wwMaxTemp_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(wwMaxTemp), FL_(wwMaxTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwMaxTemp)); MAKE_CF_CB(set_wwMaxTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwOneTimeKey_, &wwOneTimeKey_,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(wwOneTimeKey), FL_(wwOneTimeKey),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwOneTimeKey)); MAKE_CF_CB(set_wwOneTimeKey));
@@ -3905,7 +3917,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&switchOverTemp_, &switchOverTemp_,
DeviceValueType::INT, DeviceValueType::INT,
nullptr,
FL_(switchOverTemp), FL_(switchOverTemp),
DeviceValueUOM::DEGREES, DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_switchOverTemp), MAKE_CF_CB(set_switchOverTemp),
@@ -3914,7 +3925,7 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&energyCostRatio_, &energyCostRatio_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(energyCostRatio), FL_(energyCostRatio),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_energyCostRatio), MAKE_CF_CB(set_energyCostRatio),
@@ -3923,7 +3934,7 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&fossileFactor_, &fossileFactor_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(fossileFactor), FL_(fossileFactor),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_fossileFactor), MAKE_CF_CB(set_fossileFactor),
@@ -3932,7 +3943,7 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&electricFactor_, &electricFactor_,
DeviceValueType::UINT, DeviceValueType::UINT,
FL_(div10), DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(electricFactor), FL_(electricFactor),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_electricFactor), MAKE_CF_CB(set_electricFactor),
@@ -3941,7 +3952,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&delayBoiler_, &delayBoiler_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(delayBoiler), FL_(delayBoiler),
DeviceValueUOM::MINUTES, DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_delayBoiler), MAKE_CF_CB(set_delayBoiler),
@@ -3950,7 +3960,6 @@ void Thermostat::register_device_values() {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&tempDiffBoiler_, &tempDiffBoiler_,
DeviceValueType::UINT, DeviceValueType::UINT,
nullptr,
FL_(tempDiffBoiler), FL_(tempDiffBoiler),
DeviceValueUOM::DEGREES_R, DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_tempDiffBoiler), MAKE_CF_CB(set_tempDiffBoiler),
@@ -3959,11 +3968,11 @@ void Thermostat::register_device_values() {
break; break;
case EMS_DEVICE_FLAG_EASY: case EMS_DEVICE_FLAG_EASY:
// Easy TC100 have no date/time, see issue #100, not sure about CT200, so leave it. // Easy TC100 have no date/time, see issue #100, not sure about CT200, so leave it.
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
break; break;
case EMS_DEVICE_FLAG_CRF: case EMS_DEVICE_FLAG_CRF:
default: default:
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &dateTime_, DeviceValueType::STRING, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime
break; break;
} }
} }
@@ -3976,18 +3985,18 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc->hc(); uint8_t tag = DeviceValueTAG::TAG_HC1 + hc->hc();
// different logic on how temperature values are stored, depending on model // different logic on how temperature values are stored, depending on model
const __FlashStringHelper * const * seltemp_divider; uint8_t seltemp_divider;
const __FlashStringHelper * const * roomtemp_divider; uint8_t roomtemp_divider;
if (model == EMS_DEVICE_FLAG_EASY) { if (model == EMS_DEVICE_FLAG_EASY) {
seltemp_divider = FL_(div100); seltemp_divider = DeviceValueNumOp::DV_NUMOP_DIV100;
roomtemp_divider = FL_(div100); roomtemp_divider = DeviceValueNumOp::DV_NUMOP_DIV100;
} else if (model == EMS_DEVICE_FLAG_JUNKERS) { } else if (model == EMS_DEVICE_FLAG_JUNKERS) {
seltemp_divider = FL_(div10); seltemp_divider = DeviceValueNumOp::DV_NUMOP_DIV10;
roomtemp_divider = FL_(div10); roomtemp_divider = DeviceValueNumOp::DV_NUMOP_DIV10;
} else { } else {
seltemp_divider = FL_(div2); seltemp_divider = DeviceValueNumOp::DV_NUMOP_DIV2;
roomtemp_divider = FL_(div10); roomtemp_divider = DeviceValueNumOp::DV_NUMOP_DIV10;
} }
if (has_flags(EMS_DEVICE_FLAG_NO_WRITE)) { if (has_flags(EMS_DEVICE_FLAG_NO_WRITE)) {
register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->selTemp, DeviceValueType::SHORT, seltemp_divider, FL_(selRoomTemp), DeviceValueUOM::DEGREES);
@@ -4000,31 +4009,41 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
switch (model) { switch (model) {
case EMS_DEVICE_FLAG_RC10: case EMS_DEVICE_FLAG_RC10:
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode6), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode6), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); register_device_value(
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
register_device_value(tag, &hc->reducehours, DeviceValueType::UINT, nullptr, FL_(reducehours), DeviceValueUOM::HOURS, MAKE_CF_CB(set_reducehours)); register_device_value(
register_device_value(tag, &hc->reduceminutes, DeviceValueType::USHORT, nullptr, FL_(reduceminutes), DeviceValueUOM::MINUTES); tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
register_device_value(tag, &hc->reducehours, DeviceValueType::UINT, FL_(reducehours), DeviceValueUOM::HOURS, MAKE_CF_CB(set_reducehours));
register_device_value(tag, &hc->reduceminutes, DeviceValueType::USHORT, FL_(reduceminutes), DeviceValueUOM::MINUTES);
break; break;
case EMS_DEVICE_FLAG_RC100: case EMS_DEVICE_FLAG_RC100:
case EMS_DEVICE_FLAG_RC300: 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->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->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), 10, 30);
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_R, 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::DEGREES_R, MAKE_CF_CB(set_roominfluence));
register_device_value( register_device_value(
tag, &hc->roominfl_factor, DeviceValueType::UINT, FL_(div10), FL_(roominfl_factor), DeviceValueUOM::NONE, MAKE_CF_CB(set_roominfl_factor)); tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp));
register_device_value(tag, &hc->curroominfl, DeviceValueType::SHORT, FL_(div10), FL_(curroominfl), DeviceValueUOM::DEGREES_R); register_device_value(
tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp));
register_device_value(
tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(comforttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_comforttemp));
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30);
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp));
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, FL_(offsettemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_offsettemp));
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp));
register_device_value(tag, &hc->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp));
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, FL_(roominfluence), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_roominfluence));
register_device_value(tag,
&hc->roominfl_factor,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(roominfl_factor),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_roominfl_factor));
register_device_value(tag, &hc->curroominfl, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(curroominfl), DeviceValueUOM::DEGREES_R);
register_device_value( register_device_value(
tag, &hc->nofrostmode, DeviceValueType::ENUM, FL_(enum_nofrostmode1), FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrostmode)); tag, &hc->nofrostmode, DeviceValueType::ENUM, FL_(enum_nofrostmode1), FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrostmode));
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp)); register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, 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->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES);
register_device_value( register_device_value(
tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype));
register_device_value( register_device_value(
@@ -4041,65 +4060,99 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
register_device_value( register_device_value(
tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode1), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode1), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
register_device_value( register_device_value(tag,
tag, &hc->tempautotemp, DeviceValueType::INT, FL_(div2), FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp), -1, 30); &hc->tempautotemp,
register_device_value( DeviceValueType::INT,
tag, &hc->remoteseltemp, DeviceValueType::INT, FL_(div2), FL_(remoteseltemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_remoteseltemp), -1, 30); DeviceValueNumOp::DV_NUMOP_DIV2,
register_device_value(tag, &hc->fastHeatup, DeviceValueType::UINT, nullptr, FL_(fastheatup), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fastheatup)); FL_(tempautotemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_tempautotemp),
-1,
30);
register_device_value(tag,
&hc->remoteseltemp,
DeviceValueType::INT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(remoteseltemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_remoteseltemp),
-1,
30);
register_device_value(tag, &hc->fastHeatup, DeviceValueType::UINT, FL_(fastheatup), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fastheatup));
register_device_value(tag, register_device_value(tag,
&hc->switchonoptimization, &hc->switchonoptimization,
DeviceValueType::BOOL, DeviceValueType::BOOL,
nullptr,
FL_(switchonoptimization), FL_(switchonoptimization),
DeviceValueUOM::NONE, DeviceValueUOM::NONE,
MAKE_CF_CB(set_switchonoptimization)); MAKE_CF_CB(set_switchonoptimization));
register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode1), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode)); register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode1), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode));
register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, nullptr, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp)); register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp));
register_device_value(tag, &hc->reducetemp, DeviceValueType::INT, nullptr, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp)); register_device_value(tag, &hc->reducetemp, DeviceValueType::INT, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp));
register_device_value(tag, &hc->wwprio, DeviceValueType::BOOL, nullptr, FL_(wwprio), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwprio)); register_device_value(tag, &hc->wwprio, DeviceValueType::BOOL, FL_(wwprio), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwprio));
break; break;
case EMS_DEVICE_FLAG_CRF: case EMS_DEVICE_FLAG_CRF:
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode5), FL_(mode), DeviceValueUOM::NONE); register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode5), FL_(mode), DeviceValueUOM::NONE);
register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype5), FL_(modetype), DeviceValueUOM::NONE); register_device_value(tag, &hc->modetype, DeviceValueType::ENUM, FL_(enum_modetype5), FL_(modetype), DeviceValueUOM::NONE);
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, nullptr, FL_(targetflowtemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES);
break; break;
case EMS_DEVICE_FLAG_RC20: 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)); 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->manualtemp, DeviceValueType::UINT, FL_(div2), FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp)); register_device_value(
register_device_value(tag, &hc->daylowtemp, DeviceValueType::UINT, FL_(div2), FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); tag, &hc->manualtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(manualtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_manualtemp));
register_device_value(tag, &hc->daymidtemp, DeviceValueType::UINT, FL_(div2), FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); register_device_value(
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); tag, &hc->daylowtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp));
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); register_device_value(
tag, &hc->daymidtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp));
register_device_value(
tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
register_device_value(
tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
register_device_value( register_device_value(
tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1));
break; break;
case EMS_DEVICE_FLAG_RC20_N: 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->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_modetype3), FL_(modetype), DeviceValueUOM::NONE); 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(
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
register_device_value(
tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode3), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode3), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, nullptr, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, 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->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp));
register_device_value(tag, &hc->tempautotemp, DeviceValueType::UINT, FL_(div2), FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp)); register_device_value(tag,
&hc->tempautotemp,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(tempautotemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_tempautotemp));
register_device_value( register_device_value(
tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype));
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30); register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 10, 30);
register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE);
register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, FL_(div10), FL_(remotetemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES);
break; break;
case EMS_DEVICE_FLAG_RC25: case EMS_DEVICE_FLAG_RC25:
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->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->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(
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
register_device_value(
tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode3), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode3), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, nullptr, FL_(minflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minflowtemp)); register_device_value(tag, &hc->minflowtemp, DeviceValueType::UINT, 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->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp));
register_device_value(tag, &hc->tempautotemp, DeviceValueType::UINT, FL_(div2), FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp)); register_device_value(tag,
&hc->tempautotemp,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(tempautotemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_tempautotemp));
register_device_value( register_device_value(
tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype));
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25);
register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE);
break; break;
case EMS_DEVICE_FLAG_RC30: case EMS_DEVICE_FLAG_RC30:
@@ -4107,41 +4160,64 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday));
register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), 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->pause, DeviceValueType::UINT, 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->party, DeviceValueType::UINT, FL_(party), DeviceValueUOM::HOURS, MAKE_CF_CB(set_party));
register_device_value( register_device_value(
tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime1), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1));
register_device_value( register_device_value(
tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype));
register_device_value( register_device_value(
tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode));
register_device_value(tag, &hc->holidaytemp, DeviceValueType::UINT, FL_(div2), FL_(holidaytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_holidaytemp)); register_device_value(tag,
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); &hc->holidaytemp,
register_device_value(tag, &hc->daylowtemp, DeviceValueType::UINT, FL_(div2), FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp)); DeviceValueType::UINT,
register_device_value(tag, &hc->daymidtemp, DeviceValueType::UINT, FL_(div2), FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp)); DeviceValueNumOp::DV_NUMOP_DIV2,
register_device_value(tag, &hc->daytemp, DeviceValueType::UINT, FL_(div2), FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp)); FL_(holidaytemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_holidaytemp));
register_device_value(
tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp2), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
register_device_value(
tag, &hc->daylowtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daylowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daylowtemp));
register_device_value(
tag, &hc->daymidtemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daymidtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daymidtemp));
register_device_value(
tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(dayhightemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
break; break;
case EMS_DEVICE_FLAG_RC30_N: case EMS_DEVICE_FLAG_RC30_N:
case EMS_DEVICE_FLAG_RC35: 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->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->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(
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp)); tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(daytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_daytemp));
register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, nullptr, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp)); register_device_value(
register_device_value(tag, &hc->offsettemp, DeviceValueType::INT, FL_(div2), FL_(offsettemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_offsettemp)); tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(nighttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nighttemp));
register_device_value(tag, &hc->holidaytemp, DeviceValueType::UINT, FL_(div2), FL_(holidaytemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_holidaytemp)); register_device_value(tag, &hc->designtemp, DeviceValueType::UINT, FL_(designtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_designtemp));
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, nullptr, FL_(targetflowtemp), DeviceValueUOM::DEGREES); register_device_value(tag,
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, nullptr, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25); &hc->offsettemp,
DeviceValueType::INT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(offsettemp),
DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_offsettemp));
register_device_value(tag,
&hc->holidaytemp,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(holidaytemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_holidaytemp));
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &hc->summertemp, DeviceValueType::UINT, FL_(summertemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_summertemp), 9, 25);
register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE); register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE);
register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL, nullptr, FL_(holidaymode), DeviceValueUOM::NONE); register_device_value(tag, &hc->holidaymode, DeviceValueType::BOOL, FL_(holidaymode), DeviceValueUOM::NONE);
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp)); register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp));
register_device_value( register_device_value(
tag, &hc->nofrostmode, DeviceValueType::ENUM, FL_(enum_nofrostmode), FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrostmode)); tag, &hc->nofrostmode, DeviceValueType::ENUM, FL_(enum_nofrostmode), FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrostmode));
register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, nullptr, FL_(roominfluence), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_roominfluence)); register_device_value(tag, &hc->roominfluence, DeviceValueType::UINT, FL_(roominfluence), DeviceValueUOM::DEGREES_R, 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->minflowtemp, DeviceValueType::UINT, 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->maxflowtemp, DeviceValueType::UINT, FL_(maxflowtemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_maxflowtemp));
register_device_value( register_device_value(tag, &hc->flowtempoffset, DeviceValueType::UINT, FL_(flowtempoffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_flowtempoffset));
tag, &hc->flowtempoffset, DeviceValueType::UINT, nullptr, FL_(flowtempoffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_flowtempoffset));
register_device_value( register_device_value(
tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype)); tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE, MAKE_CF_CB(set_heatingtype));
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->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode));
@@ -4151,16 +4227,28 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday)); register_device_value(tag, &hc->holiday, DeviceValueType::STRING, FL_(tpl_holidays), FL_(holidays), DeviceValueUOM::NONE, MAKE_CF_CB(set_holiday));
register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation)); register_device_value(tag, &hc->vacation, DeviceValueType::STRING, FL_(tpl_holidays), FL_(vacations), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacation));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode2), 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->pause, DeviceValueType::UINT, 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->party, DeviceValueType::UINT, 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,
register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, nullptr, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp)); &hc->tempautotemp,
register_device_value(tag, &hc->reducetemp, DeviceValueType::INT, nullptr, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp)); DeviceValueType::UINT,
register_device_value(tag, &hc->vacreducetemp, DeviceValueType::INT, nullptr, FL_(vacreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_vacreducetemp)); DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(tempautotemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_tempautotemp));
register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp));
register_device_value(tag, &hc->reducetemp, DeviceValueType::INT, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp));
register_device_value(tag, &hc->vacreducetemp, DeviceValueType::INT, FL_(vacreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_vacreducetemp));
register_device_value( register_device_value(
tag, &hc->vacreducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(vacreducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacreducemode)); tag, &hc->vacreducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(vacreducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_vacreducemode));
register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, FL_(div10), FL_(remotetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_remotetemp)); register_device_value(tag,
register_device_value(tag, &hc->wwprio, DeviceValueType::BOOL, nullptr, FL_(wwprio), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwprio)); &hc->remotetemp,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(remotetemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_remotetemp));
register_device_value(tag, &hc->wwprio, DeviceValueType::BOOL, FL_(wwprio), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwprio));
register_device_value( register_device_value(
tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1)); tag, &hc->switchtime1, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime1), DeviceValueUOM::NONE, MAKE_CF_CB(set_switchtime1));
register_device_value( register_device_value(
@@ -4169,13 +4257,21 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
case EMS_DEVICE_FLAG_JUNKERS: 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->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->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(
register_device_value(tag, &hc->nighttemp, DeviceValueType::UINT, FL_(div2), FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp)); tag, &hc->daytemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(heattemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heattemp));
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, FL_(div2), FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp)); register_device_value(
tag, &hc->nighttemp, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(ecotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ecotemp));
register_device_value(tag,
&hc->nofrosttemp,
DeviceValueType::INT,
DeviceValueNumOp::DV_NUMOP_DIV2,
FL_(nofrosttemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_nofrosttemp));
register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_j_control), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control)); register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_j_control), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode4), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode4), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, FL_(div10), FL_(remotetemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->remotetemp, DeviceValueType::SHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(remotetemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, nullptr, FL_(targetflowtemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, FL_(targetflowtemp), DeviceValueUOM::DEGREES);
break; break;
default: default:
break; break;

View File

@@ -51,6 +51,7 @@ std::string EMSdevice::tag_to_mqtt(uint8_t tag) {
return read_flash_string(DeviceValue::DeviceValueTAG_mqtt[tag]); return read_flash_string(DeviceValue::DeviceValueTAG_mqtt[tag]);
} }
// convert UOM to a string - these don't need translating
std::string EMSdevice::uom_to_string(uint8_t uom) { std::string EMSdevice::uom_to_string(uint8_t uom) {
if (EMSESP::system_.fahrenheit() && (uom == DeviceValueUOM::DEGREES || uom == DeviceValueUOM::DEGREES_R)) { if (EMSESP::system_.fahrenheit() && (uom == DeviceValueUOM::DEGREES || uom == DeviceValueUOM::DEGREES_R)) {
return read_flash_string(DeviceValue::DeviceValueUOM_s[DeviceValueUOM::FAHRENHEIT]); return read_flash_string(DeviceValue::DeviceValueUOM_s[DeviceValueUOM::FAHRENHEIT]);
@@ -107,7 +108,7 @@ std::string EMSdevice::device_type_2_device_name(const uint8_t device_type) {
case DeviceType::GATEWAY: case DeviceType::GATEWAY:
return read_flash_string(F_(gateway)); return read_flash_string(F_(gateway));
default: default:
return read_flash_string(F_(unknown)); return Helpers::translated_word(FL_(unknown));
} }
} }
@@ -258,7 +259,8 @@ bool EMSdevice::has_tag(const uint8_t tag) const {
// called from the command 'entities' // called from the command 'entities'
void EMSdevice::list_device_entries(JsonObject & output) const { void EMSdevice::list_device_entries(JsonObject & output) const {
for (const auto & dv : devicevalues_) { for (const auto & dv : devicevalues_) {
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.type != DeviceValueType::CMD && dv.full_name) { auto fullname = Helpers::translated_fword(dv.fullname);
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.type != DeviceValueType::CMD && fullname) {
// if we have a tag prefix it // if we have a tag prefix it
char key[50]; char key[50];
if (!EMSdevice::tag_to_mqtt(dv.tag).empty()) { if (!EMSdevice::tag_to_mqtt(dv.tag).empty()) {
@@ -270,7 +272,7 @@ void EMSdevice::list_device_entries(JsonObject & output) const {
JsonArray details = output.createNestedArray(key); JsonArray details = output.createNestedArray(key);
// add the full name description // add the full name description
details.add(dv.full_name); details.add(fullname);
// add uom // add uom
if (!uom_to_string(dv.uom).empty() && uom_to_string(dv.uom) != " ") { if (!uom_to_string(dv.uom).empty() && uom_to_string(dv.uom) != " ") {
@@ -386,23 +388,31 @@ void EMSdevice::register_telegram_type(const uint16_t telegram_type_id, const __
// tag: to be used to group mqtt together, either as separate topics as a nested object // tag: to be used to group mqtt together, either as separate topics as a nested object
// value_p: pointer to the value from the .h file // value_p: pointer to the value from the .h file
// type: one of DeviceValueType // type: one of DeviceValueType
// options: options for enum or a divider for int (e.g. F("10")) // options: options for enum, which are translated as a list of lists
// options_single: list of names
// numeric_operatpr: to divide or multiply, see DeviceValueNumOps::
// short_name: used in Mqtt as keys // short_name: used in Mqtt as keys
// full_name: used in Web and Console unless empty (nullptr) // fullname: used in Web and Console unless empty (nullptr) - can be translated
// uom: unit of measure from DeviceValueUOM // uom: unit of measure from DeviceValueUOM
// has_cmd: true if this is an associated command // has_cmd: true if this is an associated command
// min: min allowed value // min: min allowed value
// max: max allowed value // max: max allowed value
void EMSdevice::register_device_value(uint8_t tag, void EMSdevice::add_device_value(uint8_t tag,
void * value_p, void * value_p,
uint8_t type, uint8_t type,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
const __FlashStringHelper * short_name, const __FlashStringHelper * const * options_single,
const __FlashStringHelper * full_name, int8_t numeric_operator,
const __FlashStringHelper * const * name,
uint8_t uom, uint8_t uom,
bool has_cmd, const cmd_function_p f,
int16_t min, int16_t min,
uint16_t max) { uint16_t max) {
bool has_cmd = (f != nullptr);
auto short_name = name[0];
const class __FlashStringHelper * const * fullname = &name[1]; // translations start at index 1
// initialize the device value depending on it's type // initialize the device value depending on it's type
if (type == DeviceValueType::STRING) { if (type == DeviceValueType::STRING) {
*(char *)(value_p) = {'\0'}; // this is important for string functions like strlen() to work later *(char *)(value_p) = {'\0'}; // this is important for string functions like strlen() to work later
@@ -420,15 +430,6 @@ void EMSdevice::register_device_value(uint8_t tag,
*(uint8_t *)(value_p) = EMS_VALUE_UINT_NOTSET; // enums behave as uint8_t *(uint8_t *)(value_p) = EMS_VALUE_UINT_NOTSET; // enums behave as uint8_t
} }
// count #options
uint8_t options_size = 0;
if (options != nullptr) {
uint8_t i = 0;
while (options[i++]) {
options_size++;
}
}
// determine state // determine state
uint8_t state = DeviceValueState::DV_DEFAULT; uint8_t state = DeviceValueState::DV_DEFAULT;
@@ -448,28 +449,11 @@ void EMSdevice::register_device_value(uint8_t tag,
} }
}); });
// add the device // add the device entity
devicevalues_.emplace_back(device_type_, tag, value_p, type, options, options_size, short_name, full_name, uom, 0, has_cmd, min, max, state); devicevalues_.emplace_back(device_type_, tag, value_p, type, options, options_single, numeric_operator, short_name, fullname, uom, has_cmd, min, max, state);
}
// function with min and max values
// adds a new command to the command list
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,
const cmd_function_p f,
int16_t min,
uint16_t max) {
auto short_name = name[0];
auto full_name = name[1];
register_device_value(tag, value_p, type, options, short_name, full_name, uom, (f != nullptr), min, max);
// add a new command if it has a function attached // add a new command if it has a function attached
if (f == nullptr) { if (!has_cmd) {
return; return;
} }
@@ -484,29 +468,109 @@ void EMSdevice::register_device_value(uint8_t tag,
} }
// add the command to our library // add the command to our library
// cmd is the short_name and the description is the full_name // cmd is the short_name and the description is the fullname
Command::add(device_type_, short_name, f, full_name, flags); Command::add(device_type_, short_name, f, Helpers::translated_fword(fullname), flags);
}
// single list of options
void EMSdevice::register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const * options_single,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f) {
// create a multi-list from the options
add_device_value(tag, value_p, type, nullptr, options_single, 0, name, uom, f, 0, 0);
};
// single list of options, with no translations, with min and max
void EMSdevice::register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const * options_single,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max) {
// create a multi-list from the options
add_device_value(tag, value_p, type, nullptr, options_single, 0, name, uom, f, min, max);
};
void EMSdevice::register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
int8_t numeric_operator,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f) {
add_device_value(tag, value_p, type, nullptr, nullptr, numeric_operator, name, uom, f, 0, 0);
}
void EMSdevice::register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
int8_t numeric_operator,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max) {
add_device_value(tag, value_p, type, nullptr, nullptr, numeric_operator, name, uom, f, min, max);
}
// no options, no function
void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * name, uint8_t uom, const cmd_function_p f) {
add_device_value(tag, value_p, type, nullptr, nullptr, 0, name, uom, f, 0, 0);
};
// no options, with min/max
void EMSdevice::register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max) {
add_device_value(tag, value_p, type, nullptr, nullptr, 0, name, uom, f, min, max);
};
// function with min and max values
// adds a new command to the command list
// in this function we separate out the short and long names and take any translations
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,
const cmd_function_p f,
int16_t min,
uint16_t max) {
add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, f, min, max);
} }
// function with no min and max values (set to 0) // function with no min and max values (set to 0)
void EMSdevice::register_device_value(uint8_t tag, void EMSdevice::register_device_value(uint8_t tag,
void * value_p, void * value_p,
uint8_t type, uint8_t type,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
const __FlashStringHelper * const * name, const __FlashStringHelper * const * name,
uint8_t uom, uint8_t uom,
const cmd_function_p f) { const cmd_function_p f) {
register_device_value(tag, value_p, type, options, name, uom, f, 0, 0); add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, f, 0, 0);
} }
// no associated command function, or min/max values // no associated command function, or min/max values
void EMSdevice::register_device_value(uint8_t tag, void EMSdevice::register_device_value(uint8_t tag,
void * value_p, void * value_p,
uint8_t type, uint8_t type,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
const __FlashStringHelper * const * name, const __FlashStringHelper * const * name,
uint8_t uom) { uint8_t uom) {
register_device_value(tag, value_p, type, options, name, uom, nullptr, 0, 0); add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, nullptr, 0, 0);
} }
// check if value is readable via mqtt/api // check if value is readable via mqtt/api
@@ -572,7 +636,8 @@ void EMSdevice::publish_value(void * value_p) const {
snprintf(topic, sizeof(topic), "%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), read_flash_string(dv.short_name).c_str()); snprintf(topic, sizeof(topic), "%s/%s", Mqtt::tag_to_topic(device_type_, dv.tag).c_str(), read_flash_string(dv.short_name).c_str());
} }
int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0; int8_t num_op = dv.numeric_operator;
char payload[55] = {'\0'}; char payload[55] = {'\0'};
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
@@ -585,32 +650,32 @@ void EMSdevice::publish_value(void * value_p) const {
if (EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX) { if (EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX) {
Helpers::render_value(payload, *(uint8_t *)(value_p), 0); Helpers::render_value(payload, *(uint8_t *)(value_p), 0);
} else { } else {
strlcpy(payload, read_flash_string(dv.options[*(uint8_t *)(value_p)]).c_str(), sizeof(payload)); auto enum_str = Helpers::translated_word(dv.options[*(uint8_t *)(value_p)]);
strlcpy(payload, enum_str.c_str(), sizeof(payload));
} }
} }
break; break;
} }
case DeviceValueType::USHORT: case DeviceValueType::USHORT:
Helpers::render_value(payload, *(uint16_t *)(value_p), divider, fahrenheit); Helpers::render_value(payload, *(uint16_t *)(value_p), num_op, fahrenheit);
break; break;
case DeviceValueType::UINT: case DeviceValueType::UINT:
Helpers::render_value(payload, *(uint8_t *)(value_p), divider, fahrenheit); Helpers::render_value(payload, *(uint8_t *)(value_p), num_op, fahrenheit);
break; break;
case DeviceValueType::SHORT: case DeviceValueType::SHORT:
Helpers::render_value(payload, *(int16_t *)(value_p), divider, fahrenheit); Helpers::render_value(payload, *(int16_t *)(value_p), num_op, fahrenheit);
break; break;
case DeviceValueType::INT: case DeviceValueType::INT:
Helpers::render_value(payload, *(int8_t *)(value_p), divider, fahrenheit); Helpers::render_value(payload, *(int8_t *)(value_p), num_op, fahrenheit);
break; break;
case DeviceValueType::ULONG: case DeviceValueType::ULONG:
Helpers::render_value(payload, *(uint32_t *)(value_p), divider, fahrenheit); Helpers::render_value(payload, *(uint32_t *)(value_p), num_op, fahrenheit);
break; break;
case DeviceValueType::BOOL: { case DeviceValueType::BOOL:
Helpers::render_boolean(payload, (bool)*(uint8_t *)(value_p)); Helpers::render_boolean(payload, (bool)*(uint8_t *)(value_p));
break; break;
}
case DeviceValueType::TIME: case DeviceValueType::TIME:
Helpers::render_value(payload, *(uint32_t *)(value_p), divider); Helpers::render_value(payload, *(uint32_t *)(value_p), num_op);
break; break;
case DeviceValueType::STRING: case DeviceValueType::STRING:
if (Helpers::hasValue((char *)(value_p))) { if (Helpers::hasValue((char *)(value_p))) {
@@ -648,7 +713,8 @@ std::string EMSdevice::get_value_uom(const char * key) const {
// look up key in our device value list // look up key in our device value list
for (const auto & dv : devicevalues_) { for (const auto & dv : devicevalues_) {
if ((!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.full_name) && (read_flash_string(dv.full_name) == key_p)) { auto fullname = Helpers::translated_fword(dv.fullname);
if ((!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && fullname) && (read_flash_string(fullname) == key_p)) {
// ignore TIME since "minutes" is already added to the string value // ignore TIME since "minutes" is already added to the string value
if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) { if ((dv.uom == DeviceValueUOM::NONE) || (dv.uom == DeviceValueUOM::MINUTES)) {
break; break;
@@ -669,11 +735,13 @@ void EMSdevice::generate_values_web(JsonObject & output) {
JsonArray data = output.createNestedArray("data"); JsonArray data = output.createNestedArray("data");
for (auto & dv : devicevalues_) { for (auto & dv : devicevalues_) {
auto fullname = Helpers::translated_fword(dv.fullname);
// check conditions: // check conditions:
// 1. full_name cannot be empty // 1. fullname cannot be empty
// 2. it must have a valid value, if it is not a command like 'reset' // 2. it must have a valid value, if it is not a command like 'reset'
// 3. show favorites first // 3. show favorites first
if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && dv.full_name && (dv.hasValue() || (dv.type == DeviceValueType::CMD))) { if (!dv.has_state(DeviceValueState::DV_WEB_EXCLUDE) && fullname && (dv.hasValue() || (dv.type == DeviceValueType::CMD))) {
JsonObject obj = data.createNestedObject(); // create the object, we know there is a value JsonObject obj = data.createNestedObject(); // create the object, we know there is a value
uint8_t fahrenheit = 0; uint8_t fahrenheit = 0;
@@ -691,33 +759,28 @@ void EMSdevice::generate_values_web(JsonObject & output) {
// handle ENUMs // handle ENUMs
else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) { else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) {
obj["v"] = dv.options[*(uint8_t *)(dv.value_p)]; obj["v"] = Helpers::translated_word(dv.options[*(uint8_t *)(dv.value_p)]);
} }
// handle numbers // handle numbers
else { else {
// If a divider is specified, do the division to 2 decimals places and send back as double/float // note, the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
// otherwise force as an integer whole
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0;
fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) { if ((dv.type == DeviceValueType::INT) && Helpers::hasValue(*(int8_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(int8_t *)(dv.value_p), divider, fahrenheit); obj["v"] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
} else if ((dv.type == DeviceValueType::UINT) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) { } else if ((dv.type == DeviceValueType::UINT) && Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(uint8_t *)(dv.value_p), divider, fahrenheit); obj["v"] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
} else if ((dv.type == DeviceValueType::SHORT) && Helpers::hasValue(*(int16_t *)(dv.value_p))) { } else if ((dv.type == DeviceValueType::SHORT) && Helpers::hasValue(*(int16_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(int16_t *)(dv.value_p), divider, fahrenheit); obj["v"] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
} else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) { } else if ((dv.type == DeviceValueType::USHORT) && Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(uint16_t *)(dv.value_p), divider, fahrenheit); obj["v"] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
} else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { } else if ((dv.type == DeviceValueType::ULONG) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
obj["v"] = Helpers::round2(*(uint32_t *)(dv.value_p), divider, fahrenheit); obj["v"] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), dv.numeric_operator, fahrenheit);
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { } else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
uint32_t time_value = *(uint32_t *)(dv.value_p); obj["v"] = dv.numeric_operator ? (*(uint32_t *)(dv.value_p) / dv.numeric_operator) : *(uint32_t *)(dv.value_p);
obj["v"] = (divider > 0) ? time_value / divider : time_value; // sometimes we need to divide by 60
} else { } else {
// must have a value for sorting to work obj["v"] = ""; // must have a value for sorting to work
obj["v"] = "";
} }
} }
@@ -728,9 +791,9 @@ void EMSdevice::generate_values_web(JsonObject & output) {
// add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique // add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["id"] = mask + read_flash_string(dv.full_name); obj["id"] = mask + Helpers::translated_word(dv.fullname);
} else { } else {
obj["id"] = mask + tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name); obj["id"] = mask + tag_to_string(dv.tag) + " " + Helpers::translated_word(dv.fullname);
} }
// add commands and options // add commands and options
@@ -741,12 +804,14 @@ void EMSdevice::generate_values_web(JsonObject & output) {
} else { } else {
obj["c"] = dv.short_name; obj["c"] = dv.short_name;
} }
// add the Command options // add the Command options
if (dv.type == DeviceValueType::ENUM || (dv.type == DeviceValueType::CMD && dv.options_size > 1)) { if (dv.type == DeviceValueType::ENUM || (dv.type == DeviceValueType::CMD && dv.options_size > 1)) {
JsonArray l = obj.createNestedArray("l"); JsonArray l = obj.createNestedArray("l");
for (uint8_t i = 0; i < dv.options_size; i++) { for (uint8_t i = 0; i < dv.options_size; i++) {
if (!read_flash_string(dv.options[i]).empty()) { auto enum_str = Helpers::translated_word(dv.options[i]);
l.add(read_flash_string(dv.options[i])); if (!enum_str.empty()) {
l.add(enum_str);
} }
} }
} else if (dv.type == DeviceValueType::BOOL) { } else if (dv.type == DeviceValueType::BOOL) {
@@ -758,18 +823,19 @@ void EMSdevice::generate_values_web(JsonObject & output) {
// add command help template // add command help template
else if (dv.type == DeviceValueType::STRING || dv.type == DeviceValueType::CMD) { else if (dv.type == DeviceValueType::STRING || dv.type == DeviceValueType::CMD) {
if (dv.options_size == 1) { if (dv.options_size == 1) {
obj["h"] = dv.options[0]; obj["h"] = dv.options_single[0]; // NOT translated
} }
} }
// add steps to numeric values with divider/multiplier // handle INTs
// add steps to numeric values with numeric_operator
else { else {
int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0;
char s[10]; char s[10];
if (divider > 0) { if (dv.numeric_operator > 0) {
obj["s"] = Helpers::render_value(s, (float)1 / divider, 1); obj["s"] = Helpers::render_value(s, (float)1 / dv.numeric_operator, 1);
} else if (divider < 0) { } else if (dv.numeric_operator < 0) {
obj["s"] = Helpers::render_value(s, (-1) * divider, 0); obj["s"] = Helpers::render_value(s, (-1) * dv.numeric_operator, 0);
} }
int16_t dv_set_min, dv_set_max; int16_t dv_set_min, dv_set_max;
if (dv.get_min_max(dv_set_min, dv_set_max)) { if (dv.get_min_max(dv_set_min, dv_set_max)) {
obj["m"] = Helpers::render_value(s, dv_set_min, 0); obj["m"] = Helpers::render_value(s, dv_set_min, 0);
@@ -804,39 +870,45 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
// handle ENUMs // handle ENUMs
else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) { else if ((dv.type == DeviceValueType::ENUM) && (*(uint8_t *)(dv.value_p) < dv.options_size)) {
obj["v"] = dv.options[*(uint8_t *)(dv.value_p)]; obj["v"] = Helpers::translated_word(dv.options[*(uint8_t *)(dv.value_p)]);
} }
// handle Integers and Floats // handle Integers and Floats
else { else {
// If a divider is specified, do the division to 2 decimals places and send back as double/float int8_t num_op = dv.numeric_operator;
// otherwise force as an integer whole bool make_float;
// the nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler if (num_op == 0) {
uint8_t divider = 0; // no changes to number
uint8_t factor = 1; make_float = false;
if (dv.options_size == 1) { num_op = 1; // so it gets *1
auto s_str = read_flash_string(dv.options[0]); // prevent object backing the pointer will be destroyed at the end of the full-expression } else if (num_op < 0) {
const char * s = s_str.c_str(); // negative numbers, convert to a positive multiplier
if (s[0] == '*') { make_float = false;
factor = Helpers::atoint(&s[1]); num_op *= -1;
} else { } else {
divider = Helpers::atoint(s); // has a divider, make it a float
make_float = true;
} }
// always convert temperatures to floats with 1 decimal place
if ((dv.uom == DeviceValueUOM::DEGREES) || (dv.uom == DeviceValueUOM::DEGREES_R)) {
make_float = true;
} }
if (dv.type == DeviceValueType::INT) { if (dv.type == DeviceValueType::INT) {
obj["v"] = divider ? Helpers::round2(*(int8_t *)(dv.value_p), divider) : *(int8_t *)(dv.value_p) * factor; obj["v"] = make_float ? Helpers::transformNumFloat(*(int8_t *)(dv.value_p), num_op) : *(int8_t *)(dv.value_p) * num_op;
} else if (dv.type == DeviceValueType::UINT) { } else if (dv.type == DeviceValueType::UINT) {
obj["v"] = divider ? Helpers::round2(*(uint8_t *)(dv.value_p), divider) : *(uint8_t *)(dv.value_p) * factor; obj["v"] = make_float ? Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), num_op) : *(uint8_t *)(dv.value_p) * num_op;
} else if (dv.type == DeviceValueType::SHORT) { } else if (dv.type == DeviceValueType::SHORT) {
obj["v"] = divider ? Helpers::round2(*(int16_t *)(dv.value_p), divider) : *(int16_t *)(dv.value_p) * factor; obj["v"] = make_float ? Helpers::transformNumFloat(*(int16_t *)(dv.value_p), num_op) : *(int16_t *)(dv.value_p) * num_op;
} else if (dv.type == DeviceValueType::USHORT) { } else if (dv.type == DeviceValueType::USHORT) {
obj["v"] = divider ? Helpers::round2(*(uint16_t *)(dv.value_p), divider) : *(uint16_t *)(dv.value_p) * factor; obj["v"] = make_float ? Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), num_op) : *(uint16_t *)(dv.value_p) * num_op;
} else if (dv.type == DeviceValueType::ULONG) { } else if (dv.type == DeviceValueType::ULONG) {
obj["v"] = divider ? Helpers::round2(*(uint32_t *)(dv.value_p), divider) : *(uint32_t *)(dv.value_p) * factor; obj["v"] = make_float ? Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op) : *(uint32_t *)(dv.value_p) * num_op;
} else if (dv.type == DeviceValueType::TIME) { } else if (dv.type == DeviceValueType::TIME) {
uint32_t time_value = *(uint32_t *)(dv.value_p); // sometimes we need to divide by 60
obj["v"] = (divider > 0) ? time_value / divider : time_value * factor; // sometimes we need to divide by 60 obj["v"] = (num_op == DeviceValueNumOp::DV_NUMOP_DIV60) ? (uint32_t)Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op)
: *(uint32_t *)(dv.value_p);
} }
} }
} }
@@ -850,13 +922,14 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
// n is the fullname, and can be optional // n is the fullname, and can be optional
// don't add the fullname if its a command // don't add the fullname if its a command
auto translated_full_name = Helpers::translated_fword(dv.fullname);
if (dv.type != DeviceValueType::CMD) { if (dv.type != DeviceValueType::CMD) {
if (dv.full_name) { if (translated_full_name) {
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["n"] = dv.full_name; obj["n"] = read_flash_string(translated_full_name);
} else { } else {
char name[50]; char name[50];
snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(dv.full_name).c_str()); snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(translated_full_name).c_str());
obj["n"] = name; obj["n"] = name;
} }
} }
@@ -930,7 +1003,8 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
// search device value with this tag // search device value with this tag
for (auto & dv : devicevalues_) { for (auto & dv : devicevalues_) {
if (strcmp(command_s, Helpers::toLower(read_flash_string(dv.short_name)).c_str()) == 0 && (tag <= 0 || tag == dv.tag)) { if (strcmp(command_s, Helpers::toLower(read_flash_string(dv.short_name)).c_str()) == 0 && (tag <= 0 || tag == dv.tag)) {
int8_t divider = (dv.options_size == 1) ? Helpers::atoint(read_flash_string(dv.options[0]).c_str()) : 0; int8_t num_op = dv.numeric_operator;
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
const char * type = "type"; const char * type = "type";
@@ -938,12 +1012,12 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
json["name"] = dv.short_name; json["name"] = dv.short_name;
if (dv.full_name != nullptr) { auto fullname = Helpers::translated_fword(dv.fullname);
const char * fullname = "fullname"; if (fullname != nullptr) {
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) { if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
json[fullname] = dv.full_name; json["fullname"] = fullname;
} else { } else {
json[fullname] = tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name); json["fullname"] = tag_to_string(dv.tag) + " " + read_flash_string(fullname);
} }
} }
@@ -957,48 +1031,48 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
if (EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX) { if (EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX) {
json[value] = (uint8_t)(*(uint8_t *)(dv.value_p)); json[value] = (uint8_t)(*(uint8_t *)(dv.value_p));
} else { } else {
json[value] = dv.options[*(uint8_t *)(dv.value_p)]; // text json[value] = Helpers::translated_word(dv.options[*(uint8_t *)(dv.value_p)]); // text
} }
} }
json[type] = F_(enum); json[type] = F_(enum);
JsonArray enum_ = json.createNestedArray(F_(enum)); JsonArray enum_ = json.createNestedArray(F_(enum));
for (uint8_t i = 0; i < dv.options_size; i++) { for (uint8_t i = 0; i < dv.options_size; i++) {
enum_.add(dv.options[i]); enum_.add(Helpers::translated_word(dv.options[i]));
} }
break; break;
} }
case DeviceValueType::USHORT: case DeviceValueType::USHORT:
if (Helpers::hasValue(*(uint16_t *)(dv.value_p))) { if (Helpers::hasValue(*(uint16_t *)(dv.value_p))) {
json[value] = Helpers::round2(*(uint16_t *)(dv.value_p), divider, fahrenheit); json[value] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), num_op, fahrenheit);
} }
json[type] = F_(number); json[type] = F_(number);
break; break;
case DeviceValueType::UINT: case DeviceValueType::UINT:
if (Helpers::hasValue(*(uint8_t *)(dv.value_p))) { if (Helpers::hasValue(*(uint8_t *)(dv.value_p))) {
json[value] = Helpers::round2(*(uint8_t *)(dv.value_p), divider, fahrenheit); json[value] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), num_op, fahrenheit);
} }
json[type] = F_(number); json[type] = F_(number);
break; break;
case DeviceValueType::SHORT: case DeviceValueType::SHORT:
if (Helpers::hasValue(*(int16_t *)(dv.value_p))) { if (Helpers::hasValue(*(int16_t *)(dv.value_p))) {
json[value] = Helpers::round2(*(int16_t *)(dv.value_p), divider, fahrenheit); json[value] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), num_op, fahrenheit);
} }
json[type] = F_(number); json[type] = F_(number);
break; break;
case DeviceValueType::INT: case DeviceValueType::INT:
if (Helpers::hasValue(*(int8_t *)(dv.value_p))) { if (Helpers::hasValue(*(int8_t *)(dv.value_p))) {
json[value] = Helpers::round2(*(int8_t *)(dv.value_p), divider, fahrenheit); json[value] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), num_op, fahrenheit);
} }
json[type] = F_(number); json[type] = F_(number);
break; break;
case DeviceValueType::ULONG: case DeviceValueType::ULONG:
if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) { if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
json[value] = Helpers::round2(*(uint32_t *)(dv.value_p), divider); json[value] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op);
} }
json[type] = F_(number); json[type] = F_(number);
break; break;
@@ -1020,7 +1094,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
case DeviceValueType::TIME: case DeviceValueType::TIME:
if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) { if (Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
json[value] = Helpers::round2(*(uint32_t *)(dv.value_p), divider); json[value] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op);
} }
json[type] = F_(number); json[type] = F_(number);
break; break;
@@ -1037,13 +1111,13 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
if (dv.options_size > 1) { if (dv.options_size > 1) {
JsonArray enum_ = json.createNestedArray(F_(enum)); JsonArray enum_ = json.createNestedArray(F_(enum));
for (uint8_t i = 0; i < dv.options_size; i++) { for (uint8_t i = 0; i < dv.options_size; i++) {
enum_.add(dv.options[i]); enum_.add(Helpers::translated_word(dv.options[i]));
} }
} }
break; break;
default: default:
json[type] = F_(unknown); json[type] = Helpers::translated_word(FL_(unknown));
break; break;
} }
@@ -1122,12 +1196,14 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
dv.remove_state(DeviceValueState::DV_ACTIVE); dv.remove_state(DeviceValueState::DV_ACTIVE);
} }
auto fullname = Helpers::translated_fword(dv.fullname);
// check conditions: // check conditions:
// 1. it must have a valid value (state is active) // 1. it must have a valid value (state is active)
// 2. it must have a visible flag // 2. it must have a visible flag
// 3. it must match the given tag filter or have an empty tag // 3. it must match the given tag filter or have an empty tag
// 4. it must not have the exclude flag set or outputs to console // 4. it must not have the exclude flag set or outputs to console
if (dv.has_state(DeviceValueState::DV_ACTIVE) && dv.full_name && (tag_filter == DeviceValueTAG::TAG_NONE || tag_filter == dv.tag) if (dv.has_state(DeviceValueState::DV_ACTIVE) && fullname && (tag_filter == DeviceValueTAG::TAG_NONE || tag_filter == dv.tag)
&& (output_target == OUTPUT_TARGET::CONSOLE || !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE))) { && (output_target == OUTPUT_TARGET::CONSOLE || !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE))) {
has_values = true; // flagged if we actually have data has_values = true; // flagged if we actually have data
@@ -1136,11 +1212,12 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
// create the name for the JSON key // create the name for the JSON key
char name[80]; char name[80];
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) { if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
if (have_tag) { if (have_tag) {
snprintf(name, 80, "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(dv.full_name).c_str()); // prefix the tag snprintf(name, 80, "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(fullname).c_str()); // prefix the tag
} else { } else {
strlcpy(name, read_flash_string(dv.full_name).c_str(), sizeof(name)); // use full name strlcpy(name, read_flash_string(fullname).c_str(), sizeof(name)); // use full name
} }
} else { } else {
strlcpy(name, read_flash_string(dv.short_name).c_str(), sizeof(name)); // use short name strlcpy(name, read_flash_string(dv.short_name).c_str(), sizeof(name)); // use short name
@@ -1184,82 +1261,87 @@ bool EMSdevice::generate_values(JsonObject & output, const uint8_t tag_filter, c
if (EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX) { if (EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX) {
json[name] = (uint8_t)(*(uint8_t *)(dv.value_p)); json[name] = (uint8_t)(*(uint8_t *)(dv.value_p));
} else { } else {
json[name] = dv.options[*(uint8_t *)(dv.value_p)]; json[name] = Helpers::translated_word(dv.options[*(uint8_t *)(dv.value_p)]);
} }
} }
// handle Numbers // handle Numbers
// If a divider is specified, do the division to 2 decimals places and send back as double/float
// otherwise force as a whole integer
// note: the strange nested if's is necessary due to the way the ArduinoJson templates are pre-processed by the compiler
else { else {
// If a divider is specified, do the division to 2 decimals places and send back as double/float // fahrenheit, 0 is no conversion other 1 or 2. not sure why?
// otherwise force as an integer whole
uint8_t divider = 0;
uint8_t factor = 1;
if (dv.options_size == 1) {
auto s_str = read_flash_string(dv.options[0]); // prevent object backing the pointer will be destroyed at the end of the full-expression
const char * s = s_str.c_str();
if (s[0] == '*') {
factor = Helpers::atoint(&s[1]);
} else {
divider = Helpers::atoint(s);
}
}
// fahrenheit, 0 is no converstion other 1 or 2. not sure why?
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0
: (dv.uom == DeviceValueUOM::DEGREES) ? 2 : (dv.uom == DeviceValueUOM::DEGREES) ? 2
: (dv.uom == DeviceValueUOM::DEGREES_R) ? 1 : (dv.uom == DeviceValueUOM::DEGREES_R) ? 1
: 0; : 0;
int8_t num_op = dv.numeric_operator;
bool make_float;
if (num_op == 0) {
// no changes to number
make_float = false;
num_op = 1; // so it gets *1
} else if (num_op < 0) {
// negative numbers, convert to a positive multiplier
make_float = false;
num_op *= -1;
} else {
// has a divider, make it a float
make_float = true;
}
// always convert temperatures to floats with 1 decimal place // always convert temperatures to floats with 1 decimal place
bool make_float = (divider || (dv.uom == DeviceValueUOM::DEGREES) || (dv.uom == DeviceValueUOM::DEGREES_R)); if ((dv.uom == DeviceValueUOM::DEGREES) || (dv.uom == DeviceValueUOM::DEGREES_R)) {
make_float = true;
}
if (dv.type == DeviceValueType::INT) { if (dv.type == DeviceValueType::INT) {
if (make_float) { if (make_float) {
json[name] = Helpers::round2(*(int8_t *)(dv.value_p), divider, fahrenheit); json[name] = Helpers::transformNumFloat(*(int8_t *)(dv.value_p), num_op, fahrenheit);
} else { } else {
json[name] = *(int8_t *)(dv.value_p) * factor; json[name] = *(int8_t *)(dv.value_p) * num_op;
} }
} else if (dv.type == DeviceValueType::UINT) { } else if (dv.type == DeviceValueType::UINT) {
if (make_float) { if (make_float) {
json[name] = Helpers::round2(*(uint8_t *)(dv.value_p), divider, fahrenheit); json[name] = Helpers::transformNumFloat(*(uint8_t *)(dv.value_p), num_op, fahrenheit);
} else { } else {
json[name] = *(uint8_t *)(dv.value_p) * factor; json[name] = *(uint8_t *)(dv.value_p) * num_op;
} }
} else if (dv.type == DeviceValueType::SHORT) { } else if (dv.type == DeviceValueType::SHORT) {
if (make_float) { if (make_float) {
json[name] = Helpers::round2(*(int16_t *)(dv.value_p), divider, fahrenheit); json[name] = Helpers::transformNumFloat(*(int16_t *)(dv.value_p), num_op, fahrenheit);
} else { } else {
json[name] = *(int16_t *)(dv.value_p) * factor; json[name] = *(int16_t *)(dv.value_p) * num_op;
} }
} else if (dv.type == DeviceValueType::USHORT) { } else if (dv.type == DeviceValueType::USHORT) {
if (make_float) { if (make_float) {
json[name] = Helpers::round2(*(uint16_t *)(dv.value_p), divider, fahrenheit); json[name] = Helpers::transformNumFloat(*(uint16_t *)(dv.value_p), num_op, fahrenheit);
} else { } else {
json[name] = *(uint16_t *)(dv.value_p) * factor; json[name] = *(uint16_t *)(dv.value_p) * num_op;
} }
} else if (dv.type == DeviceValueType::ULONG) { } else if (dv.type == DeviceValueType::ULONG) {
if (make_float) { if (make_float) {
json[name] = Helpers::round2(*(uint32_t *)(dv.value_p), divider, fahrenheit); json[name] = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op, fahrenheit);
} else { } else {
json[name] = *(uint32_t *)(dv.value_p) * factor; json[name] = *(uint32_t *)(dv.value_p) * num_op;
} }
} else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) { } else if ((dv.type == DeviceValueType::TIME) && Helpers::hasValue(*(uint32_t *)(dv.value_p))) {
uint32_t time_value = *(uint32_t *)(dv.value_p); uint32_t time_value;
time_value = Helpers::round2(time_value, divider); // sometimes we need to divide by 60 if (num_op == DeviceValueNumOp::DV_NUMOP_DIV60) {
// sometimes we need to divide by 60
time_value = Helpers::transformNumFloat(*(uint32_t *)(dv.value_p), num_op);
} else {
time_value = *(uint32_t *)(dv.value_p);
}
if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) { if (output_target == OUTPUT_TARGET::API_VERBOSE || output_target == OUTPUT_TARGET::CONSOLE) {
char time_s[40]; char time_s[60];
snprintf(time_s, snprintf(time_s,
sizeof(time_s), sizeof(time_s),
"%d %s %d %s %d %s", "%d %s %d %s %d %s",
(time_value / 1440), (time_value / 1440),
read_flash_string(F_(days)).c_str(), Helpers::translated_word(FL_(days)).c_str(),
((time_value % 1440) / 60), ((time_value % 1440) / 60),
read_flash_string(F_(hours)).c_str(), Helpers::translated_word(FL_(hours)).c_str(),
(time_value % 60), (time_value % 60),
read_flash_string(F_(minutes)).c_str()); Helpers::translated_word(FL_(minutes)).c_str());
json[name] = time_s; json[name] = time_s;
} else { } else {
json[name] = time_value; json[name] = time_value;

View File

@@ -204,21 +204,12 @@ class EMSdevice {
void generate_values_web(JsonObject & output); void generate_values_web(JsonObject & output);
void generate_values_web_customization(JsonArray & output); void generate_values_web_customization(JsonArray & output);
void register_device_value(uint8_t tag, void add_device_value(uint8_t tag,
void * value_p, void * value_p,
uint8_t type, uint8_t type,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
const __FlashStringHelper * short_name, const __FlashStringHelper * const * options_single,
const __FlashStringHelper * full_name, int8_t numeric_operator,
uint8_t uom,
bool has_cmd,
int16_t min,
uint16_t max);
void register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const * options,
const __FlashStringHelper * const * name, const __FlashStringHelper * const * name,
uint8_t uom, uint8_t uom,
const cmd_function_p f, const cmd_function_p f,
@@ -228,7 +219,17 @@ class EMSdevice {
void register_device_value(uint8_t tag, void register_device_value(uint8_t tag,
void * value_p, void * value_p,
uint8_t type, uint8_t type,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
void register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const ** options,
const __FlashStringHelper * const * name, const __FlashStringHelper * const * name,
uint8_t uom, uint8_t uom,
const cmd_function_p f); const cmd_function_p f);
@@ -236,10 +237,61 @@ class EMSdevice {
void register_device_value(uint8_t tag, void register_device_value(uint8_t tag,
void * value_p, void * value_p,
uint8_t type, uint8_t type,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
const __FlashStringHelper * const * name, const __FlashStringHelper * const * name,
uint8_t uom); uint8_t uom);
void register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
int8_t numeric_operator,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f = nullptr);
void register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
int8_t numeric_operator,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
// single list of options
void register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const * options_single,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f = nullptr);
// single list of options, with no translations, with min and max
void register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const * options_single,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
// no options, optional function f
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * name, uint8_t uom, const cmd_function_p f = nullptr);
// no options, with min/max
void register_device_value(uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const * name,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
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) const; 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) const;
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid) const; void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid) const;
void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value) const; void write_command(const uint16_t type_id, const uint8_t offset, const uint8_t value) const;
@@ -390,10 +442,13 @@ class EMSdevice {
} }
}; };
#ifdef EMSESP_STANDALONE
void debug_print_dv(const char * shortname);
#endif
std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types std::vector<TelegramFunction> telegram_functions_; // each EMS device has its own set of registered telegram types
// device values std::vector<DeviceValue> devicevalues_; // all the device values
std::vector<DeviceValue> devicevalues_;
std::vector<uint16_t> handlers_ignored_; std::vector<uint16_t> handlers_ignored_;
}; };

View File

@@ -22,30 +22,97 @@
namespace emsesp { namespace emsesp {
// constructor
DeviceValue::DeviceValue(uint8_t device_type,
uint8_t tag,
void * value_p,
uint8_t type,
const __FlashStringHelper * const ** options,
const __FlashStringHelper * const * options_single,
int8_t numeric_operator,
const __FlashStringHelper * const short_name,
const __FlashStringHelper * const * fullname,
uint8_t uom,
bool has_cmd,
int16_t min,
uint16_t max,
uint8_t state)
: device_type(device_type)
, tag(tag)
, value_p(value_p)
, type(type)
, options(options)
, options_single(options_single)
, numeric_operator(numeric_operator)
, short_name(short_name)
, fullname(fullname)
, uom(uom)
, has_cmd(has_cmd)
, min(min)
, max(max)
, state(state) {
// calculate #options in options list
if (options_single) {
options_size = 1;
} else {
options_size = Helpers::count_items(options);
}
#ifdef EMSESP_STANDALONE
// only added for debugging
Serial.print("registering entity: ");
Serial.print(read_flash_string(short_name).c_str());
Serial.print("/");
auto trans_fullname = Helpers::translated_word(fullname);
Serial.print(trans_fullname.c_str());
Serial.print(" (#options=");
Serial.print(options_size);
Serial.print(",numop=");
Serial.print(numeric_operator);
Serial.print(") ");
if (options != nullptr) {
uint8_t i = 0;
while (i < options_size) {
Serial.print(" option");
Serial.print(i + 1);
Serial.print(":");
auto str = Helpers::translated_fword(options[i]);
Serial.print(read_flash_string(str).c_str());
i++;
}
} else if (options_single != nullptr) {
Serial.print("option1:!");
Serial.print(read_flash_string(options_single[0]).c_str());
Serial.print("!");
}
Serial.println("");
#endif
}
// mapping of UOM, to match order in DeviceValueUOM enum emsdevice.h // mapping of UOM, to match order in DeviceValueUOM enum emsdevice.h
// also maps to DeviceValueUOM in interface/src/project/types.ts for the Web UI // also maps to DeviceValueUOM in interface/src/project/types.ts for the Web UI
// must be an int of 4 bytes, 32bit aligned // must be an int of 4 bytes, 32bit aligned
const __FlashStringHelper * DeviceValue::DeviceValueUOM_s[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = { const __FlashStringHelper * DeviceValue::DeviceValueUOM_s[] __attribute__((__aligned__(sizeof(uint32_t)))) PROGMEM = {
F_(blank), F_(uom_blank),
F_(degrees), F_(uom_degrees),
F_(degrees), F_(uom_degrees),
F_(percent), F_(uom_percent),
F_(lmin), F_(uom_lmin),
F_(kwh), F_(uom_kwh),
F_(wh), F_(uom_wh),
F_(hours), F_(uom_hours),
F_(minutes), F_(uom_minutes),
F_(ua), F_(uom_ua),
F_(bar), F_(uom_bar),
F_(kw), F_(uom_kw),
F_(w), F_(uom_w),
F_(kb), F_(uom_kb),
F_(seconds), F_(uom_seconds),
F_(dbm), F_(uom_dbm),
F_(fahrenheit), F_(uom_fahrenheit),
F_(mv), F_(uom_mv),
F_(sqm) F_(uom_sqm)
}; };
@@ -196,10 +263,10 @@ bool DeviceValue::get_min_max(int16_t & dv_set_min, int16_t & dv_set_max) {
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0; uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
// if we have individual limits set already, just do the conversion // if we have individual limits set already, just do the conversion
// limits are not scaled with divider and temperatures are °C // limits are not scaled with num operator and temperatures are °C
if (min != 0 || max != 0) { if (min != 0 || max != 0) {
dv_set_min = Helpers::round2(min, 0, fahrenheit); dv_set_min = Helpers::transformNumFloat(min, 0, fahrenheit);
dv_set_max = Helpers::round2(max, 0, fahrenheit); dv_set_max = Helpers::transformNumFloat(max, 0, fahrenheit);
return true; return true;
} }
@@ -207,17 +274,15 @@ bool DeviceValue::get_min_max(int16_t & dv_set_min, int16_t & dv_set_max) {
dv_set_min = 0; dv_set_min = 0;
dv_set_max = 0; dv_set_max = 0;
int8_t divider = (options_size == 1) ? Helpers::atoint(uuid::read_flash_string(options[0]).c_str()) : 0;
if (type == DeviceValueType::USHORT) { if (type == DeviceValueType::USHORT) {
dv_set_min = Helpers::round2(0, divider, fahrenheit); dv_set_min = Helpers::transformNumFloat(0, numeric_operator, fahrenheit);
dv_set_max = Helpers::round2(EMS_VALUE_USHORT_NOTSET, divider, fahrenheit); dv_set_max = Helpers::transformNumFloat(EMS_VALUE_USHORT_NOTSET, numeric_operator, fahrenheit);
return true; return true;
} }
if (type == DeviceValueType::SHORT) { if (type == DeviceValueType::SHORT) {
dv_set_min = Helpers::round2(-EMS_VALUE_SHORT_NOTSET, divider, fahrenheit); dv_set_min = Helpers::transformNumFloat(-EMS_VALUE_SHORT_NOTSET, numeric_operator, fahrenheit);
dv_set_max = Helpers::round2(EMS_VALUE_SHORT_NOTSET, divider, fahrenheit); dv_set_max = Helpers::transformNumFloat(EMS_VALUE_SHORT_NOTSET, numeric_operator, fahrenheit);
return true; return true;
} }
@@ -225,7 +290,7 @@ bool DeviceValue::get_min_max(int16_t & dv_set_min, int16_t & dv_set_max) {
if (uom == DeviceValueUOM::PERCENT) { if (uom == DeviceValueUOM::PERCENT) {
dv_set_max = 100; dv_set_max = 100;
} else { } else {
dv_set_max = Helpers::round2(EMS_VALUE_UINT_NOTSET, divider, fahrenheit); dv_set_max = Helpers::transformNumFloat(EMS_VALUE_UINT_NOTSET, numeric_operator, fahrenheit);
} }
return true; return true;
} }
@@ -235,19 +300,19 @@ bool DeviceValue::get_min_max(int16_t & dv_set_min, int16_t & dv_set_max) {
dv_set_min = -100; dv_set_min = -100;
dv_set_max = 100; dv_set_max = 100;
} else { } else {
dv_set_min = Helpers::round2(-EMS_VALUE_INT_NOTSET, divider, fahrenheit); dv_set_min = Helpers::transformNumFloat(-EMS_VALUE_INT_NOTSET, numeric_operator, fahrenheit);
dv_set_max = Helpers::round2(EMS_VALUE_INT_NOTSET, divider, fahrenheit); dv_set_max = Helpers::transformNumFloat(EMS_VALUE_INT_NOTSET, numeric_operator, fahrenheit);
} }
return true; return true;
} }
if (type == DeviceValueType::ULONG) { if (type == DeviceValueType::ULONG) {
dv_set_max = Helpers::round2(EMS_VALUE_ULONG_NOTSET, divider); dv_set_max = Helpers::transformNumFloat(EMS_VALUE_ULONG_NOTSET, numeric_operator);
return true; return true;
} }
if (type == DeviceValueType::TIME) { if (type == DeviceValueType::TIME) {
dv_set_max = Helpers::round2(EMS_VALUE_ULONG_NOTSET, divider); dv_set_max = Helpers::transformNumFloat(EMS_VALUE_ULONG_NOTSET, numeric_operator);
return true; return true;
} }

View File

@@ -130,16 +130,30 @@ class DeviceValue {
DV_FAVORITE = (1 << 7) // 128 - sort to front DV_FAVORITE = (1 << 7) // 128 - sort to front
}; };
// numeric operators
// negative numbers used for multipliers
enum DeviceValueNumOp : int8_t {
DV_NUMOP_NONE = 0, // default
DV_NUMOP_DIV2 = 2,
DV_NUMOP_DIV10 = 10,
DV_NUMOP_DIV60 = 60,
DV_NUMOP_DIV100 = 100,
DV_NUMOP_MUL5 = -5,
DV_NUMOP_MUL10 = -10,
DV_NUMOP_MUL15 = -15
};
uint8_t device_type; // EMSdevice::DeviceType uint8_t device_type; // EMSdevice::DeviceType
uint8_t tag; // DeviceValueTAG::* uint8_t tag; // DeviceValueTAG::*
void * value_p; // pointer to variable of any type void * value_p; // pointer to variable of any type
uint8_t type; // DeviceValueType::* uint8_t type; // DeviceValueType::*
const __FlashStringHelper * const * options; // options as a flash char array const __FlashStringHelper * const ** options; // options as a flash char array
const __FlashStringHelper * const * options_single; // options are not translated
int8_t numeric_operator;
uint8_t options_size; // number of options in the char array, calculated uint8_t options_size; // number of options in the char array, calculated
const __FlashStringHelper * short_name; // used in MQTT const __FlashStringHelper * const short_name; // used in MQTT and API
const __FlashStringHelper * full_name; // used in Web and Console const __FlashStringHelper * const * fullname; // used in Web and Console, is translated
uint8_t uom; // DeviceValueUOM::* uint8_t uom; // DeviceValueUOM::*
uint8_t ha; // DevcieValueHA::
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
int16_t min; // min range int16_t min; // min range
uint16_t max; // max range uint16_t max; // max range
@@ -149,36 +163,21 @@ class DeviceValue {
uint8_t tag, uint8_t tag,
void * value_p, void * value_p,
uint8_t type, uint8_t type,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
uint8_t options_size, const __FlashStringHelper * const * options_single,
const __FlashStringHelper * short_name, int8_t numeric_operator,
const __FlashStringHelper * full_name, const __FlashStringHelper * const short_name,
const __FlashStringHelper * const * fullname,
uint8_t uom, uint8_t uom,
uint8_t ha,
bool has_cmd, bool has_cmd,
int16_t min, int16_t min,
uint16_t max, uint16_t max,
uint8_t state) uint8_t state);
: device_type(device_type)
, tag(tag)
, value_p(value_p)
, type(type)
, options(options)
, options_size(options_size)
, short_name(short_name)
, full_name(full_name)
, uom(uom)
, ha(ha)
, has_cmd(has_cmd)
, min(min)
, max(max)
, state(state) {
}
bool hasValue() const; bool hasValue() const;
bool get_min_max(int16_t & dv_set_min, int16_t & dv_set_max); bool get_min_max(int16_t & dv_set_min, int16_t & dv_set_max);
// state flags // dv state flags
void add_state(uint8_t s) { void add_state(uint8_t s) {
state |= s; state |= s;
} }

View File

@@ -299,7 +299,6 @@ void EMSESP::show_ems(uuid::console::Shell & shell) {
} }
// show EMS device values to the shell console // show EMS device values to the shell console
// generate_values_json is called in verbose mode
void EMSESP::show_device_values(uuid::console::Shell & shell) { void EMSESP::show_device_values(uuid::console::Shell & shell) {
if (emsdevices.empty()) { if (emsdevices.empty()) {
shell.printfln(F("No EMS devices detected.")); shell.printfln(F("No EMS devices detected."));
@@ -317,7 +316,7 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) {
DynamicJsonDocument doc(EMSESP_JSON_SIZE_XXLARGE_DYN); // use max size DynamicJsonDocument doc(EMSESP_JSON_SIZE_XXLARGE_DYN); // use max size
JsonObject json = doc.to<JsonObject>(); JsonObject json = doc.to<JsonObject>();
emsdevice->generate_values(json, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::CONSOLE); // verbose mode and nested emsdevice->generate_values(json, DeviceValueTAG::TAG_NONE, true, EMSdevice::OUTPUT_TARGET::CONSOLE);
// print line // print line
uint8_t id = 0; uint8_t id = 0;
@@ -334,7 +333,7 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) {
char s[10]; char s[10];
shell.print(Helpers::render_value(s, data.as<float>(), 1)); shell.print(Helpers::render_value(s, data.as<float>(), 1));
} else if (data.is<bool>()) { } else if (data.is<bool>()) {
shell.print(data.as<bool>() ? F_(on) : F_(off)); shell.print(data.as<bool>() ? Helpers::translated_word(FL_(on)) : Helpers::translated_word(FL_(off)));
} }
// if there is a uom print it // if there is a uom print it
@@ -488,6 +487,8 @@ void EMSESP::reset_mqtt_ha() {
for (const auto & emsdevice : emsdevices) { for (const auto & emsdevice : emsdevices) {
emsdevice->ha_config_clear(); emsdevice->ha_config_clear();
} }
// force the re-creating of the dallas and analog sensor topics (for HA)
dallassensor_.reload(); dallassensor_.reload();
analogsensor_.reload(); analogsensor_.reload();
} }
@@ -1291,11 +1292,16 @@ void EMSESP::start() {
esp8266React.begin(); // loads core system services settings (network, mqtt, ap, ntp etc) esp8266React.begin(); // loads core system services settings (network, mqtt, ap, ntp etc)
webLogService.begin(); // start web log service. now we can start capturing logs to the web log webLogService.begin(); // start web log service. now we can start capturing logs to the web log
#ifdef EMSESP_DEBUG
LOG_NOTICE(F("System is running in Debug mode"));
#endif
LOG_INFO(F("Last system reset reason Core0: %s, Core1: %s"), system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str()); LOG_INFO(F("Last system reset reason Core0: %s, Core1: %s"), system_.reset_reason(0).c_str(), system_.reset_reason(1).c_str());
// do any system upgrades // do any system upgrades
if (system_.check_upgrade()) { if (system_.check_upgrade()) {
LOG_INFO(F("System will be restarted to apply upgrade")); LOG_INFO(F("System needs a restart to apply new settings. Please wait."));
system_.system_restart(); system_.system_restart();
}; };

View File

@@ -92,6 +92,8 @@ using DeviceValueUOM = emsesp::DeviceValue::DeviceValueUOM;
using DeviceValueType = emsesp::DeviceValue::DeviceValueType; using DeviceValueType = emsesp::DeviceValue::DeviceValueType;
using DeviceValueState = emsesp::DeviceValue::DeviceValueState; using DeviceValueState = emsesp::DeviceValue::DeviceValueState;
using DeviceValueTAG = emsesp::DeviceValue::DeviceValueTAG; using DeviceValueTAG = emsesp::DeviceValue::DeviceValueTAG;
using DeviceValueNumOp = emsesp::DeviceValue::DeviceValueNumOp;
class Shower; // forward declaration for compiler class Shower; // forward declaration for compiler

View File

@@ -177,10 +177,11 @@ char * Helpers::smallitoa(char * result, const uint16_t value) {
// for strings only // for strings only
char * Helpers::render_boolean(char * result, const bool value, const bool dashboard) { char * Helpers::render_boolean(char * result, const bool value, const bool dashboard) {
uint8_t bool_format_ = dashboard ? EMSESP::system_.bool_dashboard() : EMSESP::system_.bool_format(); uint8_t bool_format_ = dashboard ? EMSESP::system_.bool_dashboard() : EMSESP::system_.bool_format();
if (bool_format_ == BOOL_FORMAT_ONOFF_STR) { if (bool_format_ == BOOL_FORMAT_ONOFF_STR) {
strlcpy(result, value ? read_flash_string(F_(on)).c_str() : read_flash_string(F_(off)).c_str(), 5); strlcpy(result, value ? translated_word(FL_(on)).c_str() : translated_word(FL_(off)).c_str(), 5);
} else if (bool_format_ == BOOL_FORMAT_ONOFF_STR_CAP) { } else if (bool_format_ == BOOL_FORMAT_ONOFF_STR_CAP) {
strlcpy(result, value ? read_flash_string(F_(ON)).c_str() : read_flash_string(F_(OFF)).c_str(), 5); strlcpy(result, value ? translated_word(FL_(ON)).c_str() : translated_word(FL_(OFF)).c_str(), 5);
} else if ((bool_format_ == BOOL_FORMAT_10) || (bool_format_ == BOOL_FORMAT_10_STR)) { } else if ((bool_format_ == BOOL_FORMAT_10) || (bool_format_ == BOOL_FORMAT_10_STR)) {
strlcpy(result, value ? "1" : "0", 2); strlcpy(result, value ? "1" : "0", 2);
} else { } else {
@@ -439,17 +440,41 @@ int Helpers::atoint(const char * value) {
// The conversion to Fahrenheit is different for absolute temperatures and relative temperatures like hysteresis. // The conversion to Fahrenheit is different for absolute temperatures and relative temperatures like hysteresis.
// fahrenheit=0 - off, no conversion // fahrenheit=0 - off, no conversion
// fahrenheit=1 - relative, 1.8t // fahrenheit=1 - relative, 1.8t
// fahrenheit=2 - absolute, 1.8t + 32(fahrenheit-1). // fahrenheit=2 - absolute, 1.8t + 32(fahrenheit-1)
float Helpers::round2(float value, const int8_t divider, const uint8_t fahrenheit) { float Helpers::transformNumFloat(float value, const int8_t numeric_operator, const uint8_t fahrenheit) {
float val = (value * 100 + 0.5); float val;
if (divider > 0) {
val = ((value / divider) * 100 + 0.5); switch (numeric_operator) {
} else if (divider < 0) { case DeviceValueNumOp::DV_NUMOP_DIV2:
val = value * -100 * divider; val = ((value / 2) * 100 + 0.5);
break;
case DeviceValueNumOp::DV_NUMOP_DIV10:
val = ((value / 10) * 100 + 0.5);
break;
case DeviceValueNumOp::DV_NUMOP_DIV60:
val = ((value / 60) * 100 + 0.5);
break;
case DeviceValueNumOp::DV_NUMOP_DIV100:
val = ((value / 100) * 100 + 0.5);
break;
case DeviceValueNumOp::DV_NUMOP_MUL5:
val = value * -100 * 5;
break;
case DeviceValueNumOp::DV_NUMOP_MUL10:
val = value * -100 * 10;
break;
case DeviceValueNumOp::DV_NUMOP_MUL15:
val = value * -100 * 15;
break;
default:
val = (value * 100 + 0.5); // no ops
break;
} }
if (value < 0) { // negative rounding if (value < 0) { // negative rounding
val = val - 1; val = val - 1;
} }
if (fahrenheit) { if (fahrenheit) {
val = val * 1.8 + 3200 * (fahrenheit - 1); val = val * 1.8 + 3200 * (fahrenheit - 1);
} }
@@ -568,12 +593,12 @@ bool Helpers::value2bool(const char * value, bool & value_b) {
std::string bool_str = toLower(value); // convert to lower case std::string bool_str = toLower(value); // convert to lower case
if ((bool_str == read_flash_string(F_(on))) || (bool_str == "1") || (bool_str == "true")) { if ((bool_str == Helpers::translated_word(FL_(on))) || (bool_str == "1") || (bool_str == "true")) {
value_b = true; value_b = true;
return true; // is a bool return true; // is a bool
} }
if ((bool_str == read_flash_string(F_(off))) || (bool_str == "0") || (bool_str == "false")) { if ((bool_str == Helpers::translated_word(FL_(off))) || (bool_str == "0") || (bool_str == "false")) {
value_b = false; value_b = false;
return true; // is a bool return true; // is a bool
} }
@@ -581,6 +606,26 @@ bool Helpers::value2bool(const char * value, bool & value_b) {
return false; // not a bool return false; // not a bool
} }
// checks to see if a string is member of a vector and return the index, also allow true/false for on/off
// this for a list of lists, when using translated strings
bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const ** strs) {
if ((value == nullptr) || (strlen(value) == 0)) {
return false;
}
std::string str = toLower(value);
for (value_ui = 0; strs[value_ui]; value_ui++) {
std::string str1 = toLower(Helpers::translated_word(strs[value_ui]));
if ((str1 != "")
&& ((str1 == Helpers::translated_word(FL_(off)) && str == "false") || (str1 == Helpers::translated_word(FL_(on)) && str == "true") || (str == str1)
|| (value[0] == ('0' + value_ui) && value[1] == '\0'))) {
return true;
}
}
return false;
}
// checks to see if a string is member of a vector and return the index, also allow true/false for on/off // checks to see if a string is member of a vector and return the index, also allow true/false for on/off
bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const * strs) { bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const * strs) {
if ((value == nullptr) || (strlen(value) == 0)) { if ((value == nullptr) || (strlen(value) == 0)) {
@@ -589,13 +634,15 @@ bool Helpers::value2enum(const char * value, uint8_t & value_ui, const __FlashSt
std::string str = toLower(value); std::string str = toLower(value);
for (value_ui = 0; strs[value_ui]; value_ui++) { for (value_ui = 0; strs[value_ui]; value_ui++) {
std::string str1 = toLower(read_flash_string(strs[value_ui])); std::string enum_str = toLower(read_flash_string(strs[value_ui]));
if ((str1 != "")
&& ((str1 == read_flash_string(F_(off)) && str == "false") || (str1 == read_flash_string(F_(on)) && str == "true") || (str == str1) if ((enum_str != "")
|| (value[0] == ('0' + value_ui) && value[1] == '\0'))) { && ((enum_str == Helpers::translated_word(FL_(off)) && str == "false") || (enum_str == Helpers::translated_word(FL_(on)) && str == "true")
|| (str == enum_str) || (value[0] == ('0' + value_ui) && value[1] == '\0'))) {
return true; return true;
} }
} }
return false; return false;
} }
@@ -617,7 +664,7 @@ void Helpers::replace_char(char * str, char find, char replace) {
int i = 0; int i = 0;
while (str[i] != '\0') { while (str[i] != '\0') {
/*Replace the matched character...*/ // Replace the matched character...
if (str[i] == find) if (str[i] == find)
str[i] = replace; str[i] = replace;
@@ -625,4 +672,55 @@ void Helpers::replace_char(char * str, char find, char replace) {
} }
} }
// count number of items in a list
// the end of a list has a nullptr
uint8_t Helpers::count_items(const __FlashStringHelper * const * list) {
uint8_t list_size = 0;
if (list != nullptr) {
while (list[list_size]) {
list_size++;
}
}
return list_size;
}
// count number of items in a list of lists
// the end of a list has a nullptr
uint8_t Helpers::count_items(const __FlashStringHelper * const ** list) {
uint8_t list_size = 0;
if (list != nullptr) {
while (list[list_size]) {
list_size++;
}
}
return list_size;
}
// return translated string as a std::string, optionally converting to lowercase (for console commands)
// takes a FL(...)
std::string Helpers::translated_word(const __FlashStringHelper * const * strings, bool to_lower) {
uint8_t language_index = EMSESP::system_.language_index();
uint8_t index = 0;
// see how many translations we have for this entity. if there is no translation for this, revert to EN
if (Helpers::count_items(strings) >= language_index + 1) {
index = language_index;
}
return to_lower ? toLower(read_flash_string(strings[index])) : read_flash_string(strings[index]);
}
// return translated string
// takes a F(...)
const __FlashStringHelper * Helpers::translated_fword(const __FlashStringHelper * const * strings) {
uint8_t language_index = EMSESP::system_.language_index();
uint8_t index = 0;
// see how many translations we have for this entity. if there is no translation for this, revert to EN
if (Helpers::count_items(strings) >= language_index + 1) {
index = language_index;
}
return strings[index];
}
} // namespace emsesp } // namespace emsesp

View File

@@ -21,13 +21,10 @@
#include "telegram.h" // for EMS_VALUE_* settings #include "telegram.h" // for EMS_VALUE_* settings
#define FJSON(x) x #include "common.h"
// #define FJSON(x) F(x)
namespace emsesp { namespace emsesp {
using flash_string_vector = std::vector<const __FlashStringHelper *>;
class Helpers { class Helpers {
public: public:
static char * render_value(char * result, const float value, const int8_t format); // format is the precision static char * render_value(char * result, const float value, const int8_t format); // format is the precision
@@ -52,7 +49,9 @@ class Helpers {
static int atoint(const char * value); static int atoint(const char * value);
static bool check_abs(const int32_t i); static bool check_abs(const int32_t i);
static uint32_t abs(const int32_t i); static uint32_t abs(const int32_t i);
static float round2(float value, const int8_t divider, const uint8_t fahrenheit = 0);
static float transformNumFloat(float value, const int8_t numeric_operator, const uint8_t fahrenheit = 0);
static std::string toLower(std::string const & s); static std::string toLower(std::string const & s);
static std::string toUpper(std::string const & s); static std::string toUpper(std::string const & s);
static void replace_char(char * str, char find, char replace); static void replace_char(char * str, char find, char replace);
@@ -68,10 +67,17 @@ class Helpers {
static bool value2float(const char * value, float & value_f); static bool value2float(const char * value, float & value_f);
static bool value2bool(const char * value, bool & value_b); static bool value2bool(const char * value, bool & value_b);
static bool value2string(const char * value, std::string & value_s); static bool value2string(const char * value, std::string & value_s);
static bool value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const ** strs);
static bool value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const * strs); static bool value2enum(const char * value, uint8_t & value_ui, const __FlashStringHelper * const * strs);
static bool value2temperature(const char * value, float & value_f, bool relative = false); static bool value2temperature(const char * value, float & value_f, bool relative = false);
static bool value2temperature(const char * value, int & value_i, const bool relative = false, const int min = -2147483648, const int max = 2147483647); static bool value2temperature(const char * value, int & value_i, const bool relative = false, const int min = -2147483648, const int max = 2147483647);
static uint8_t count_items(const __FlashStringHelper * const ** list);
static uint8_t count_items(const __FlashStringHelper * const * list);
static std::string translated_word(const __FlashStringHelper * const * strings, bool to_lower = false);
static const __FlashStringHelper * translated_fword(const __FlashStringHelper * const * strings);
#ifdef EMSESP_STANDALONE #ifdef EMSESP_STANDALONE
static char * ultostr(char * ptr, uint32_t value, const uint8_t base); static char * ultostr(char * ptr, uint32_t value, const uint8_t base);
#endif #endif

View File

@@ -1,858 +0,0 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// common words
MAKE_PSTR_WORD(debug)
MAKE_PSTR_WORD(exit)
MAKE_PSTR_WORD(help)
MAKE_PSTR_WORD(log)
MAKE_PSTR_WORD(logout)
MAKE_PSTR_WORD(enabled)
MAKE_PSTR_WORD(disabled)
MAKE_PSTR_WORD(set)
MAKE_PSTR_WORD(show)
MAKE_PSTR_WORD(on)
MAKE_PSTR_WORD(off)
MAKE_PSTR_WORD(ON)
MAKE_PSTR_WORD(OFF)
MAKE_PSTR_WORD(su)
MAKE_PSTR_WORD(name)
MAKE_PSTR_WORD(auto)
MAKE_PSTR_WORD(scan)
MAKE_PSTR_WORD(password)
MAKE_PSTR_WORD(read)
MAKE_PSTR_WORD(version)
MAKE_PSTR_WORD(values)
MAKE_PSTR_WORD(system)
MAKE_PSTR_WORD(fetch)
MAKE_PSTR_WORD(restart)
MAKE_PSTR_WORD(format)
MAKE_PSTR_WORD(raw)
MAKE_PSTR_WORD(watch)
MAKE_PSTR_WORD(syslog)
MAKE_PSTR_WORD(send)
MAKE_PSTR_WORD(telegram)
MAKE_PSTR_WORD(bus_id)
MAKE_PSTR_WORD(tx_mode)
MAKE_PSTR_WORD(ems)
MAKE_PSTR_WORD(devices)
MAKE_PSTR_WORD(shower)
MAKE_PSTR_WORD(mqtt)
MAKE_PSTR_WORD(emsesp)
MAKE_PSTR_WORD(connected)
MAKE_PSTR_WORD(disconnected)
MAKE_PSTR_WORD(passwd)
MAKE_PSTR_WORD(hostname)
MAKE_PSTR_WORD(wifi)
MAKE_PSTR_WORD(reconnect)
MAKE_PSTR_WORD(ssid)
MAKE_PSTR_WORD(heartbeat)
MAKE_PSTR_WORD(users)
MAKE_PSTR_WORD(publish)
MAKE_PSTR_WORD(timeout)
MAKE_PSTR_WORD(board_profile)
MAKE_PSTR_WORD(setvalue)
// for commands
MAKE_PSTR_WORD(call)
MAKE_PSTR_WORD(cmd)
MAKE_PSTR_WORD(id)
MAKE_PSTR_WORD(hc)
MAKE_PSTR_WORD(wwc)
MAKE_PSTR_WORD(device)
MAKE_PSTR_WORD(data)
MAKE_PSTR_WORD(command)
MAKE_PSTR_WORD(commands)
MAKE_PSTR_WORD(info)
MAKE_PSTR_WORD(settings)
MAKE_PSTR_WORD(customizations)
MAKE_PSTR_WORD(value)
MAKE_PSTR_WORD(error)
MAKE_PSTR_WORD(entities)
// devices
MAKE_PSTR_WORD(boiler)
MAKE_PSTR_WORD(thermostat)
MAKE_PSTR_WORD(switch)
MAKE_PSTR_WORD(solar)
MAKE_PSTR_WORD(mixer)
MAKE_PSTR_WORD(gateway)
MAKE_PSTR_WORD(controller)
MAKE_PSTR_WORD(connect)
MAKE_PSTR_WORD(heatpump)
MAKE_PSTR_WORD(generic)
MAKE_PSTR_WORD(analogsensor)
MAKE_PSTR_WORD(unknown)
MAKE_PSTR_WORD(dallassensor)
// format strings
MAKE_PSTR(host_fmt, "Host: %s")
MAKE_PSTR(port_fmt, "Port: %d")
MAKE_PSTR(hostname_fmt, "Hostname: %s")
MAKE_PSTR(board_profile_fmt, "Board Profile: %s")
MAKE_PSTR(mark_interval_fmt, "Mark interval: %lus")
MAKE_PSTR(wifi_ssid_fmt, "WiFi SSID: %s")
MAKE_PSTR(wifi_password_fmt, "WiFi Password: %S")
MAKE_PSTR(tx_mode_fmt, "Tx mode: %d")
MAKE_PSTR(bus_id_fmt, "Bus ID: %02X")
MAKE_PSTR(log_level_fmt, "Log level: %s")
MAKE_STR(productid_fmt, "%s EMS ProductID")
MAKE_PSTR_LIST(enum_syslog_level, F_(off), F("emerg"), F("alert"), F("crit"), F_(error), F("warn"), F("notice"), F_(info), F_(debug), F("trace"), F("all"))
MAKE_PSTR_LIST(enum_watch, F_(off), F_(on), F_(raw), F_(unknown))
MAKE_PSTR_LIST(enum_sensortype, F("none"), F("digital in"), F("counter"), F("adc"), F("timer"), F("rate"), F("digital out"), F("pwm 0"), F("pwm 1"), F("pwm 2"))
// strings
MAKE_PSTR(EMSESP, "EMS-ESP")
MAKE_PSTR(cmd_optional, "[cmd]")
MAKE_PSTR(ha_optional, "[ha]")
MAKE_PSTR(deep_optional, "[deep]")
MAKE_PSTR(watchid_optional, "[ID]")
MAKE_PSTR(watch_format_optional, "[off | on | raw | unknown]")
MAKE_PSTR(invalid_watch, "Invalid watch type")
MAKE_PSTR(data_mandatory, "\"XX XX ...\"")
MAKE_PSTR(asterisks, "********")
MAKE_PSTR(n_mandatory, "<n>")
MAKE_PSTR(sensorid_optional, "[sensor ID]")
MAKE_PSTR(id_optional, "[id|hc]")
MAKE_PSTR(data_optional, "[data]")
MAKE_PSTR(offset_optional, "[offset]")
MAKE_PSTR(length_optional, "[length]")
MAKE_PSTR(typeid_mandatory, "<type ID>")
MAKE_PSTR(deviceid_mandatory, "<device ID>")
MAKE_PSTR(device_type_optional, "[device]")
MAKE_PSTR(invalid_log_level, "Invalid log level")
MAKE_PSTR(log_level_optional, "[level]")
MAKE_PSTR(name_mandatory, "<name>")
MAKE_PSTR(name_optional, "[name]")
MAKE_PSTR(new_password_prompt1, "Enter new password: ")
MAKE_PSTR(new_password_prompt2, "Retype new password: ")
MAKE_PSTR(password_prompt, "Password: ")
MAKE_PSTR(unset, "<unset>")
// command descriptions
MAKE_PSTR(info_cmd, "lists all values")
MAKE_PSTR(commands_cmd, "lists all commands")
MAKE_PSTR(entities_cmd, "lists all entities")
MAKE_PSTR_WORD(number)
MAKE_PSTR_WORD(enum)
MAKE_PSTR_WORD(text)
MAKE_PSTR_WORD(2)
MAKE_PSTR_WORD(4)
MAKE_PSTR_WORD(10)
MAKE_PSTR_WORD(100)
MAKE_PSTR_WORD(60)
MAKE_PSTR_LIST(div2, F_(2))
MAKE_PSTR_LIST(div4, F_(4))
MAKE_PSTR_LIST(div10, F_(10))
MAKE_PSTR_LIST(div60, F_(60))
MAKE_PSTR_LIST(div100, F_(100))
MAKE_PSTR_LIST(mul5, F("-5"))
MAKE_PSTR_LIST(mul10, F("-10"))
MAKE_PSTR_LIST(mul15, F("-15"))
// Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp
// uom - also used with HA see https://github.com/home-assistant/core/blob/d7ac4bd65379e11461c7ce0893d3533d8d8b8cbf/homeassistant/const.py#L384
MAKE_PSTR(blank, " ")
MAKE_PSTR(percent, "%")
MAKE_PSTR(degrees, "°C")
MAKE_PSTR(kwh, "kWh")
MAKE_PSTR(wh, "Wh")
MAKE_PSTR(bar, "bar")
MAKE_PSTR(minutes, "Minuten")
MAKE_PSTR(hours, "Stunden")
MAKE_PSTR(days, "Tage")
MAKE_PSTR(ua, "uA")
MAKE_PSTR(lmin, "l/min")
MAKE_PSTR(kw, "kW")
MAKE_PSTR(w, "W")
MAKE_PSTR(kb, "KB")
MAKE_PSTR(seconds, "seconds")
MAKE_PSTR(dbm, "dBm")
MAKE_PSTR(fahrenheit, "°F")
MAKE_PSTR(mv, "mV")
MAKE_PSTR(sqm, "sqm")
MAKE_PSTR(m3, "m3")
MAKE_PSTR(l, "l")
// MAKE_PSTR(times, "mal")
// MAKE_PSTR(oclock, "Uhr")
// TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp
// use empty string if want to suppress showing tags
// mqtt tags must not have spaces
MAKE_PSTR(tag_none, "")
MAKE_PSTR(tag_heartbeat, "")
MAKE_PSTR(tag_boiler_data_ww, "ww")
MAKE_PSTR(tag_device_data, "")
MAKE_PSTR(tag_device_data_ww, "ww")
MAKE_PSTR(tag_hc1, "hc1")
MAKE_PSTR(tag_hc2, "hc2")
MAKE_PSTR(tag_hc3, "hc3")
MAKE_PSTR(tag_hc4, "hc4")
MAKE_PSTR(tag_hc5, "hc5")
MAKE_PSTR(tag_hc6, "hc6")
MAKE_PSTR(tag_hc7, "hc7")
MAKE_PSTR(tag_hc8, "hc8")
MAKE_PSTR(tag_wwc1, "wwc1")
MAKE_PSTR(tag_wwc2, "wwc2")
MAKE_PSTR(tag_wwc3, "wwc3")
MAKE_PSTR(tag_wwc4, "wwc4")
MAKE_PSTR(tag_wwc5, "wwc5")
MAKE_PSTR(tag_wwc6, "wwc6")
MAKE_PSTR(tag_wwc7, "wwc7")
MAKE_PSTR(tag_wwc8, "wwc8")
MAKE_PSTR(tag_wwc9, "wwc9")
MAKE_PSTR(tag_wwc10, "wwc10")
MAKE_PSTR(tag_ahs, "ahs")
MAKE_PSTR(tag_hs1, "hs1")
MAKE_PSTR(tag_hs2, "hs2")
MAKE_PSTR(tag_hs3, "hs3")
MAKE_PSTR(tag_hs4, "hs4")
MAKE_PSTR(tag_hs5, "hs5")
MAKE_PSTR(tag_hs6, "hs6")
MAKE_PSTR(tag_hs7, "hs7")
MAKE_PSTR(tag_hs8, "hs8")
MAKE_PSTR(tag_hs9, "hs9")
MAKE_PSTR(tag_hs10, "hs10")
MAKE_PSTR(tag_hs11, "hs11")
MAKE_PSTR(tag_hs12, "hs12")
MAKE_PSTR(tag_hs13, "hs13")
MAKE_PSTR(tag_hs14, "hs14")
MAKE_PSTR(tag_hs15, "hs15")
MAKE_PSTR(tag_hs16, "hs16")
// MQTT topic names
// MAKE_PSTR(tag_heartbeat_mqtt, "heartbeat")
// MAKE_PSTR(tag_boiler_data_mqtt, "")
MAKE_PSTR(tag_boiler_data_ww_mqtt, "ww")
MAKE_PSTR(tag_device_data_ww_mqtt, "")
// boiler
MAKE_PSTR(time, "Zeit")
MAKE_PSTR(date, "Datum")
MAKE_PSTR_WORD(1x3min)
MAKE_PSTR_WORD(2x3min)
MAKE_PSTR_WORD(3x3min)
MAKE_PSTR_WORD(4x3min)
MAKE_PSTR_WORD(5x3min)
MAKE_PSTR_WORD(6x3min)
MAKE_PSTR_(continuos, "kontinuierlich")
MAKE_PSTR(3wayvalve, "3-Wege Ventil")
MAKE_PSTR(chargepump, "Ladepumpe")
MAKE_PSTR(hot, "Heiss")
MAKE_PSTR(high_comfort, "Heiss Komfort")
MAKE_PSTR(eco, "Eco")
MAKE_PSTR(intelligent, "Intelligent")
MAKE_PSTR_(flow, "Fluss")
MAKE_PSTR(manual, "Manuell")
MAKE_PSTR_(buffer, "Speicher")
MAKE_PSTR(bufferedflow, "Durchlaufspeicher")
MAKE_PSTR(layeredbuffer, "Schichtspeicher")
MAKE_PSTR(maintenance, "Wartung")
MAKE_PSTR(heating, "Heizen")
MAKE_PSTR(cooling, "K<EFBFBD>hlen")
// boiler lists
MAKE_PSTR_LIST(tpl_date, F("Format: < dd.mm.yyyy >")) // template for text input
MAKE_PSTR_LIST(enum_off_time_date_manual, F_(off), F_(time), F_(date), F_(manual))
MAKE_PSTR_LIST(enum_freq, F_(off), F_(1x3min), F_(2x3min), F_(3x3min), F_(4x3min), F_(5x3min), F_(6x3min), F_(continuous))
MAKE_PSTR_LIST(enum_charge, F_(chargepump), F_(3wayvalve))
MAKE_PSTR_LIST(enum_comfort, F_(hot), F_(eco), F_(intelligent))
MAKE_PSTR_LIST(enum_comfort1, F_(high_comfort), F_(eco))
MAKE_PSTR_LIST(enum_flow, F_(off), F_(flow), F_(bufferedflow), F_(buffer), F_(layeredbuffer))
MAKE_PSTR_LIST(enum_reset, F("-"), F_(maintenance), F_(error))
// MAKE_PSTR_LIST(enum_bool, F_(off), F_(on))
// AM200 lists
MAKE_PSTR_LIST(enum_vr2Config, F_(off), F("bypass"));
MAKE_PSTR_LIST(enum_aPumpSignal, F_(off), F("pwm"), F("pwm_invers"));
MAKE_PSTR_LIST(enum_bufBypass, F("no"), F_(mixer), F("valve"));
MAKE_PSTR_LIST(enum_bufConfig, F("monovalent"), F("bivalent"));
MAKE_PSTR_LIST(enum_blockMode, F_(off), F_(auto), F("blocking"));
MAKE_PSTR_LIST(enum_blockTerm, F("n_o"), F("n_c"));
//heatpump
MAKE_PSTR_LIST(enum_hpactivity, F("Kein"), F("Heizen"), F("Kühlen"), F("Warmwasser"), F("Pool"))
// mixer
MAKE_PSTR_LIST(enum_shunt, F("gestoppt"), F("öffnen"), F("schließen"), F("Offen"), F("Geschlossen"))
// thermostat
MAKE_PSTR(light, "Leicht")
MAKE_PSTR(medium, "Mittel")
MAKE_PSTR(heavy, "Schwer")
MAKE_PSTR(own_prog, "Eigenprog")
MAKE_PSTR(start, "Start")
MAKE_PSTR(heat, "Heizen")
MAKE_PSTR(hold, "Halten")
MAKE_PSTR(cool, "Kühl")
MAKE_PSTR(end, "Ende")
MAKE_PSTR(german, "Deutsch")
MAKE_PSTR(dutch, "Niederländisch")
MAKE_PSTR(french, "Französisch")
MAKE_PSTR(italian, "Italienisch")
MAKE_PSTR(high, "hoch")
MAKE_PSTR(low, "niedrig")
MAKE_PSTR(radiator, "Heizkörper")
MAKE_PSTR(convector, "Konvektor")
MAKE_PSTR(floor, "Fussboden")
MAKE_PSTR(summer, "Sommer")
MAKE_PSTR(winter, "Winter")
MAKE_PSTR(outdoor, "Aussentemperatur")
MAKE_PSTR_WORD(mpc)
MAKE_PSTR(room, "Raum")
MAKE_PSTR(room_outdoor, "Raum+Au<41>en")
MAKE_PSTR(power, "Leistung")
MAKE_PSTR(constant, "konstant")
MAKE_PSTR(simple, "einfach")
MAKE_PSTR(optimized, "optimiert")
MAKE_PSTR(nofrost, "Frostschutz")
MAKE_PSTR(comfort, "Komfort")
MAKE_PSTR(night, "Nacht")
MAKE_PSTR(day, "Tag")
MAKE_PSTR(holiday, "Urlaub")
MAKE_PSTR(reduce, "reduziert")
MAKE_PSTR(noreduce, "unreduziert")
MAKE_PSTR(offset, "Anhebung")
MAKE_PSTR(design, "Auslegung")
MAKE_PSTR_WORD(tempauto)
MAKE_PSTR(minflow, "minfluss")
MAKE_PSTR(maxflow, "maxfluss")
MAKE_PSTR_WORD(rc3x)
MAKE_PSTR_WORD(rc20)
MAKE_PSTR(internal_temperature, "interne Temperatur")
MAKE_PSTR(internal_setpoint, "interner Sollwert")
MAKE_PSTR(external_temperature, "externe Temperatur")
MAKE_PSTR(burner_temperature, "Kesseltemperatur")
MAKE_PSTR(ww_temperature, "Wassertemperatur")
MAKE_PSTR(functioning_mode, "functioning mode")
MAKE_PSTR(smoke_temperature, "Abgastemperatur")
// thermostat lists
MAKE_PSTR_LIST(tpl_datetime, F("Format: < NTP | dd.mm.yyyy-hh:mm:ss-dw-dst >"))
MAKE_PSTR_LIST(tpl_switchtime, F("Format: < nn.d.o.hh:mm >"))
MAKE_PSTR_LIST(tpl_switchtime1, F("Format: <nn> [ not_set | day hh:mm Tn ]"))
MAKE_PSTR_LIST(tpl_holidays, F("Format: < dd.mm.yyyy-dd.mm.yyyy >"))
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_ibaLanguage_RC30, F_(german), F_(dutch))
MAKE_PSTR_LIST(enum_floordrystatus, F_(off), F_(start), F_(heat), F_(hold), F_(cool), F_(end))
MAKE_PSTR_LIST(enum_ibaBuildingType, F_(light), F_(medium), F_(heavy)) // RC300
MAKE_PSTR_LIST(enum_PID, F("fast"), F_(medium), F("slow"))
MAKE_PSTR_LIST(enum_wwMode, F_(off), F("normal"), F_(comfort), F_(auto), F_(own_prog), F_(eco))
MAKE_PSTR_LIST(enum_wwCircMode, F_(off), F_(on), F_(auto), F_(own_prog))
MAKE_PSTR_LIST(enum_wwMode2, F_(off), F_(on), F_(auto))
MAKE_PSTR_LIST(enum_wwMode3, F_(on), F_(off), F_(auto))
MAKE_PSTR_LIST(enum_heatingtype, F_(off), F_(radiator), F_(convector), F_(floor))
MAKE_PSTR_LIST(enum_summermode, F_(summer), F_(auto), F_(winter))
MAKE_PSTR_LIST(enum_hpoperatingmode, F_(off), F_(auto), F("heizen"), F("kühlen"))
MAKE_PSTR_LIST(enum_summer, F_(winter), F_(summer))
MAKE_PSTR_LIST(enum_operatingstate, F_(heating), F_(off), F_(cooling))
MAKE_PSTR_LIST(enum_mode, F_(manual), F_(auto)) // RC100, RC300, RC310
MAKE_PSTR_LIST(enum_mode2, F_(off), F_(manual), F_(auto)) // RC20
MAKE_PSTR_LIST(enum_mode3, F_(night), F_(day), F_(auto)) // RC35, RC30, RC25
MAKE_PSTR_LIST(enum_mode4, F_(nofrost), F_(eco), F_(heat), F_(auto)) // JUNKERS
MAKE_PSTR_LIST(enum_mode5, F_(auto), F_(off)) // CRF
MAKE_PSTR_LIST(enum_mode6, F_(nofrost), F_(night), F_(day)) // RC10
MAKE_PSTR_LIST(enum_modetype, F_(eco), F_(comfort))
// MAKE_PSTR_LIST(enum_modetype2, F_(day))
MAKE_PSTR_LIST(enum_modetype3, F_(night), F_(day))
MAKE_PSTR_LIST(enum_modetype4, F_(nofrost), F_(eco), F_(heat))
MAKE_PSTR_LIST(enum_modetype5, F_(off), F_(on))
MAKE_PSTR_LIST(enum_reducemode, F_(nofrost), F_(reduce), F_(room), F_(outdoor))
MAKE_PSTR_LIST(enum_reducemode1, F_(outdoor), F_(room), F_(reduce)) // RC310 values: 1-3
MAKE_PSTR_LIST(enum_nofrostmode, F_(off), F_(room), F_(outdoor))
MAKE_PSTR_LIST(enum_nofrostmode1, F_(room), F_(outdoor), F_(room_outdoor))
MAKE_PSTR_LIST(enum_controlmode, F_(off), F_(optimized), F_(simple), F_(mpc), F_(room), F_(power), F_(constant))
MAKE_PSTR_LIST(enum_controlmode1, F("weather-compensated"), F("outside-basepoint"), F("n/a"), F_(room)) // RC310 1-4
MAKE_PSTR_LIST(enum_controlmode2, F_(outdoor), F_(room))
// MAKE_PSTR_LIST(enum_controlmode3, F_(off), F_(room), F_(outdoor), F("room+outdoor"))
MAKE_PSTR_LIST(enum_control, F_(off), F_(rc20), F_(rc3x))
MAKE_PSTR_LIST(enum_j_control, F_(off), F("fb10"), F("fb110"))
MAKE_PSTR_LIST(enum_wwProgMode, F("std Prog"), F_(own_prog))
MAKE_PSTR_LIST(enum_dayOfWeek, F("Mo"), F("Di"), F("Mi"), F("Do"), F("Fr"), F("Sa"), F("So"), F("Alle"))
MAKE_PSTR_LIST(enum_progMode, F("Prog_1"), F("Prog_2"))
MAKE_PSTR_LIST(enum_progMode2,
F("Eigen_1"),
F("Familie"),
F("Morgends"),
F("Abends"),
F("Vormittag"),
F("Nachmittag"),
F("Mittag"),
F("Singles"),
F("Senioren"),
F("Neu"),
F("Eigen_2"))
MAKE_PSTR_LIST(enum_progMode3, F("Familie"), F("Morgends"), F("Abends"), F("Vormittag"), F("Nachmittag"), F("Mittag"), F("Singles"), F("Senioren"))
MAKE_PSTR_LIST(enum_progMode4, F("prog_a"), F("prog_b"), F("prog_c"), F("prog_d"), F("prog_e"), F("prog_f"))
MAKE_PSTR_LIST(enum_switchmode, F_(off), F_(eco), F_(comfort), F_(heat))
MAKE_PSTR_LIST(enum_climate, F("Solltemperature"), F("Raumtemperatur"))
// solar list
MAKE_PSTR_LIST(enum_solarmode, F_(constant), F("pwm"), F("analog"))
MAKE_PSTR_LIST(enum_collectortype, F("flach"), F("vakuum"))
MAKE_PSTR_LIST(enum_cylprio, F("Zyl_1"), F("Zyl_2"))
// id used to store the device ID, goes into MQTT payload
MAKE_PSTR_LIST(ID, F_(id))
// Boiler
// extra commands
MAKE_PSTR_LIST(wwtapactivated, F("wwtapactivated"), F("Aktiviere Warmwasser im Wartungsmodus"))
MAKE_PSTR_LIST(reset, F("reset"), F("Reset"))
// single mqtt topics
MAKE_PSTR_WORD(heating_active)
MAKE_PSTR_WORD(tapwater_active)
MAKE_PSTR_WORD(response)
// mqtt, commands and text
MAKE_PSTR_LIST(heatingActive, F("heatingactive"), F("Heizung aktiv"))
MAKE_PSTR_LIST(tapwaterActive, F("tapwateractive"), F("Warmwasser aktiv"))
MAKE_PSTR_LIST(selFlowTemp, F("selflowtemp"), F("Sollwert Flusstemperatur"))
MAKE_PSTR_LIST(selBurnPow, F("selburnpow"), F("Sollwert Brennerleistung"))
MAKE_PSTR_LIST(heatingPumpMod, F("heatingpumpmod"), F("Heizungspumpe 1 Modulation"))
MAKE_PSTR_LIST(heatingPump2Mod, F("heatingpump2mod"), F("Heizungspumpe 2 Modulation"))
MAKE_PSTR_LIST(outdoorTemp, F("outdoortemp"), F("Aussentemperatur"))
MAKE_PSTR_LIST(curFlowTemp, F("curflowtemp"), F("aktuelle Flusstemperatur"))
MAKE_PSTR_LIST(retTemp, F("rettemp"), F("Rücklauftemperatur"))
MAKE_PSTR_LIST(switchTemp, F("switchtemp"), F("Mischer Schalttemperatur"))
MAKE_PSTR_LIST(sysPress, F("syspress"), F("Systemdruck"))
MAKE_PSTR_LIST(boilTemp, F("boiltemp"), F("Kesseltemperatur"))
MAKE_PSTR_LIST(exhaustTemp, F("exhausttemp"), F("Auslasstemperatur"))
MAKE_PSTR_LIST(burnGas, F("burngas"), F("Gas"))
MAKE_PSTR_LIST(burnGas2, F("burngas2"), F("Gas Stufe 2"))
MAKE_PSTR_LIST(flameCurr, F("flamecurr"), F("Flammstrom"))
MAKE_PSTR_LIST(heatingPump, F("heatingpump"), F("Heizungspumpe"))
MAKE_PSTR_LIST(fanWork, F("fanwork"), F("Gebläse"))
MAKE_PSTR_LIST(ignWork, F("ignwork"), F("Zündung"))
MAKE_PSTR_LIST(oilPreHeat, F("oilpreheat"), F("oil preheating"))
MAKE_PSTR_LIST(heatingActivated, F("heatingactivated"), F("Heizen aktiviert"))
MAKE_PSTR_LIST(heatingTemp, F("heatingtemp"), F("Kesseltemperatur"))
MAKE_PSTR_LIST(pumpModMax, F("pumpmodmax"), F("Kesselpumpen Maximalleistung"))
MAKE_PSTR_LIST(pumpModMin, F("pumpmodmin"), F("Kesselpumpen Minmalleistung"))
MAKE_PSTR_LIST(pumpDelay, F("pumpdelay"), F("Pumpennachlauf"))
MAKE_PSTR_LIST(burnMinPeriod, F("burnminperiod"), F("Antipendelzeit"))
MAKE_PSTR_LIST(burnMinPower, F("burnminpower"), F("minimale Brennerleistung"))
MAKE_PSTR_LIST(burnMaxPower, F("burnmaxpower"), F("maximale Brennerleistung"))
MAKE_PSTR_LIST(boilHystOn, F("boilhyston"), F("Hysterese ein temperatur"))
MAKE_PSTR_LIST(boilHystOff, F("boilhystoff"), F("Hysterese aus temperatur"))
MAKE_PSTR_LIST(setFlowTemp, F("setflowtemp"), F("Sollwert Flusstemperatur"))
MAKE_PSTR_LIST(setBurnPow, F("setburnpow"), F("Sollwert Brennerleistung"))
MAKE_PSTR_LIST(curBurnPow, F("curburnpow"), F("Brennerleistung"))
MAKE_PSTR_LIST(burnStarts, F("burnstarts"), F("Brenner # starts"))
MAKE_PSTR_LIST(burnWorkMin, F("burnworkmin"), F("Brenner Laufzeit"))
MAKE_PSTR_LIST(burn2WorkMin, F("burn2workmin"), F("Brenner Stufe 2 Laufzeit"))
MAKE_PSTR_LIST(heatWorkMin, F("heatworkmin"), F("Heizung Laufzeit"))
MAKE_PSTR_LIST(UBAuptime, F("ubauptime"), F("gesamte Laufzeit"))
MAKE_PSTR_LIST(lastCode, F("lastcode"), F("Fehlerspeicher"))
MAKE_PSTR_LIST(serviceCode, F("servicecode"), F("Statusmeldung"))
MAKE_PSTR_LIST(serviceCodeNumber, F("servicecodenumber"), F("Statusmeldungsnummer"))
MAKE_PSTR_LIST(maintenanceMessage, F("maintenancemessage"), F("Wartungsmeldung"))
MAKE_PSTR_LIST(maintenanceDate, F("maintenancedate"), F("Wartungsdatum"))
MAKE_PSTR_LIST(maintenanceType, F_(maintenance), F("Wartungsplan"))
MAKE_PSTR_LIST(maintenanceTime, F("maintenancetime"), F("Wartung in"))
MAKE_PSTR_LIST(emergencyOps, F("emergencyops"), F("emergency operation"))
MAKE_PSTR_LIST(emergencyTemp, F("emergencytemp"), F("emergency temperature"))
// heatpump/compress specific
MAKE_PSTR_LIST(upTimeControl, F("uptimecontrol"), F("Betriebszeit total heizen"))
MAKE_PSTR_LIST(upTimeCompHeating, F("uptimecompheating"), F("Betriebszeit Kompressor heizen"))
MAKE_PSTR_LIST(upTimeCompCooling, F("uptimecompcooling"), F("Betriebszeit Kompressor kühlen"))
MAKE_PSTR_LIST(upTimeCompWw, F("uptimecompww"), F("Betriebszeit Kompressor"))
MAKE_PSTR_LIST(upTimeCompPool, F("uptimecomppool"), F("Betriebszeit Kompressor Pool"))
MAKE_PSTR_LIST(totalCompStarts, F("totalcompstarts"), F("gesamt Kompressor Starts"))
MAKE_PSTR_LIST(heatingStarts, F("heatingstarts"), F("Heizen Starts"))
MAKE_PSTR_LIST(coolingStarts, F("coolingstarts"), F("Kühlen Starts"))
MAKE_PSTR_LIST(poolStarts, F("poolstarts"), F("Pool Starts"))
MAKE_PSTR_LIST(nrgConsTotal, F("nrgconstotal"), F("totaler Energieverbrauch"))
MAKE_PSTR_LIST(nrgConsCompTotal, F("nrgconscomptotal"), F("Energieverbrauch Kompressor total"))
MAKE_PSTR_LIST(nrgConsCompHeating, F("nrgconscompheating"), F("Energieverbrauch Kompressor heizen"))
MAKE_PSTR_LIST(nrgConsCompWw, F("nrgconscompww"), F("Energieverbrauch Kompressor"))
MAKE_PSTR_LIST(nrgConsCompCooling, F("nrgconscompcooling"), F("Energieverbrauch Kompressor kühlen"))
MAKE_PSTR_LIST(nrgConsCompPool, F("nrgconscomppool"), F("Energieverbrauch Kompressor Pool"))
MAKE_PSTR_LIST(nrgSuppTotal, F("nrgsupptotal"), F("gesamte Energieabgabe"))
MAKE_PSTR_LIST(nrgSuppHeating, F("nrgsuppheating"), F("gesamte Energieabgabe heizen"))
MAKE_PSTR_LIST(nrgSuppWw, F("nrgsuppww"), F("gesamte Energieabgabe"))
MAKE_PSTR_LIST(nrgSuppCooling, F("nrgsuppcooling"), F("gesamte Energieabgabe kühlen"))
MAKE_PSTR_LIST(nrgSuppPool, F("nrgsupppool"), F("gesamte Energieabgabe Pool"))
MAKE_PSTR_LIST(auxElecHeatNrgConsTotal, F("auxelecheatnrgconstotal"), F("Energieverbrauch el. Zusatzheizung"))
MAKE_PSTR_LIST(auxElecHeatNrgConsHeating, F("auxelecheatnrgconsheating"), F("Energieverbrauch el. Zusatzheizung Heizen"))
MAKE_PSTR_LIST(auxElecHeatNrgConsWW, F("auxelecheatnrgconsww"), F("Energieverbrauch el. Zusatzheizung"))
MAKE_PSTR_LIST(auxElecHeatNrgConsPool, F("auxelecheatnrgconspool"), F("Energieverbrauch el. Zusatzheizung Pool"))
MAKE_PSTR_LIST(hpPower, F("hppower"), F("Leistung Wärmepumpe"))
MAKE_PSTR_LIST(hpCompOn, F("hpcompon"), F("HP Compressor"))
MAKE_PSTR_LIST(hpHeatingOn, F("hpheatingon"), F("HP Heating"))
MAKE_PSTR_LIST(hpCoolingOn, F("hpcoolingon"), F("HP Cooling"))
MAKE_PSTR_LIST(hpWwOn, F("hpwwon"), F("HP dhw"))
MAKE_PSTR_LIST(hpPoolOn, F("hppoolon"), F("HP Pool"))
MAKE_PSTR_LIST(hpBrinePumpSpd, F("hpbrinepumpspd"), F("Brine Pump Speed"))
MAKE_PSTR_LIST(hpCompSpd, F("hpcompspd"), F("Compressor Speed"))
MAKE_PSTR_LIST(hpCircSpd, F("hpcircspd"), F("Circulation pump Speed"))
MAKE_PSTR_LIST(hpBrineIn, F("hpbrinein"), F("Brine in/Evaporator"))
MAKE_PSTR_LIST(hpBrineOut, F("hpbrineout"), F("Brine out/Condenser"))
MAKE_PSTR_LIST(hpSuctionGas, F("hpsuctiongas"), F("Suction gas"))
MAKE_PSTR_LIST(hpHotGas, F("hphotgas"), F("Hot gas/Compressed"))
MAKE_PSTR_LIST(hpSwitchValve, F("hpswitchvalve"), F("Switch Valve"))
MAKE_PSTR_LIST(hpActivity, F("hpactivity"), F("Compressor Activity"))
MAKE_PSTR_LIST(hpTc0, F("hptc0"), F("Wärmeträgerflüssigkeit Eingang (TC0)"))
MAKE_PSTR_LIST(hpTc1, F("hptc1"), F("Wärmeträgerflüssigkeit Ausgang (TC1)"))
MAKE_PSTR_LIST(hpTc3, F("hptc3"), F("Verflüssigertemperatur (TC3)"))
MAKE_PSTR_LIST(hpTr3, F("hptr3"), F(" Temperaturfühler Kältemittel (Flüssigkeit) (TR3)"))
MAKE_PSTR_LIST(hpTr4, F("hptr4"), F("Verdampfer Eintritt (TR4)"))
MAKE_PSTR_LIST(hpTr5, F("hptr5"), F("Temperaturfühler Kompessoransaugleitung (TR5)"))
MAKE_PSTR_LIST(hpTr6, F("hptr6"), F("Temperaturfühler Kompressorausgangsleitung (TR6)"))
MAKE_PSTR_LIST(hpTr7, F("hptr7"), F("Temperaturfühler Kältemittel (Gas) (TR7)"))
MAKE_PSTR_LIST(hpTl2, F("hptl2"), F("Außenlufttemperaturfühler (TL2)"))
MAKE_PSTR_LIST(hpPl1, F("hppl1"), F("Niedrigdruckfühler (PL1)"))
MAKE_PSTR_LIST(hpPh1, F("hpph1"), F("Hochdruckfühler (PH1)"))
// hybrid heatpump
MAKE_PSTR_LIST(enum_hybridStrategy, F("co2-optimized"), F("cost-optimized"), F("outside-temp-switched"), F("co2-cost-mix"))
MAKE_PSTR_LIST(hybridStrategy, F("hybridstrategy"), F("hybrid control strategy"))
MAKE_PSTR_LIST(switchOverTemp, F("switchovertemp"), F("outside switchover temperature"))
MAKE_PSTR_LIST(energyCostRatio, F("energycostratio"), F("energy cost ratio"))
MAKE_PSTR_LIST(fossileFactor, F("fossilefactor"), F("fossile energy factor"))
MAKE_PSTR_LIST(electricFactor, F("electricfactor"), F("electric energy factor"))
MAKE_PSTR_LIST(delayBoiler, F("delayboiler"), F("delay boiler support"))
MAKE_PSTR_LIST(tempDiffBoiler, F("tempdiffboiler"), F("tempediff boiler support"))
// alternative heatsource AM200
MAKE_PSTR_LIST(aCylTopTemp, F("cyltoptemp"), F("Zylinder oben Temperatur"))
MAKE_PSTR_LIST(aCylCenterTemp, F("cylcentertemp"), F("Zylinder mitte Temperatur"))
MAKE_PSTR_LIST(aCylBottomTemp, F("cylbottomtemp"), F("Zylinder unten Temperatur"))
MAKE_PSTR_LIST(aFlowTemp, F("altflowtemp"), F("Alternativ hs Flusstemperatur"))
MAKE_PSTR_LIST(aRetTemp, F("altrettemp"), F("Alternativ hs Rücktemperatur"))
MAKE_PSTR_LIST(sysFlowTemp, F("sysflowtemp"), F("System Flusstemperature"))
MAKE_PSTR_LIST(sysRetTemp, F("sysrettemp"), F("System Rücktemperature"))
MAKE_PSTR_LIST(valveByPass, F("valvebypass"), F("bypass Ventil"))
MAKE_PSTR_LIST(valveBuffer, F("valvebuffer"), F("Puffer Ventil"))
MAKE_PSTR_LIST(valveReturn, F("valvereturn"), F("Rückfluss Ventil"))
MAKE_PSTR_LIST(aPumpMod, F("altpumpmod"), F("Alternativ hs Pumpenmodulation"))
MAKE_PSTR_LIST(heatSource, F("heatsource"), F("Alternativ Heizung"))
MAKE_PSTR_LIST(vr2Config, F("vr2config"), F("vr2 configuration"))
MAKE_PSTR_LIST(ahsActivated, F("ahsactivated"), F("alternate heat source activation"))
MAKE_PSTR_LIST(aPumpConfig, F("apumpconfig"), F("primary pump config"))
MAKE_PSTR_LIST(aPumpSignal, F("apumpsignal"), F("output for pr1 pump"))
MAKE_PSTR_LIST(aPumpMin, F("apumpmin"), F("min output pump pr1"))
MAKE_PSTR_LIST(tempRise, F("temprise"), F("ahs return temp rise"))
MAKE_PSTR_LIST(setReturnTemp, F("setreturntemp"), F("set temp return"))
MAKE_PSTR_LIST(mixRuntime, F("mixruntime"), F("mixer run time"))
// MAKE_PSTR_LIST(setFlowTemp, F("setflowtemp"), F("set flow temp"))
MAKE_PSTR_LIST(bufBypass, F("bufbypass"), F("buffer bypass config"))
MAKE_PSTR_LIST(bufMixRuntime, F("bufmixruntime"), F("bypass mixer run time"))
MAKE_PSTR_LIST(bufConfig, F("bufconfig"), F("dhw buffer config"))
MAKE_PSTR_LIST(blockMode, F("blockmode"), F("config htg. blocking mode"))
MAKE_PSTR_LIST(blockTerm, F("blockterm"), F("config of block terminal"))
MAKE_PSTR_LIST(blockHyst, F("blockhyst"), F("hyst. for bolier block"))
MAKE_PSTR_LIST(releaseWait, F("releasewait"), F("boiler release wait time"))
// the following are dhw for the boiler and automatically tagged with 'ww'
MAKE_PSTR_LIST(wWSelTemp, F("wwseltemp"), F("gewählte Temperatur"))
MAKE_PSTR_LIST(wwSelTempLow, F("wwseltemplow"), F("selected lower temperature"))
MAKE_PSTR_LIST(wwSelTempOff, F("wwseltempoff"), F("selected temperature for off"))
MAKE_PSTR_LIST(wwSelTempSingle, F("wwseltempsingle"), F("single charge temperature"))
MAKE_PSTR_LIST(wWSetTemp, F("wwsettemp"), F("Solltemperatur"))
MAKE_PSTR_LIST(wWType, F("wwtype"), F("Typ"))
MAKE_PSTR_LIST(wWComfort, F("wwcomfort"), F("Komfort"))
MAKE_PSTR_LIST(wWFlowTempOffset, F("wwflowtempoffset"), F("Flusstemperaturanhebung"))
MAKE_PSTR_LIST(wWMaxPower, F("wwmaxpower"), F("max Leistung"))
MAKE_PSTR_LIST(wWCircPump, F("wwcircpump"), F("Zirkulationspumpe vorhanden"))
MAKE_PSTR_LIST(wWChargeType, F("wwchargetype"), F("Ladungstyp"))
MAKE_PSTR_LIST(wWDisinfectionTemp, F("wwdisinfectiontemp"), F("Desinfectionstemperatur"))
MAKE_PSTR_LIST(wWCircMode, F("wwcircmode"), F("Zirkulationspumpenfrequenz"))
MAKE_PSTR_LIST(wWCirc, F("wwcirc"), F("Zirkulation aktiv"))
MAKE_PSTR_LIST(wWCurTemp, F("wwcurtemp"), F("aktuelle Warmwasser Temperatur intern"))
MAKE_PSTR_LIST(wWCurTemp2, F("wwcurtemp2"), F("aktuelle Warmwaser Temperatur extern"))
MAKE_PSTR_LIST(wWCurFlow, F("wwcurflow"), F("aktueller Durchfluss"))
MAKE_PSTR_LIST(wWStorageTemp1, F("wwstoragetemp1"), F("interne Speichertemperature"))
MAKE_PSTR_LIST(wWStorageTemp2, F("wwstoragetemp2"), F("externer Speichertemperatur"))
MAKE_PSTR_LIST(wWActivated, F("wwactivated"), F("aktiviert"))
MAKE_PSTR_LIST(wWOneTime, F("wwonetime"), F("Einmalladung"))
MAKE_PSTR_LIST(wWDisinfecting, F("wwdisinfect"), F("Desinfizieren"))
MAKE_PSTR_LIST(wWCharging, F("wwcharging"), F("Laden"))
MAKE_PSTR_LIST(wWRecharging, F("wwrecharging"), F("Nachladen"))
MAKE_PSTR_LIST(wWTempOK, F("wwtempok"), F("Temperatur ok"))
MAKE_PSTR_LIST(wWActive, F("wwactive"), F("aktiv"))
MAKE_PSTR_LIST(wwTempOK, F("wwtempok"), F("Temperatur ok"))
MAKE_PSTR_LIST(wwActive, F("wwactive"), F("aktiv"))
MAKE_PSTR_LIST(ww3wayValve, F("ww3wayvalve"), F("3-Wegeventil aktiv"))
MAKE_PSTR_LIST(wWSetPumpPower, F("wwsetpumppower"), F("Soll Pumpenleistung"))
MAKE_PSTR_LIST(mixerTemp, F("mixertemp"), F("Mischertemperatur"))
MAKE_PSTR_LIST(wwCylMiddleTemp, F("wwcylmiddletemp"), F("cylinder middle temperature (TS3)"))
MAKE_PSTR_LIST(wWStarts, F("wwstarts"), F("Anzahl starts"))
MAKE_PSTR_LIST(wWStarts2, F("wwstarts2"), F("Kreis 2 Anzahl Starts"))
MAKE_PSTR_LIST(wWWorkM, F("wwworkm"), F("aktive Zeit"))
MAKE_PSTR_LIST(wWHystOn, F("wwhyston"), F("Hysterese Einschalttemperatur"))
MAKE_PSTR_LIST(wWHystOff, F("wwhystoff"), F("Hysterese Ausschalttemperatur"))
MAKE_PSTR_LIST(wwProgMode, F("wwprogmode"), F("Programmmodus"))
MAKE_PSTR_LIST(wwCircProg, F("wwcircprog"), F("Zirkulationsprogramm"))
MAKE_PSTR_LIST(wwMaxTemp, F("wwmaxtemp"), F("Maximale Temperatur"))
MAKE_PSTR_LIST(wwOneTimeKey, F("wwonetimekey"), F("Einmalladungstaste"))
// mqtt values / commands
MAKE_PSTR_LIST(switchtime, F("switchtime"), F("Program Schaltzeit"))
MAKE_PSTR_LIST(switchtime1, F("switchtime1"), F("Program 1 Schaltzeit"))
MAKE_PSTR_LIST(switchtime2, F("switchtime2"), F("Programm 2 Schaltzeit"))
MAKE_PSTR_LIST(wwswitchtime, F("wwswitchtime"), F("Programm Schaltzeit"))
MAKE_PSTR_LIST(wwcircswitchtime, F("wwcircswitchtime"), F("Zirculationsprogramm Schaltzeit"))
MAKE_PSTR_LIST(dateTime, F("datetime"), F("Datum/Zeit"))
MAKE_PSTR_LIST(errorCode, F("errorcode"), F("Fehlermeldung"))
MAKE_PSTR_LIST(ibaMainDisplay, F("display"), F("Anzeige"))
MAKE_PSTR_LIST(ibaLanguage, F("language"), F("Sprache"))
MAKE_PSTR_LIST(ibaClockOffset, F("clockoffset"), F("Uhrkorrektur"))
MAKE_PSTR_LIST(ibaBuildingType, F("building"), F("Gebäude"))
MAKE_PSTR_LIST(heatingPID, F("heatingpid"), F("heating PID"))
MAKE_PSTR_LIST(ibaCalIntTemperature, F("intoffset"), F("Korrektur interner Temperatur"))
MAKE_PSTR_LIST(ibaMinExtTemperature, F("minexttemp"), F("min Aussentemperatur"))
MAKE_PSTR_LIST(backlight, F("backlight"), F("key backlight"))
MAKE_PSTR_LIST(damping, F("damping"), F("Dämpfung der Außentemperatur"))
MAKE_PSTR_LIST(tempsensor1, F("inttemp1"), F("Temperatursensor 1"))
MAKE_PSTR_LIST(tempsensor2, F("inttemp2"), F("Temperatursensor 2"))
MAKE_PSTR_LIST(dampedoutdoortemp, F("dampedoutdoortemp"), F("gedämpfte Aussentemperatur"))
MAKE_PSTR_LIST(floordrystatus, F("floordry"), F("Estrichtrocknung"))
MAKE_PSTR_LIST(floordrytemp, F("floordrytemp"), F("Estrichtrocknungs Temperatur"))
MAKE_PSTR_LIST(brightness, F("brightness"), F("bildschirmhelligkeit"))
MAKE_PSTR_LIST(autodst, F("autodst"), F("automatische sommerzeit umstellung"))
MAKE_PSTR_LIST(preheating, F("preheating"), F("vorheizen im uhrenprogramm"))
MAKE_PSTR_LIST(offtemp, F("offtemp"), F("temperatur bei ausgeschaltetem modus"))
MAKE_PSTR_LIST(mixingvalves, F("mixingvalves"), F("mischventile"))
// thermostat ww
MAKE_PSTR_LIST(wwMode, F("wwmode"), F("modus"))
MAKE_PSTR_LIST(wwSetTempLow, F("wwsettemplow"), F("untere Solltemperatur"))
MAKE_PSTR_LIST(wwCharge, F("wwcharge"), F("charge"))
MAKE_PSTR_LIST(wwChargeDuration, F("wwchargeduration"), F("charge duration"))
MAKE_PSTR_LIST(wwDisinfect, F("wwdisinfect"), F("disinfection"))
MAKE_PSTR_LIST(wwDisinfectDay, F("wwdisinfectday"), F("disinfection day"))
MAKE_PSTR_LIST(wwDisinfectHour, F("wwdisinfecthour"), F("disinfection hour"))
MAKE_PSTR_LIST(wwDisinfectTime, F("wwdisinfecttime"), F("disinfection time"))
MAKE_PSTR_LIST(wwExtra1, F("wwextra1"), F("Kreis 1 Extra"))
MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("Kreis 2 Extra"))
MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating"))
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time"))
MAKE_PSTR_LIST(wwWhenModeOff, F("wwwhenmodeoff"), F("wenn Thermostatmodus ist aus"))
// thermostat hc
MAKE_PSTR_LIST(climate, F("climate"))
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("Sollwert Raumtemperatur"))
MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("aktuelle Raumtemperatur"))
MAKE_PSTR_LIST(mode, F("mode"), F("modus"))
MAKE_PSTR_LIST(modetype, F("modetype"), F("modus Typ"))
MAKE_PSTR_LIST(fastheatup, F("fastheatup"), F("fast heatup"))
MAKE_PSTR_LIST(daytemp, F("daytemp"), F("Tagestemperatur"))
MAKE_PSTR_LIST(daylowtemp, F("daytemp2"), F("Tagestemperatur T2"))
MAKE_PSTR_LIST(daymidtemp, F("daytemp3"), F("Tagestemperatur T3"))
MAKE_PSTR_LIST(dayhightemp, F("daytemp4"), F("Tagestemperatur T4"))
MAKE_PSTR_LIST(heattemp, F("heattemp"), F("Heizen Temperatur"))
MAKE_PSTR_LIST(nighttemp, F("nighttemp"), F("Nachttemperatur"))
MAKE_PSTR_LIST(nighttemp2, F("nighttemp"), F("Nachttemperatur T1"))
MAKE_PSTR_LIST(ecotemp, F("ecotemp"), F("eco Temperatur"))
MAKE_PSTR_LIST(manualtemp, F("manualtemp"), F("manuelle Temperatur"))
MAKE_PSTR_LIST(tempautotemp, F("tempautotemp"), F("zwischenzeitliche Solltemperatur"))
MAKE_PSTR_LIST(comforttemp, F("comforttemp"), F("Komforttemperatur"))
MAKE_PSTR_LIST(summertemp, F("summertemp"), F("Sommertemperatur"))
MAKE_PSTR_LIST(designtemp, F("designtemp"), F("design-Temperatur"))
MAKE_PSTR_LIST(offsettemp, F("offsettemp"), F("Temperaturanhebung"))
MAKE_PSTR_LIST(minflowtemp, F("minflowtemp"), F("min Flusstemperatur"))
MAKE_PSTR_LIST(maxflowtemp, F("maxflowtemp"), F("max Flusstemperatur"))
MAKE_PSTR_LIST(roominfluence, F("roominfluence"), F("Raumeinfluss"))
MAKE_PSTR_LIST(roominfl_factor, F("roominflfactor"), F("Raumeinfluss Factor"))
MAKE_PSTR_LIST(curroominfl, F("curroominfl"), F("aktueller Raumeinfluss"))
MAKE_PSTR_LIST(nofrosttemp, F("nofrosttemp"), F("Frostschutztemperatur"))
MAKE_PSTR_LIST(targetflowtemp, F("targetflowtemp"), F("berechnete Flusstemperatur"))
MAKE_PSTR_LIST(heatingtype, F("heatingtype"), F("Heizungstyp"))
MAKE_PSTR_LIST(summersetmode, F("summersetmode"), F("Einstellung Sommerbetrieb"))
MAKE_PSTR_LIST(hpoperatingmode, F("hpoperatingmode"), F("Wärmepumpe Betriebsmodus"))
MAKE_PSTR_LIST(hpoperatingstate, F("hpoperatingstate"), F("heatpump operating state"))
MAKE_PSTR_LIST(controlmode, F("controlmode"), F("Kontrollmodus"))
MAKE_PSTR_LIST(control, F("control"), F("Fernsteuerung"))
MAKE_PSTR_LIST(wwHolidays, F("wwholidays"), F("holiday dates"))
MAKE_PSTR_LIST(wwVacations, F("wwvacations"), F("vacation dates"))
MAKE_PSTR_LIST(holidays, F("holidays"), F("holiday dates"))
MAKE_PSTR_LIST(vacations, F("vacations"), F("vacation dates"))
MAKE_PSTR_LIST(program, F("program"), F("Programm"))
MAKE_PSTR_LIST(pause, F("pause"), F("Pausenzeit"))
MAKE_PSTR_LIST(party, F("party"), F("Partyzeit"))
MAKE_PSTR_LIST(wwprio, F("wwprio"), F("dhw priority"))
MAKE_PSTR_LIST(holidaytemp, F("holidaytemp"), F("Urlaubstemperatur"))
MAKE_PSTR_LIST(summermode, F("summermode"), F("Sommerbetrieb"))
MAKE_PSTR_LIST(holidaymode, F("holidaymode"), F("Urlaubsbetrieb"))
MAKE_PSTR_LIST(flowtempoffset, F("flowtempoffset"), F("Flusstemperaturanhebung"))
MAKE_PSTR_LIST(reducemode, F("reducemode"), F("Absenkmodus"))
MAKE_PSTR_LIST(noreducetemp, F("noreducetemp"), F("Absenkung unterbrechen unter Temperatur"))
MAKE_PSTR_LIST(reducetemp, F("reducetemp"), F("Absenkmodus unter Temperatur"))
MAKE_PSTR_LIST(vacreducetemp, F("vacreducetemp"), F("Urlaub Absenkmodus unter Temperatur"))
MAKE_PSTR_LIST(vacreducemode, F("vacreducemode"), F("Urlaub Absenkmodus"))
MAKE_PSTR_LIST(nofrostmode, F("nofrostmode"), F("Frostschutz Modus"))
MAKE_PSTR_LIST(nofrostmode1, F("nofrostmode1"), F("nofrost mode")) // RC310
MAKE_PSTR_LIST(remotetemp, F("remotetemp"), F("Raumtemperatur der Fernsteuerung"))
MAKE_PSTR_LIST(reducehours, F("reducehours"), F("duration for nighttemp"))
MAKE_PSTR_LIST(reduceminutes, F("reduceminutes"), F("remaining time for nightmode"))
MAKE_PSTR_LIST(switchonoptimization, F("switchonoptimization"), F("switch-on optimization"))
// heatpump
MAKE_PSTR_LIST(airHumidity, F("airhumidity"), F("relative Luftfeuchte"))
MAKE_PSTR_LIST(dewTemperature, F("dewtemperature"), F("Taupunkttemperatur"))
// mixer
MAKE_PSTR_LIST(flowSetTemp, F("flowsettemp"), F("Sollwert Flusstemperatur"))
MAKE_PSTR_LIST(flowTempHc, F("flowtemphc"), F("Flusstemperatur des hk (TC1)"))
MAKE_PSTR_LIST(pumpStatus, F("pumpstatus"), F("Pumpenstatus des hk (PC1)"))
MAKE_PSTR_LIST(mixerStatus, F("valvestatus"), F("Mischerventil Position (VC1)"))
MAKE_PSTR_LIST(flowTempVf, F("flowtempvf"), F("Flusstemperatur am Kessel (T0/Vf)"))
MAKE_PSTR_LIST(mixerSetTime, F("valvesettime"), F("time to set valve"))
// mixer prefixed with wwc
MAKE_PSTR_LIST(wwPumpStatus, F("pumpstatus"), F("Pumpenstatus des wwk (PC1)"))
MAKE_PSTR_LIST(wwTempStatus, F("tempstatus"), F("Temperaturschalter des wwk (MC1)"))
MAKE_PSTR_LIST(wwTemp, F("wwtemp"), F("aktuelle Temperatur"))
// mixer pool
MAKE_PSTR_LIST(poolSetTemp, F("poolsettemp"), F("pool set temperature"))
MAKE_PSTR_LIST(poolTemp, F("pooltemp"), F("pool temperature"))
MAKE_PSTR_LIST(poolShuntStatus, F("poolshuntstatus"), F("pool shunt status opening/closing"))
MAKE_PSTR_LIST(poolShunt, F("poolshunt"), F("pool shunt open/close (0% = pool / 100% = heat)"))
MAKE_PSTR_LIST(hydrTemp, F("hydrTemp"), F("hydraulic header temperature"))
// solar
MAKE_PSTR_LIST(collectorTemp, F("collectortemp"), F("Kollektortemperatur (TS1)"))
MAKE_PSTR_LIST(collector2Temp, F("collector2temp"), F("collector 2 temperature (TS7)"))
MAKE_PSTR_LIST(cylBottomTemp, F("cylbottomtemp"), F("Speicher Bodentemperatur (TS2)"))
MAKE_PSTR_LIST(cyl2BottomTemp, F("cyl2bottomtemp"), F("2. Speicher Bodentemperatur (TS5)"))
MAKE_PSTR_LIST(heatExchangerTemp, F("heatexchangertemp"), F("wärmetauscher Temperatur (TS6)"))
MAKE_PSTR_LIST(cylMiddleTemp, F("cylmiddletemp"), F("cylinder middle temperature (TS3)"))
MAKE_PSTR_LIST(retHeatAssist, F("retheatassist"), F("return temperature heat assistance (TS4)"))
// correct name for M1? value not found, try this:
MAKE_PSTR_LIST(m1Valve, F("heatassistvalve"), F("heat assistance valve (M1)"))
MAKE_PSTR_LIST(m1Power, F("heatassistpower"), F("heat assistance valve power (M1)"))
MAKE_PSTR_LIST(collectorMaxTemp, F("collectormaxtemp"), F("maximale Kollektortemperatur"))
MAKE_PSTR_LIST(collectorMinTemp, F("collectormintemp"), F("minimale Kollektortemperatur"))
MAKE_PSTR_LIST(cylMaxTemp, F("cylmaxtemp"), F("maximale Speichertemperatur"))
// MAKE_PSTR_LIST(cyl2MaxTemp, F("cyl2maxtemp"), F("maximum cylinder 2 temperature"))
MAKE_PSTR_LIST(solarPumpMod, F("solarpumpmod"), F("Pumpenmodulation (PS1)"))
MAKE_PSTR_LIST(cylPumpMod, F("cylpumpmod"), F("Speicherpumpenmodulation (PS5)"))
MAKE_PSTR_LIST(solarPump, F("solarpump"), F("Pumpe (PS1)"))
MAKE_PSTR_LIST(solarPump2, F("solarpump2"), F("pump 2 (PS4)"))
MAKE_PSTR_LIST(solarPump2Mod, F("solarpump2mod"), F("pump 2 modulation (PS4)"))
MAKE_PSTR_LIST(valveStatus, F("valvestatus"), F("ventilstatus"))
MAKE_PSTR_LIST(cylHeated, F("cylheated"), F("Speichertemperatur erreicht"))
MAKE_PSTR_LIST(collectorShutdown, F("collectorshutdown"), F("Kollektorabschaltung"))
MAKE_PSTR_LIST(pumpWorkTime, F("pumpworktime"), F("Pumpenlaufzeit"))
MAKE_PSTR_LIST(pump2WorkTime, F("pump2worktime"), F("Pumpe 2 Laufzeit"))
MAKE_PSTR_LIST(m1WorkTime, F("m1worktime"), F("Differenzregelung Arbeitszeit"))
MAKE_PSTR_LIST(energyLastHour, F("energylasthour"), F("Energie letzte Std"))
MAKE_PSTR_LIST(energyTotal, F("energytotal"), F("Gesamtenergie"))
MAKE_PSTR_LIST(energyToday, F("energytoday"), F("Energie heute"))
MAKE_PSTR_LIST(pumpMinMod, F("pumpminmod"), F("minimum pump modulation"))
MAKE_PSTR_LIST(maxFlow, F("maxflow"), F("maximum solar flow"))
MAKE_PSTR_LIST(solarPower, F("solarpower"), F("actual solar power"))
MAKE_PSTR_LIST(solarPumpTurnonDiff, F("turnondiff"), F("pump turn on difference"))
MAKE_PSTR_LIST(solarPumpTurnoffDiff, F("turnoffdiff"), F("pump turn off difference"))
MAKE_PSTR_LIST(pump2MinMod, F("pump2minmod"), F("minimum pump 2 modulation"))
MAKE_PSTR_LIST(solarPump2TurnonDiff, F("turnondiff2"), F("pump 2 turn on difference"))
MAKE_PSTR_LIST(solarPump2TurnoffDiff, F("turnoffdiff2"), F("pump 2 turn off difference"))
// solar ww
MAKE_PSTR_LIST(wwTemp1, F("wwtemp1"), F("Temperatur 1"))
MAKE_PSTR_LIST(wwTemp3, F("wwtemp3"), F("Temperatur 3"))
MAKE_PSTR_LIST(wwTemp4, F("wwtemp4"), F("Temperatur 4"))
MAKE_PSTR_LIST(wwTemp5, F("wwtemp5"), F("Temperatur 5"))
MAKE_PSTR_LIST(wwTemp7, F("wwtemp7"), F("Temperatur 7"))
MAKE_PSTR_LIST(wwPump, F("wwpump"), F("Pumpe"))
// solar ww and mixer wwc
MAKE_PSTR_LIST(wwMinTemp, F("wwmintemp"), F("minimale Temperatur"))
MAKE_PSTR_LIST(wwRedTemp, F("wwredtemp"), F("redizierte Temperatur"))
MAKE_PSTR_LIST(wwDailyTemp, F("wwdailytemp"), F("tägl. Temperatur"))
MAKE_PSTR_LIST(wwKeepWarm, F("wwkeepwarm"), F("Warmhalten"))
MAKE_PSTR_LIST(wwStatus2, F("wwstatus2"), F("Status 2"))
MAKE_PSTR_LIST(enum_wwStatus2, F(""), F(""), F(""), F("no_heat"), F(""), F(""), F("heatrequest"), F(""), F("disinfecting"), F("hold"))
MAKE_PSTR_LIST(wwPumpMod, F("wwpumpmod"), F("Pumpen Modulation"))
MAKE_PSTR_LIST(wwFlow, F("wwflow"), F("Flussrate"))
// extra mixer ww
MAKE_PSTR_LIST(wwRequiredTemp, F("wwrequiredtemp"), F("benötigte Temperatur"))
MAKE_PSTR_LIST(wwDiffTemp, F("wwdifftemp"), F("Start Differential Temperatur"))
//SM100
MAKE_PSTR_LIST(heatTransferSystem, F("heattransfersystem"), F("Wärmetransfer System"))
MAKE_PSTR_LIST(externalCyl, F("externalcyl"), F("Externer Speicher"))
MAKE_PSTR_LIST(thermalDisinfect, F("thermaldisinfect"), F("Thermische Desinfektion"))
MAKE_PSTR_LIST(heatMetering, F("heatmetering"), F("Wärmemessung"))
MAKE_PSTR_LIST(solarIsEnabled, F("solarenabled"), F("Solarmodul aktiviert"))
// telegram 0x035A
MAKE_PSTR_LIST(solarPumpMode, F("solarpumpmode"), F("solar Pumpen Einst."))
MAKE_PSTR_LIST(solarPumpKick, F("pumpkick"), F("pumpkick"))
MAKE_PSTR_LIST(plainWaterMode, F("plainwatermode"), F("plain water mode"))
MAKE_PSTR_LIST(doubleMatchFlow, F("doublematchflow"), F("doublematchflow"))
MAKE_PSTR_LIST(solarPump2Mode, F("pump2mode"), F("pump 2 mode"))
MAKE_PSTR_LIST(solarPump2Kick, F("pump2kick"), F("pumpkick 2"))
// telegram 0x035F
MAKE_PSTR_LIST(cylPriority, F("cylpriority"), F("Speicher Priorität"))
// telegram 0x380
MAKE_PSTR_LIST(climateZone, F("climatezone"), F("climate zone"))
MAKE_PSTR_LIST(collector1Area, F("collector1area"), F("Kollektor 1 Fläche"))
MAKE_PSTR_LIST(collector1Type, F("collector1type"), F("Kollektor 1 Type"))
MAKE_PSTR_LIST(collector2Area, F("collector2area"), F("Kollektor 2 Fläche"))
MAKE_PSTR_LIST(collector2Type, F("collector2type"), F("Kollektor 2 Type"))
// telegram 0x0363 heatCounter
MAKE_PSTR_LIST(heatCntFlowTemp, F("heatcntflowtemp"), F("Wärmezähler Fluss-Temperatur"))
MAKE_PSTR_LIST(heatCntRetTemp, F("heatcntrettemp"), F("Wärmezähler Rückfluss-Temperatur"))
MAKE_PSTR_LIST(heatCnt, F("heatcnt"), F("Wärmezäler Impulse"))
MAKE_PSTR_LIST(swapFlowTemp, F("swapflowtemp"), F("Austausch Fluss-Temperatur (TS14)"))
MAKE_PSTR_LIST(swapRetTemp, F("swaprettemp"), F("Austausch Rückfluss-Temperatur (TS15)"))
// switch
MAKE_PSTR_LIST(activated, F("activated"), F("aktiviert"))
MAKE_PSTR_LIST(status, F("status"), F("Status"))
// unknown fields to track (SM10)
MAKE_PSTR_LIST(data11, F("data11"), F("unknown datafield 11"))
MAKE_PSTR_LIST(data12, F("data12"), F("unknown datafield 12"))
MAKE_PSTR_LIST(data8, F("data8"), F("unknown datafield 8"))
MAKE_PSTR_LIST(data0, F("data0"), F("unknown datafield 0"))
MAKE_PSTR_LIST(data1, F("data1"), F("unknown datafield 1"))
MAKE_PSTR_LIST(setting3, F("setting3"), F("unknown setting 3"))
MAKE_PSTR_LIST(setting4, F("setting4"), F("unknown setting 4"))
// RF sensor, id 0x40, telegram 0x435
MAKE_PSTR_LIST(RFTemp, F("rftemp"), F("RF Raumtemperatur Sensor"));

View File

@@ -1,848 +0,0 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// common words
MAKE_PSTR_WORD(debug)
MAKE_PSTR_WORD(exit)
MAKE_PSTR_WORD(help)
MAKE_PSTR_WORD(log)
MAKE_PSTR_WORD(logout)
MAKE_PSTR_WORD(enabled)
MAKE_PSTR_WORD(disabled)
MAKE_PSTR_WORD(set)
MAKE_PSTR_WORD(show)
MAKE_PSTR_WORD(on)
MAKE_PSTR_WORD(off)
MAKE_PSTR_WORD(ON)
MAKE_PSTR_WORD(OFF)
MAKE_PSTR_WORD(su)
MAKE_PSTR_WORD(name)
MAKE_PSTR_WORD(auto)
MAKE_PSTR_WORD(scan)
MAKE_PSTR_WORD(password)
MAKE_PSTR_WORD(read)
MAKE_PSTR_WORD(version)
MAKE_PSTR_WORD(values)
MAKE_PSTR_WORD(system)
MAKE_PSTR_WORD(fetch)
MAKE_PSTR_WORD(restart)
MAKE_PSTR_WORD(format)
MAKE_PSTR_WORD(raw)
MAKE_PSTR_WORD(watch)
MAKE_PSTR_WORD(syslog)
MAKE_PSTR_WORD(send)
MAKE_PSTR_WORD(telegram)
MAKE_PSTR_WORD(bus_id)
MAKE_PSTR_WORD(tx_mode)
MAKE_PSTR_WORD(ems)
MAKE_PSTR_WORD(devices)
MAKE_PSTR_WORD(shower)
MAKE_PSTR_WORD(mqtt)
MAKE_PSTR_WORD(emsesp)
MAKE_PSTR_WORD(connected)
MAKE_PSTR_WORD(disconnected)
MAKE_PSTR_WORD(passwd)
MAKE_PSTR_WORD(hostname)
MAKE_PSTR_WORD(wifi)
MAKE_PSTR_WORD(reconnect)
MAKE_PSTR_WORD(ssid)
MAKE_PSTR_WORD(heartbeat)
MAKE_PSTR_WORD(users)
MAKE_PSTR_WORD(publish)
MAKE_PSTR_WORD(timeout)
MAKE_PSTR_WORD(board_profile)
MAKE_PSTR_WORD(setvalue)
// for commands
MAKE_PSTR_WORD(call)
MAKE_PSTR_WORD(cmd)
MAKE_PSTR_WORD(id)
MAKE_PSTR_WORD(hc)
MAKE_PSTR_WORD(wwc)
MAKE_PSTR_WORD(device)
MAKE_PSTR_WORD(data)
MAKE_PSTR_WORD(command)
MAKE_PSTR_WORD(commands)
MAKE_PSTR_WORD(info)
MAKE_PSTR_WORD(settings)
MAKE_PSTR_WORD(customizations)
MAKE_PSTR_WORD(value)
MAKE_PSTR_WORD(error)
MAKE_PSTR_WORD(entities)
// devices
MAKE_PSTR_WORD(boiler)
MAKE_PSTR_WORD(thermostat)
MAKE_PSTR_WORD(switch)
MAKE_PSTR_WORD(solar)
MAKE_PSTR_WORD(mixer)
MAKE_PSTR_WORD(gateway)
MAKE_PSTR_WORD(controller)
MAKE_PSTR_WORD(connect)
MAKE_PSTR_WORD(heatpump)
MAKE_PSTR_WORD(generic)
MAKE_PSTR_WORD(analogsensor)
MAKE_PSTR_WORD(unknown)
MAKE_PSTR_WORD(dallassensor)
// format strings
MAKE_PSTR(host_fmt, "Host: %s")
MAKE_PSTR(port_fmt, "Port: %d")
MAKE_PSTR(hostname_fmt, "Hostname: %s")
MAKE_PSTR(board_profile_fmt, "Board Profile: %s")
MAKE_PSTR(mark_interval_fmt, "Mark interval: %lus")
MAKE_PSTR(wifi_ssid_fmt, "WiFi SSID: %s")
MAKE_PSTR(wifi_password_fmt, "WiFi Password: %S")
MAKE_PSTR(tx_mode_fmt, "Tx mode: %d")
MAKE_PSTR(bus_id_fmt, "Bus ID: %02X")
MAKE_PSTR(log_level_fmt, "Log level: %s")
MAKE_STR(productid_fmt, "%s EMS ProductID")
MAKE_PSTR_LIST(enum_syslog_level, F_(off), F("emerg"), F("alert"), F("crit"), F_(error), F("warn"), F("notice"), F_(info), F_(debug), F("trace"), F("all"))
MAKE_PSTR_LIST(enum_watch, F_(off), F_(on), F_(raw), F_(unknown))
MAKE_PSTR_LIST(enum_sensortype, F("none"), F("digital in"), F("counter"), F("adc"), F("timer"), F("rate"), F("digital out"), F("pwm 0"), F("pwm 1"), F("pwm 2"))
// strings
MAKE_PSTR(EMSESP, "EMS-ESP")
MAKE_PSTR(cmd_optional, "[cmd]")
MAKE_PSTR(ha_optional, "[ha]")
MAKE_PSTR(deep_optional, "[deep]")
MAKE_PSTR(watchid_optional, "[ID]")
MAKE_PSTR(watch_format_optional, "[off | on | raw | unknown]")
MAKE_PSTR(invalid_watch, "Invalid watch type")
MAKE_PSTR(data_mandatory, "\"XX XX ...\"")
MAKE_PSTR(asterisks, "********")
MAKE_PSTR(n_mandatory, "<n>")
MAKE_PSTR(sensorid_optional, "[sensor ID]")
MAKE_PSTR(id_optional, "[id|hc]")
MAKE_PSTR(data_optional, "[data]")
MAKE_PSTR(offset_optional, "[offset]")
MAKE_PSTR(length_optional, "[length]")
MAKE_PSTR(typeid_mandatory, "<type ID>")
MAKE_PSTR(deviceid_mandatory, "<device ID>")
MAKE_PSTR(device_type_optional, "[device]")
MAKE_PSTR(invalid_log_level, "Invalid log level")
MAKE_PSTR(log_level_optional, "[level]")
MAKE_PSTR(name_mandatory, "<name>")
MAKE_PSTR(name_optional, "[name]")
MAKE_PSTR(new_password_prompt1, "Enter new password: ")
MAKE_PSTR(new_password_prompt2, "Retype new password: ")
MAKE_PSTR(password_prompt, "Password: ")
MAKE_PSTR(unset, "<unset>")
// command descriptions
MAKE_PSTR(info_cmd, "lists all values")
MAKE_PSTR(commands_cmd, "lists all commands")
MAKE_PSTR(entities_cmd, "lists all entities")
MAKE_PSTR_WORD(number)
MAKE_PSTR_WORD(enum)
MAKE_PSTR_WORD(text)
MAKE_PSTR_WORD(2)
MAKE_PSTR_WORD(4)
MAKE_PSTR_WORD(10)
MAKE_PSTR_WORD(100)
MAKE_PSTR_WORD(60)
MAKE_PSTR_LIST(div2, F_(2))
MAKE_PSTR_LIST(div4, F_(4))
MAKE_PSTR_LIST(div10, F_(10))
MAKE_PSTR_LIST(div60, F_(60))
MAKE_PSTR_LIST(div100, F_(100))
MAKE_PSTR_LIST(mul5, F("-5"))
MAKE_PSTR_LIST(mul10, F("-10"))
MAKE_PSTR_LIST(mul15, F("-15"))
// Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp
// uom - also used with HA see https://github.com/home-assistant/core/blob/d7ac4bd65379e11461c7ce0893d3533d8d8b8cbf/homeassistant/const.py#L384
MAKE_PSTR(blank, " ")
MAKE_PSTR(percent, "%")
MAKE_PSTR(degrees, "°C")
MAKE_PSTR(kwh, "kWh")
MAKE_PSTR(wh, "Wh")
MAKE_PSTR(bar, "bar")
MAKE_PSTR(minutes, "minutes")
MAKE_PSTR(hours, "hours")
MAKE_PSTR(days, "days")
MAKE_PSTR(ua, "uA")
MAKE_PSTR(lmin, "l/min")
MAKE_PSTR(kw, "kW")
MAKE_PSTR(w, "W")
MAKE_PSTR(kb, "KB")
MAKE_PSTR(seconds, "seconds")
MAKE_PSTR(dbm, "dBm")
MAKE_PSTR(fahrenheit, "°F")
MAKE_PSTR(mv, "mV")
MAKE_PSTR(sqm, "sqm")
MAKE_PSTR(m3, "m3")
MAKE_PSTR(l, "l")
// MAKE_PSTR(times, "times")
// MAKE_PSTR(oclock, "o'clock")
// TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp
// use empty string if want to suppress showing tags
// mqtt tags must not have spaces
MAKE_PSTR(tag_none, "")
MAKE_PSTR(tag_heartbeat, "")
MAKE_PSTR(tag_boiler_data_ww, "dhw")
MAKE_PSTR(tag_device_data, "")
MAKE_PSTR(tag_device_data_ww, "dhw")
MAKE_PSTR(tag_hc1, "hc1")
MAKE_PSTR(tag_hc2, "hc2")
MAKE_PSTR(tag_hc3, "hc3")
MAKE_PSTR(tag_hc4, "hc4")
MAKE_PSTR(tag_hc5, "hc5")
MAKE_PSTR(tag_hc6, "hc6")
MAKE_PSTR(tag_hc7, "hc7")
MAKE_PSTR(tag_hc8, "hc8")
MAKE_PSTR(tag_wwc1, "wwc1")
MAKE_PSTR(tag_wwc2, "wwc2")
MAKE_PSTR(tag_wwc3, "wwc3")
MAKE_PSTR(tag_wwc4, "wwc4")
MAKE_PSTR(tag_wwc5, "wwc5")
MAKE_PSTR(tag_wwc6, "wwc6")
MAKE_PSTR(tag_wwc7, "wwc7")
MAKE_PSTR(tag_wwc8, "wwc8")
MAKE_PSTR(tag_wwc9, "wwc9")
MAKE_PSTR(tag_wwc10, "wwc10")
MAKE_PSTR(tag_ahs, "ahs")
MAKE_PSTR(tag_hs1, "hs1")
MAKE_PSTR(tag_hs2, "hs2")
MAKE_PSTR(tag_hs3, "hs3")
MAKE_PSTR(tag_hs4, "hs4")
MAKE_PSTR(tag_hs5, "hs5")
MAKE_PSTR(tag_hs6, "hs6")
MAKE_PSTR(tag_hs7, "hs7")
MAKE_PSTR(tag_hs8, "hs8")
MAKE_PSTR(tag_hs9, "hs9")
MAKE_PSTR(tag_hs10, "hs10")
MAKE_PSTR(tag_hs11, "hs11")
MAKE_PSTR(tag_hs12, "hs12")
MAKE_PSTR(tag_hs13, "hs13")
MAKE_PSTR(tag_hs14, "hs14")
MAKE_PSTR(tag_hs15, "hs15")
MAKE_PSTR(tag_hs16, "hs16")
// MQTT topic names
// MAKE_PSTR(tag_heartbeat_mqtt, "heartbeat")
// MAKE_PSTR(tag_boiler_data_mqtt, "")
MAKE_PSTR(tag_boiler_data_ww_mqtt, "ww")
MAKE_PSTR(tag_device_data_ww_mqtt, "")
// boiler
MAKE_PSTR_WORD(time)
MAKE_PSTR_WORD(date)
MAKE_PSTR_WORD(1x3min)
MAKE_PSTR_WORD(2x3min)
MAKE_PSTR_WORD(3x3min)
MAKE_PSTR_WORD(4x3min)
MAKE_PSTR_WORD(5x3min)
MAKE_PSTR_WORD(6x3min)
MAKE_PSTR_WORD(continuous)
MAKE_PSTR(3wayvalve, "3-way valve")
MAKE_PSTR(chargepump, "charge pump")
MAKE_PSTR_WORD(hot)
MAKE_PSTR_WORD(high_comfort)
MAKE_PSTR_WORD(eco)
MAKE_PSTR_WORD(intelligent)
MAKE_PSTR_WORD(flow)
MAKE_PSTR_WORD(manual)
MAKE_PSTR_WORD(buffer)
MAKE_PSTR(bufferedflow, "buffered flow")
MAKE_PSTR(layeredbuffer, "layered buffer")
MAKE_PSTR_WORD(maintenance)
MAKE_PSTR_WORD(heating)
MAKE_PSTR_WORD(cooling)
// boiler lists
MAKE_PSTR_LIST(tpl_date, F("Format: < dd.mm.yyyy >")) // template for text input
MAKE_PSTR_LIST(enum_off_time_date_manual, F_(off), F_(time), F_(date), F_(manual))
MAKE_PSTR_LIST(enum_freq, F_(off), F_(1x3min), F_(2x3min), F_(3x3min), F_(4x3min), F_(5x3min), F_(6x3min), F_(continuous))
MAKE_PSTR_LIST(enum_charge, F_(chargepump), F_(3wayvalve))
MAKE_PSTR_LIST(enum_comfort, F_(hot), F_(eco), F_(intelligent))
MAKE_PSTR_LIST(enum_comfort1, F_(high_comfort), F_(eco))
MAKE_PSTR_LIST(enum_flow, F_(off), F_(flow), F_(bufferedflow), F_(buffer), F_(layeredbuffer))
MAKE_PSTR_LIST(enum_reset, F("-"), F_(maintenance), F_(error))
// MAKE_PSTR_LIST(enum_bool, F_(off), F_(on))
// AM200 lists
MAKE_PSTR_LIST(enum_vr2Config, F_(off), F("bypass"));
MAKE_PSTR_LIST(enum_aPumpSignal, F_(off), F("pwm"), F("pwm_invers"));
MAKE_PSTR_LIST(enum_bufBypass, F("no"), F_(mixer), F("valve"));
MAKE_PSTR_LIST(enum_bufConfig, F("monovalent"), F("bivalent"));
MAKE_PSTR_LIST(enum_blockMode, F_(off), F_(auto), F("blocking"));
MAKE_PSTR_LIST(enum_blockTerm, F("n_o"), F("n_c"));
//heatpump
MAKE_PSTR_LIST(enum_hpactivity, F("none"), F_(heating), F_(cooling), F("hot_water"), F("pool"))
// mixer
MAKE_PSTR_LIST(enum_shunt, F("stopped"), F("opening"), F("closing"), F("open"), F("close"))
// thermostat
MAKE_PSTR_WORD(light)
MAKE_PSTR_WORD(medium)
MAKE_PSTR_WORD(heavy)
MAKE_PSTR_WORD(own_prog)
MAKE_PSTR_WORD(start)
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(high)
MAKE_PSTR_WORD(low)
MAKE_PSTR_WORD(radiator)
MAKE_PSTR_WORD(convector)
MAKE_PSTR_WORD(floor)
MAKE_PSTR_WORD(summer)
MAKE_PSTR_WORD(winter)
MAKE_PSTR_WORD(outdoor)
MAKE_PSTR_WORD(mpc)
MAKE_PSTR_WORD(room)
MAKE_PSTR_WORD(room_outdoor)
MAKE_PSTR_WORD(power)
MAKE_PSTR_WORD(constant)
MAKE_PSTR_WORD(simple)
MAKE_PSTR_WORD(optimized)
MAKE_PSTR_WORD(nofrost)
MAKE_PSTR_WORD(comfort)
MAKE_PSTR_WORD(night)
MAKE_PSTR_WORD(day)
MAKE_PSTR_WORD(holiday)
MAKE_PSTR_WORD(reduce)
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(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(functioning_mode, "functioning mode")
MAKE_PSTR(smoke_temperature, "smoke temperature")
// thermostat lists
MAKE_PSTR_LIST(tpl_datetime, F("Format: < NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >"))
MAKE_PSTR_LIST(tpl_switchtime, F("Format: <nn> [ not_set | day hh:mm on|off ]"))
MAKE_PSTR_LIST(tpl_switchtime1, F("Format: <nn> [ not_set | day hh:mm Tn ]"))
MAKE_PSTR_LIST(tpl_holidays, F("format: < dd.mm.yyyy-dd.mm.yyyy >"))
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_ibaLanguage_RC30, F_(german), F_(dutch))
MAKE_PSTR_LIST(enum_floordrystatus, F_(off), F_(start), F_(heat), F_(hold), F_(cool), F_(end))
MAKE_PSTR_LIST(enum_ibaBuildingType, F_(light), F_(medium), F_(heavy))
MAKE_PSTR_LIST(enum_PID, F("fast"), F_(medium), F("slow"))
MAKE_PSTR_LIST(enum_wwMode, F_(off), F("normal"), F_(comfort), F_(auto), F_(own_prog), F_(eco))
MAKE_PSTR_LIST(enum_wwCircMode, F_(off), F_(on), F_(auto), F_(own_prog))
MAKE_PSTR_LIST(enum_wwMode2, F_(off), F_(on), F_(auto))
MAKE_PSTR_LIST(enum_wwMode3, F_(on), F_(off), F_(auto))
MAKE_PSTR_LIST(enum_heatingtype, F_(off), F_(radiator), F_(convector), F_(floor))
MAKE_PSTR_LIST(enum_summermode, F_(summer), F_(auto), F_(winter))
MAKE_PSTR_LIST(enum_hpoperatingmode, F_(off), F_(auto), F_(heating), F_(cooling))
MAKE_PSTR_LIST(enum_summer, F_(winter), F_(summer))
MAKE_PSTR_LIST(enum_operatingstate, F_(heating), F_(off), F_(cooling))
MAKE_PSTR_LIST(enum_mode, F_(manual), F_(auto)) // RC100, RC300, RC310
MAKE_PSTR_LIST(enum_mode2, F_(off), F_(manual), F_(auto)) // RC20
MAKE_PSTR_LIST(enum_mode3, F_(night), F_(day), F_(auto)) // RC35, RC30, RC25
MAKE_PSTR_LIST(enum_mode4, F_(nofrost), F_(eco), F_(heat), F_(auto)) // JUNKERS
MAKE_PSTR_LIST(enum_mode5, F_(auto), F_(off)) // CRF
MAKE_PSTR_LIST(enum_mode6, F_(nofrost), F_(night), F_(day)) // RC10
MAKE_PSTR_LIST(enum_modetype, F_(eco), F_(comfort))
// MAKE_PSTR_LIST(enum_modetype2, F_(day))
MAKE_PSTR_LIST(enum_modetype3, F_(night), F_(day))
MAKE_PSTR_LIST(enum_modetype4, F_(nofrost), F_(eco), F_(heat))
MAKE_PSTR_LIST(enum_modetype5, F_(off), F_(on))
MAKE_PSTR_LIST(enum_reducemode, F_(nofrost), F_(reduce), F_(room), F_(outdoor))
MAKE_PSTR_LIST(enum_reducemode1, F_(outdoor), F_(room), F_(reduce)) // RC310 values: 1-3
MAKE_PSTR_LIST(enum_nofrostmode, F_(off), F_(room), F_(outdoor))
MAKE_PSTR_LIST(enum_nofrostmode1, F_(room), F_(outdoor), F_(room_outdoor))
MAKE_PSTR_LIST(enum_controlmode, F_(off), F_(optimized), F_(simple), F_(mpc), F_(room), F_(power), F_(constant))
MAKE_PSTR_LIST(enum_controlmode1, F("weather-compensated"), F("outside-basepoint"), F("n/a"), F_(room)) // RC310 1-4
MAKE_PSTR_LIST(enum_controlmode2, F_(outdoor), F_(room))
// MAKE_PSTR_LIST(enum_controlmode3, F_(off), F_(room), F_(outdoor), F("room+outdoor"))
MAKE_PSTR_LIST(enum_control, F_(off), F_(rc20), F_(rc3x))
MAKE_PSTR_LIST(enum_j_control, F_(off), F("fb10"), F("fb100"))
MAKE_PSTR_LIST(enum_wwProgMode, F("std_prog"), F_(own_prog))
MAKE_PSTR_LIST(enum_dayOfWeek, F("mo"), F("tu"), F("we"), F("th"), F("fr"), F("sa"), F("su"), F("all"))
MAKE_PSTR_LIST(enum_progMode, F("prog_1"), F("prog_2"))
MAKE_PSTR_LIST(enum_progMode2, F("own_1"), F("family"), F("morning"), F("evening"), F("am"), F("pm"), F("midday"), F("singles"), F("seniors"), F("new"), F("own_2"))
MAKE_PSTR_LIST(enum_progMode3, F("family"), F("morning"), F("evening"), F("am"), F("pm"), F("midday"), F("singles"), F("seniors"))
MAKE_PSTR_LIST(enum_progMode4, F("prog_a"), F("prog_b"), F("prog_c"), F("prog_d"), F("prog_e"), F("prog_f"))
MAKE_PSTR_LIST(enum_switchmode, F_(off), F_(eco), F_(comfort), F_(heat))
MAKE_PSTR_LIST(enum_climate, F("selTemp"), F("roomTemp"))
// solar list
MAKE_PSTR_LIST(enum_solarmode, F_(constant), F("pwm"), F("analog"))
MAKE_PSTR_LIST(enum_collectortype, F("flat"), F("vacuum"))
MAKE_PSTR_LIST(enum_cylprio, F("cyl_1"), F("cyl_2"))
// id used to store the device ID. empty full name so only gets displayed in the MQTT payload
MAKE_PSTR_LIST(ID, F_(id))
// Boiler
// extra commands, with no json output
MAKE_PSTR_LIST(wwtapactivated, F("wwtapactivated"), F("turn on/off"))
MAKE_PSTR_LIST(reset, F("reset"), F("reset"))
// single mqtt topics
MAKE_PSTR_WORD(heating_active)
MAKE_PSTR_WORD(tapwater_active)
MAKE_PSTR_WORD(response)
// mqtt, commands and text
MAKE_PSTR_LIST(heatingActive, F("heatingactive"), F("heating active"))
MAKE_PSTR_LIST(tapwaterActive, F("tapwateractive"), F("tapwater active"))
MAKE_PSTR_LIST(selFlowTemp, F("selflowtemp"), F("selected flow temperature"))
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(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"))
MAKE_PSTR_LIST(boilTemp, F("boiltemp"), F("actual boiler temperature"))
MAKE_PSTR_LIST(exhaustTemp, F("exhausttemp"), F("exhaust temperature"))
MAKE_PSTR_LIST(burnGas, F("burngas"), F("gas"))
MAKE_PSTR_LIST(burnGas2, F("burngas2"), F("gas stage 2"))
MAKE_PSTR_LIST(flameCurr, F("flamecurr"), F("flame current"))
MAKE_PSTR_LIST(heatingPump, F("heatingpump"), F("heating pump"))
MAKE_PSTR_LIST(fanWork, F("fanwork"), F("fan"))
MAKE_PSTR_LIST(ignWork, F("ignwork"), F("ignition"))
MAKE_PSTR_LIST(oilPreHeat, F("oilpreheat"), F("oil preheating"))
MAKE_PSTR_LIST(heatingActivated, F("heatingactivated"), F("heating activated"))
MAKE_PSTR_LIST(heatingTemp, F("heatingtemp"), F("heating temperature"))
MAKE_PSTR_LIST(pumpModMax, F("pumpmodmax"), F("burner pump max power"))
MAKE_PSTR_LIST(pumpModMin, F("pumpmodmin"), F("burner pump min power"))
MAKE_PSTR_LIST(pumpDelay, F("pumpdelay"), F("pump delay"))
MAKE_PSTR_LIST(burnMinPeriod, F("burnminperiod"), F("burner min period"))
MAKE_PSTR_LIST(burnMinPower, F("burnminpower"), F("burner min power"))
MAKE_PSTR_LIST(burnMaxPower, F("burnmaxpower"), F("burner max power"))
MAKE_PSTR_LIST(boilHystOn, F("boilhyston"), F("hysteresis on temperature"))
MAKE_PSTR_LIST(boilHystOff, F("boilhystoff"), F("hysteresis off temperature"))
MAKE_PSTR_LIST(setFlowTemp, F("setflowtemp"), F("set flow temperature"))
MAKE_PSTR_LIST(setBurnPow, F("setburnpow"), F("burner set power"))
MAKE_PSTR_LIST(curBurnPow, F("curburnpow"), F("burner current power"))
MAKE_PSTR_LIST(burnStarts, F("burnstarts"), F("burner starts"))
MAKE_PSTR_LIST(burnWorkMin, F("burnworkmin"), F("total burner operating time"))
MAKE_PSTR_LIST(burn2WorkMin, F("burn2workmin"), F("burner stage 2 operating time"))
MAKE_PSTR_LIST(heatWorkMin, F("heatworkmin"), F("total heat operating time"))
MAKE_PSTR_LIST(UBAuptime, F("ubauptime"), F("total UBA operating time"))
MAKE_PSTR_LIST(lastCode, F("lastcode"), F("last error code"))
MAKE_PSTR_LIST(serviceCode, F("servicecode"), F("service code"))
MAKE_PSTR_LIST(serviceCodeNumber, F("servicecodenumber"), F("service code number"))
MAKE_PSTR_LIST(maintenanceMessage, F("maintenancemessage"), F("maintenance message"))
MAKE_PSTR_LIST(maintenanceDate, F("maintenancedate"), F("next maintenance date"))
MAKE_PSTR_LIST(maintenanceType, F_(maintenance), F("maintenance scheduled"))
MAKE_PSTR_LIST(maintenanceTime, F("maintenancetime"), F("time to next maintenance"))
MAKE_PSTR_LIST(emergencyOps, F("emergencyops"), F("emergency operation"))
MAKE_PSTR_LIST(emergencyTemp, F("emergencytemp"), F("emergency temperature"))
// heatpump/compress specific
MAKE_PSTR_LIST(upTimeControl, F("uptimecontrol"), F("total operating time heat"))
MAKE_PSTR_LIST(upTimeCompHeating, F("uptimecompheating"), F("operating time compressor heating"))
MAKE_PSTR_LIST(upTimeCompCooling, F("uptimecompcooling"), F("operating time compressor cooling"))
MAKE_PSTR_LIST(upTimeCompWw, F("uptimecompww"), F("operating time compressor dhw"))
MAKE_PSTR_LIST(upTimeCompPool, F("uptimecomppool"), F("operating time compressor pool"))
MAKE_PSTR_LIST(totalCompStarts, F("totalcompstarts"), F("total compressor control starts"))
MAKE_PSTR_LIST(heatingStarts, F("heatingstarts"), F("heating control starts"))
MAKE_PSTR_LIST(coolingStarts, F("coolingstarts"), F("cooling control starts"))
MAKE_PSTR_LIST(poolStarts, F("poolstarts"), F("pool control starts"))
MAKE_PSTR_LIST(nrgConsTotal, F("nrgconstotal"), F("total energy consumption"))
MAKE_PSTR_LIST(nrgConsCompTotal, F("nrgconscomptotal"), F("total energy consumption compressor"))
MAKE_PSTR_LIST(nrgConsCompHeating, F("nrgconscompheating"), F("energy consumption compressor heating"))
MAKE_PSTR_LIST(nrgConsCompWw, F("nrgconscompww"), F("energy consumption compressor dhw"))
MAKE_PSTR_LIST(nrgConsCompCooling, F("nrgconscompcooling"), F("energy consumption compressor cooling"))
MAKE_PSTR_LIST(nrgConsCompPool, F("nrgconscomppool"), F("energy consumption compressor pool"))
MAKE_PSTR_LIST(nrgSuppTotal, F("nrgsupptotal"), F("total energy supplied"))
MAKE_PSTR_LIST(nrgSuppHeating, F("nrgsuppheating"), F("total energy supplied heating"))
MAKE_PSTR_LIST(nrgSuppWw, F("nrgsuppww"), F("total energy warm supplied dhw"))
MAKE_PSTR_LIST(nrgSuppCooling, F("nrgsuppcooling"), F("total energy supplied cooling"))
MAKE_PSTR_LIST(nrgSuppPool, F("nrgsupppool"), F("total energy supplied pool"))
MAKE_PSTR_LIST(auxElecHeatNrgConsTotal, F("auxelecheatnrgconstotal"), F("total auxiliary electrical heater energy consumption"))
MAKE_PSTR_LIST(auxElecHeatNrgConsHeating, F("auxelecheatnrgconsheating"), F("auxiliary electrical heater energy consumption heating"))
MAKE_PSTR_LIST(auxElecHeatNrgConsWW, F("auxelecheatnrgconsww"), F("auxiliary electrical heater energy consumption dhw"))
MAKE_PSTR_LIST(auxElecHeatNrgConsPool, F("auxelecheatnrgconspool"), F("auxiliary electrical heater energy consumption pool"))
MAKE_PSTR_LIST(hpPower, F("hppower"), F("compressor power output"))
MAKE_PSTR_LIST(hpCompOn, F("hpcompon"), F("hp compressor"))
MAKE_PSTR_LIST(hpHeatingOn, F("hpheatingon"), F("hp heating"))
MAKE_PSTR_LIST(hpCoolingOn, F("hpcoolingon"), F("hp cooling"))
MAKE_PSTR_LIST(hpWwOn, F("hpwwon"), F("hp dhw"))
MAKE_PSTR_LIST(hpPoolOn, F("hppoolon"), F("hp pool"))
MAKE_PSTR_LIST(hpBrinePumpSpd, F("hpbrinepumpspd"), F("brine pump speed"))
MAKE_PSTR_LIST(hpCompSpd, F("hpcompspd"), F("compressor speed"))
MAKE_PSTR_LIST(hpCircSpd, F("hpcircspd"), F("circulation pump speed"))
MAKE_PSTR_LIST(hpBrineIn, F("hpbrinein"), F("brine in/evaporator"))
MAKE_PSTR_LIST(hpBrineOut, F("hpbrineout"), F("brine out/condenser"))
MAKE_PSTR_LIST(hpSuctionGas, F("hpsuctiongas"), F("suction gas"))
MAKE_PSTR_LIST(hpHotGas, F("hphotgas"), F("hot gas/compressed"))
MAKE_PSTR_LIST(hpSwitchValve, F("hpswitchvalve"), F("switch valve"))
MAKE_PSTR_LIST(hpActivity, F("hpactivity"), F("compressor activity"))
MAKE_PSTR_LIST(hpTc0, F("hptc0"), F("heat carrier return (TC0)"))
MAKE_PSTR_LIST(hpTc1, F("hptc1"), F("heat carrier forward (TC1)"))
MAKE_PSTR_LIST(hpTc3, F("hptc3"), F("condenser temperature (TC3)"))
MAKE_PSTR_LIST(hpTr3, F("hptr3"), F("refrigerant temperature liquid side (condenser output) (TR3)"))
MAKE_PSTR_LIST(hpTr4, F("hptr4"), F("evaporator inlet temperature (TR4)"))
MAKE_PSTR_LIST(hpTr5, F("hptr5"), F("compressor Inlet temperature (TR5)"))
MAKE_PSTR_LIST(hpTr6, F("hptr6"), F("compressor outlet temperature (TR6)"))
MAKE_PSTR_LIST(hpTr7, F("hptr7"), F("refrigerant temperature gas side (condenser input) (TR7)"))
MAKE_PSTR_LIST(hpTl2, F("hptl2"), F("air inlet temperature (TL2)"))
MAKE_PSTR_LIST(hpPl1, F("hppl1"), F("low pressure side temperature (PL1)"))
MAKE_PSTR_LIST(hpPh1, F("hpph1"), F("high pressure side temperature (PH1)"))
// hybrid heatpump
MAKE_PSTR_LIST(enum_hybridStrategy, F("co2-optimized"), F("cost-optimized"), F("outside-temp-switched"), F("co2-cost-mix"))
MAKE_PSTR_LIST(hybridStrategy, F("hybridstrategy"), F("hybrid control strategy"))
MAKE_PSTR_LIST(switchOverTemp, F("switchovertemp"), F("outside switchover temperature"))
MAKE_PSTR_LIST(energyCostRatio, F("energycostratio"), F("energy cost ratio"))
MAKE_PSTR_LIST(fossileFactor, F("fossilefactor"), F("fossile energy factor"))
MAKE_PSTR_LIST(electricFactor, F("electricfactor"), F("electric energy factor"))
MAKE_PSTR_LIST(delayBoiler, F("delayboiler"), F("delay boiler support"))
MAKE_PSTR_LIST(tempDiffBoiler, F("tempdiffboiler"), F("tempediff boiler support"))
// alternative heatsource AM200
MAKE_PSTR_LIST(aCylTopTemp, F("cyltoptemp"), F("cylinder top temperature"))
MAKE_PSTR_LIST(aCylCenterTemp, F("cylcentertemp"), F("cylinder center temperature"))
MAKE_PSTR_LIST(aCylBottomTemp, F("cylbottomtemp"), F("cylinder bottom temperature"))
MAKE_PSTR_LIST(aFlowTemp, F("altflowtemp"), F("alternative hs flow temperature"))
MAKE_PSTR_LIST(aRetTemp, F("altrettemp"), F("alternative hs return temperature"))
MAKE_PSTR_LIST(sysFlowTemp, F("sysflowtemp"), F("system flow temperature"))
MAKE_PSTR_LIST(sysRetTemp, F("sysrettemp"), F("system return temperature"))
MAKE_PSTR_LIST(valveByPass, F("valvebypass"), F("bypass valve"))
MAKE_PSTR_LIST(valveBuffer, F("valvebuffer"), F("buffer valve"))
MAKE_PSTR_LIST(valveReturn, F("valvereturn"), F("return valve"))
MAKE_PSTR_LIST(aPumpMod, F("altpumpmod"), F("alternative hs pump modulation"))
MAKE_PSTR_LIST(heatSource, F("heatsource"), F("alternative heating active"))
MAKE_PSTR_LIST(vr2Config, F("vr2config"), F("vr2 configuration"))
MAKE_PSTR_LIST(ahsActivated, F("ahsactivated"), F("alternate heat source activation"))
MAKE_PSTR_LIST(aPumpConfig, F("apumpconfig"), F("primary pump config"))
MAKE_PSTR_LIST(aPumpSignal, F("apumpsignal"), F("output for pr1 pump"))
MAKE_PSTR_LIST(aPumpMin, F("apumpmin"), F("min output pump pr1"))
MAKE_PSTR_LIST(tempRise, F("temprise"), F("ahs return temp rise"))
MAKE_PSTR_LIST(setReturnTemp, F("setreturntemp"), F("set temp return"))
MAKE_PSTR_LIST(mixRuntime, F("mixruntime"), F("mixer run time"))
// MAKE_PSTR_LIST(setFlowTemp, F("setflowtemp"), F("set flow temp"))
MAKE_PSTR_LIST(bufBypass, F("bufbypass"), F("buffer bypass config"))
MAKE_PSTR_LIST(bufMixRuntime, F("bufmixruntime"), F("bypass mixer run time"))
MAKE_PSTR_LIST(bufConfig, F("bufconfig"), F("dhw buffer config"))
MAKE_PSTR_LIST(blockMode, F("blockmode"), F("config htg. blocking mode"))
MAKE_PSTR_LIST(blockTerm, F("blockterm"), F("config of block terminal"))
MAKE_PSTR_LIST(blockHyst, F("blockhyst"), F("hyst. for bolier block"))
MAKE_PSTR_LIST(releaseWait, F("releasewait"), F("boiler release wait time"))
// the following are dhw for the boiler and automatically tagged with 'ww'
MAKE_PSTR_LIST(wwSelTemp, F("wwseltemp"), F("selected temperature"))
MAKE_PSTR_LIST(wwSelTempLow, F("wwseltemplow"), F("selected lower temperature"))
MAKE_PSTR_LIST(wwSelTempOff, F("wwseltempoff"), F("selected temperature for off"))
MAKE_PSTR_LIST(wwSelTempSingle, F("wwseltempsingle"), F("single charge 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(wwComfort1, F("wwcomfort1"), F("comfort mode"))
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"))
MAKE_PSTR_LIST(wwCircMode, F("wwcircmode"), F("circulation pump mode")) // also used in thermostat
MAKE_PSTR_LIST(wwCirc, F("wwcirc"), F("circulation active"))
MAKE_PSTR_LIST(wwCurTemp, F("wwcurtemp"), F("current intern temperature"))
MAKE_PSTR_LIST(wwCurTemp2, F("wwcurtemp2"), F("current extern temperature"))
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(wwDisinfecting, F("wwdisinfecting"), F("disinfecting"))
MAKE_PSTR_LIST(wwCharging, F("wwcharging"), F("charging"))
MAKE_PSTR_LIST(wwChargeOptimization, F("wwchargeoptimization"), F("charge optimization"))
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(ww3wayValve, F("ww3wayvalve"), F("3way valve active"))
MAKE_PSTR_LIST(wwSetPumpPower, F("wwsetpumppower"), F("set pump power"))
MAKE_PSTR_LIST(wwMixerTemp, F("wwmixertemp"), F("mixer temperature"))
MAKE_PSTR_LIST(wwCylMiddleTemp, F("wwcylmiddletemp"), F("cylinder middle temperature (TS3)"))
MAKE_PSTR_LIST(wwStarts, F("wwstarts"), F("starts"))
MAKE_PSTR_LIST(wwStarts2, F("wwstarts2"), F("control starts2"))
MAKE_PSTR_LIST(wwWorkM, F("wwworkm"), F("active time"))
MAKE_PSTR_LIST(wwHystOn, F("wwhyston"), F("hysteresis on temperature"))
MAKE_PSTR_LIST(wwHystOff, F("wwhystoff"), F("hysteresis off temperature"))
MAKE_PSTR_LIST(wwProgMode, F("wwprogmode"), F("program"))
MAKE_PSTR_LIST(wwCircProg, F("wwcircprog"), F("circulation program"))
MAKE_PSTR_LIST(wwMaxTemp, F("wwmaxtemp"), F("maximum temperature"))
MAKE_PSTR_LIST(wwOneTimeKey, F("wwonetimekey"), F("one time key function"))
// mqtt values / commands
MAKE_PSTR_LIST(switchtime, F("switchtime"), F("program switchtime"))
MAKE_PSTR_LIST(switchtime1, F("switchtime1"), F("own1 program switchtime"))
MAKE_PSTR_LIST(switchtime2, F("switchtime2"), F("own2 program switchtime"))
MAKE_PSTR_LIST(wwswitchtime, F("wwswitchtime"), F("program switchtime"))
MAKE_PSTR_LIST(wwcircswitchtime, F("wwcircswitchtime"), F("circulation program switchtime"))
MAKE_PSTR_LIST(dateTime, F("datetime"), F("date/time"))
MAKE_PSTR_LIST(errorCode, F("errorcode"), F("error code"))
MAKE_PSTR_LIST(ibaMainDisplay, F("display"), F("display"))
MAKE_PSTR_LIST(ibaLanguage, F("language"), F("language"))
MAKE_PSTR_LIST(ibaClockOffset, F("clockoffset"), F("clock offset"))
MAKE_PSTR_LIST(ibaBuildingType, F("building"), F("building type"))
MAKE_PSTR_LIST(heatingPID, F("heatingpid"), F("heating PID"))
MAKE_PSTR_LIST(ibaCalIntTemperature, F("intoffset"), F("internal temperature offset"))
MAKE_PSTR_LIST(ibaMinExtTemperature, F("minexttemp"), F("minimal external temperature"))
MAKE_PSTR_LIST(backlight, F("backlight"), F("key backlight"))
MAKE_PSTR_LIST(damping, F("damping"), F("damping outdoor temperature"))
MAKE_PSTR_LIST(tempsensor1, F("inttemp1"), F("temperature sensor 1"))
MAKE_PSTR_LIST(tempsensor2, F("inttemp2"), F("temperature sensor 2"))
MAKE_PSTR_LIST(dampedoutdoortemp, F("dampedoutdoortemp"), F("damped outdoor temperature"))
MAKE_PSTR_LIST(floordrystatus, F("floordry"), F("floor drying"))
MAKE_PSTR_LIST(floordrytemp, F("floordrytemp"), F("floor drying temperature"))
MAKE_PSTR_LIST(brightness, F("brightness"), F("screen brightness"))
MAKE_PSTR_LIST(autodst, F("autodst"), F("automatic change daylight saving time"))
MAKE_PSTR_LIST(preheating, F("preheating"), F("preheating in the clock program"))
MAKE_PSTR_LIST(offtemp, F("offtemp"), F("temperature when mode is off"))
MAKE_PSTR_LIST(mixingvalves, F("mixingvalves"), F("mixing valves"))
// thermostat ww
MAKE_PSTR_LIST(wwMode, F("wwmode"), F("mode"))
MAKE_PSTR_LIST(wwSetTempLow, F("wwsettemplow"), F("set low temperature"))
MAKE_PSTR_LIST(wwCharge, F("wwcharge"), F("charge"))
MAKE_PSTR_LIST(wwChargeDuration, F("wwchargeduration"), F("charge duration"))
MAKE_PSTR_LIST(wwDisinfect, F("wwdisinfect"), F("disinfection"))
MAKE_PSTR_LIST(wwDisinfectDay, F("wwdisinfectday"), F("disinfection day"))
MAKE_PSTR_LIST(wwDisinfectHour, F("wwdisinfecthour"), F("disinfection hour"))
MAKE_PSTR_LIST(wwDisinfectTime, F("wwdisinfecttime"), F("disinfection time"))
MAKE_PSTR_LIST(wwExtra1, F("wwextra1"), F("circuit 1 extra"))
MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("circuit 2 extra"))
MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating"))
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time"))
MAKE_PSTR_LIST(wwWhenModeOff, F("wwwhenmodeoff"), F("when thermostat mode off"))
// thermostat hc
MAKE_PSTR_LIST(climate, F("HA climate config creation")) // no full-name, hidden, only for creation
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("selected room temperature"))
MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("current room temperature"))
MAKE_PSTR_LIST(mode, F("mode"), F("mode"))
MAKE_PSTR_LIST(modetype, F("modetype"), F("mode type"))
MAKE_PSTR_LIST(fastheatup, F("fastheatup"), F("fast heatup"))
MAKE_PSTR_LIST(daytemp, F("daytemp"), F("day temperature"))
MAKE_PSTR_LIST(daylowtemp, F("daytemp2"), F("day temperature T2"))
MAKE_PSTR_LIST(daymidtemp, F("daytemp3"), F("day temperature T3"))
MAKE_PSTR_LIST(dayhightemp, F("daytemp4"), F("day temperature T4"))
MAKE_PSTR_LIST(heattemp, F("heattemp"), F("heat temperature"))
MAKE_PSTR_LIST(nighttemp, F("nighttemp"), F("night temperature"))
MAKE_PSTR_LIST(nighttemp2, F("nighttemp"), F("night temperature T1"))
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 set temperature automode"))
MAKE_PSTR_LIST(remoteseltemp, F("remoteseltemp"), F("temporary set temperature from remote"))
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"))
MAKE_PSTR_LIST(offsettemp, F("offsettemp"), F("offset temperature"))
MAKE_PSTR_LIST(minflowtemp, F("minflowtemp"), F("min flow temperature"))
MAKE_PSTR_LIST(maxflowtemp, F("maxflowtemp"), F("max flow temperature"))
MAKE_PSTR_LIST(roominfluence, F("roominfluence"), F("room influence"))
MAKE_PSTR_LIST(roominfl_factor, F("roominflfactor"), F("room influence factor"))
MAKE_PSTR_LIST(curroominfl, F("curroominfl"), F("current 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(summersetmode, F("summersetmode"), F("set summer mode"))
MAKE_PSTR_LIST(hpoperatingmode, F("hpoperatingmode"), F("heatpump operating mode"))
MAKE_PSTR_LIST(hpoperatingstate, F("hpoperatingstate"), F("heatpump operating state"))
MAKE_PSTR_LIST(controlmode, F("controlmode"), F("control mode"))
MAKE_PSTR_LIST(control, F("control"), F("control device"))
MAKE_PSTR_LIST(wwHolidays, F("wwholidays"), F("holiday dates"))
MAKE_PSTR_LIST(wwVacations, F("wwvacations"), F("vacation dates"))
MAKE_PSTR_LIST(holidays, F("holidays"), F("holiday dates"))
MAKE_PSTR_LIST(vacations, F("vacations"), F("vacation dates"))
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(wwprio, F("wwprio"), F("dhw priority"))
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 for mixer"))
MAKE_PSTR_LIST(reducemode, F("reducemode"), F("reduce mode"))
MAKE_PSTR_LIST(noreducetemp, F("noreducetemp"), F("no reduce below temperature"))
MAKE_PSTR_LIST(reducetemp, F("reducetemp"), F("off/reduce switch temperature"))
MAKE_PSTR_LIST(vacreducetemp, F("vacreducetemp"), F("vacations off/reduce switch temperature"))
MAKE_PSTR_LIST(vacreducemode, F("vacreducemode"), F("vacations reduce mode"))
MAKE_PSTR_LIST(nofrostmode, F("nofrostmode"), F("nofrost mode"))
MAKE_PSTR_LIST(nofrostmode1, F("nofrostmode1"), F("nofrost mode")) // RC310
MAKE_PSTR_LIST(remotetemp, F("remotetemp"), F("room temperature from remote"))
MAKE_PSTR_LIST(reducehours, F("reducehours"), F("duration for nighttemp"))
MAKE_PSTR_LIST(reduceminutes, F("reduceminutes"), F("remaining time for nightmode"))
MAKE_PSTR_LIST(switchonoptimization, F("switchonoptimization"), F("switch-on optimization"))
// heatpump
MAKE_PSTR_LIST(airHumidity, F("airhumidity"), F("relative air humidity"))
MAKE_PSTR_LIST(dewTemperature, F("dewtemperature"), F("dew point temperature"))
// mixer
MAKE_PSTR_LIST(flowSetTemp, F("flowsettemp"), F("setpoint flow temperature"))
MAKE_PSTR_LIST(flowTempHc, F("flowtemphc"), F("flow temperature (TC1)"))
MAKE_PSTR_LIST(pumpStatus, F("pumpstatus"), F("pump status (PC1)"))
MAKE_PSTR_LIST(mixerStatus, F("valvestatus"), F("mixing valve actuator (VC1)"))
MAKE_PSTR_LIST(flowTempVf, F("flowtempvf"), F("flow temperature in header (T0/Vf)"))
MAKE_PSTR_LIST(mixerSetTime, F("valvesettime"), F("time to set valve"))
// mixer prefixed with wwc
MAKE_PSTR_LIST(wwPumpStatus, F("pumpstatus"), F("pump status in assigned wwc (PC1)"))
MAKE_PSTR_LIST(wwTempStatus, F("wwtempstatus"), F("temperature switch in assigned wwc (MC1)"))
MAKE_PSTR_LIST(wwTemp, F("wwtemp"), F("current temperature"))
// mixer pool
MAKE_PSTR_LIST(poolSetTemp, F("poolsettemp"), F("pool set temperature"))
MAKE_PSTR_LIST(poolTemp, F("pooltemp"), F("pool temperature"))
MAKE_PSTR_LIST(poolShuntStatus, F("poolshuntstatus"), F("pool shunt status opening/closing"))
MAKE_PSTR_LIST(poolShunt, F("poolshunt"), F("pool shunt open/close (0% = pool / 100% = heat)"))
MAKE_PSTR_LIST(hydrTemp, F("hydrTemp"), F("hydraulic header temperature"))
// solar
MAKE_PSTR_LIST(collectorTemp, F("collectortemp"), F("collector temperature (TS1)"))
MAKE_PSTR_LIST(collector2Temp, F("collector2temp"), F("collector 2 temperature (TS7)"))
MAKE_PSTR_LIST(cylBottomTemp, F("cylbottomtemp"), F("cylinder bottom temperature (TS2)"))
MAKE_PSTR_LIST(cyl2BottomTemp, F("cyl2bottomtemp"), F("second cylinder bottom temperature (TS5)"))
MAKE_PSTR_LIST(heatExchangerTemp, F("heatexchangertemp"), F("heat exchanger temperature (TS6)"))
MAKE_PSTR_LIST(cylMiddleTemp, F("cylmiddletemp"), F("cylinder middle temperature (TS3)"))
MAKE_PSTR_LIST(retHeatAssist, F("retheatassist"), F("return temperature heat assistance (TS4)"))
// correct name for M1? value not found, try this:
MAKE_PSTR_LIST(m1Valve, F("heatassistvalve"), F("heat assistance valve (M1)"))
MAKE_PSTR_LIST(m1Power, F("heatassistpower"), F("heat assistance valve power (M1)"))
MAKE_PSTR_LIST(collectorMaxTemp, F("collectormaxtemp"), F("maximum collector temperature"))
MAKE_PSTR_LIST(collectorMinTemp, F("collectormintemp"), F("minimum collector temperature"))
MAKE_PSTR_LIST(cylMaxTemp, F("cylmaxtemp"), F("maximum cylinder temperature"))
// MAKE_PSTR_LIST(cyl2MaxTemp, F("cyl2maxtemp"), F("maximum cylinder 2 temperature"))
MAKE_PSTR_LIST(solarPumpMod, F("solarpumpmod"), F("pump modulation (PS1)"))
MAKE_PSTR_LIST(cylPumpMod, F("cylpumpmod"), F("cylinder pump modulation (PS5)"))
MAKE_PSTR_LIST(solarPump, F("solarpump"), F("pump (PS1)"))
MAKE_PSTR_LIST(solarPump2, F("solarpump2"), F("pump 2 (PS4)"))
MAKE_PSTR_LIST(solarPump2Mod, F("solarpump2mod"), F("pump 2 modulation (PS4)"))
MAKE_PSTR_LIST(valveStatus, F("valvestatus"), F("valve status"))
MAKE_PSTR_LIST(cylHeated, F("cylheated"), F("cyl heated"))
MAKE_PSTR_LIST(collectorShutdown, F("collectorshutdown"), F("collector shutdown"))
MAKE_PSTR_LIST(pumpWorkTime, F("pumpworktime"), F("pump working time"))
MAKE_PSTR_LIST(pump2WorkTime, F("pump2worktime"), F("pump 2 working time"))
MAKE_PSTR_LIST(m1WorkTime, F("m1worktime"), F("differential control working time"))
MAKE_PSTR_LIST(energyLastHour, F("energylasthour"), F("energy last hour"))
MAKE_PSTR_LIST(energyTotal, F("energytotal"), F("total energy"))
MAKE_PSTR_LIST(energyToday, F("energytoday"), F("total energy today"))
MAKE_PSTR_LIST(pumpMinMod, F("pumpminmod"), F("minimum pump modulation"))
MAKE_PSTR_LIST(maxFlow, F("maxflow"), F("maximum solar flow"))
MAKE_PSTR_LIST(solarPower, F("solarpower"), F("actual solar power"))
MAKE_PSTR_LIST(solarPumpTurnonDiff, F("turnondiff"), F("pump turn on difference"))
MAKE_PSTR_LIST(solarPumpTurnoffDiff, F("turnoffdiff"), F("pump turn off difference"))
MAKE_PSTR_LIST(pump2MinMod, F("pump2minmod"), F("minimum pump 2 modulation"))
MAKE_PSTR_LIST(solarPump2TurnonDiff, F("turnondiff2"), F("pump 2 turn on difference"))
MAKE_PSTR_LIST(solarPump2TurnoffDiff, F("turnoffdiff2"), F("pump 2 turn off difference"))
// solar ww
MAKE_PSTR_LIST(wwTemp1, F("wwtemp1"), F("temperature 1"))
MAKE_PSTR_LIST(wwTemp3, F("wwtemp3"), F("temperature 3"))
MAKE_PSTR_LIST(wwTemp4, F("wwtemp4"), F("temperature 4"))
MAKE_PSTR_LIST(wwTemp5, F("wwtemp5"), F("temperature 5"))
MAKE_PSTR_LIST(wwTemp7, F("wwtemp7"), F("temperature 7"))
MAKE_PSTR_LIST(wwPump, F("wwpump"), F("pump"))
// solar ww and mixer wwc
MAKE_PSTR_LIST(wwMinTemp, F("wwmintemp"), F("minimum temperature"))
MAKE_PSTR_LIST(wwRedTemp, F("wwredtemp"), F("reduced temperature"))
MAKE_PSTR_LIST(wwDailyTemp, F("wwdailytemp"), F("daily temperature"))
MAKE_PSTR_LIST(wwKeepWarm, F("wwkeepwarm"), F("keep warm"))
MAKE_PSTR_LIST(wwStatus2, F("wwstatus2"), F("status 2"))
MAKE_PSTR_LIST(enum_wwStatus2, F(""), F(""), F(""), F("no_heat"), F(""), F(""), F("heatrequest"), F(""), F("disinfecting"), F("hold"))
MAKE_PSTR_LIST(wwPumpMod, F("wwpumpmod"), F("pump modulation"))
MAKE_PSTR_LIST(wwFlow, F("wwflow"), F("flow rate"))
// extra mixer ww
MAKE_PSTR_LIST(wwRequiredTemp, F("wwrequiredtemp"), F("required temperature"))
MAKE_PSTR_LIST(wwDiffTemp, F("wwdifftemp"), F("start differential temperature"))
//SM100
MAKE_PSTR_LIST(heatTransferSystem, F("heattransfersystem"), F("heattransfer system"))
MAKE_PSTR_LIST(externalCyl, F("externalcyl"), F("external cylinder"))
MAKE_PSTR_LIST(thermalDisinfect, F("thermaldisinfect"), F("thermal disinfection"))
MAKE_PSTR_LIST(heatMetering, F("heatmetering"), F("heatmetering"))
MAKE_PSTR_LIST(solarIsEnabled, F("solarenabled"), F("solarmodule enabled"))
// telegram 0x035A
MAKE_PSTR_LIST(solarPumpMode, F("solarpumpmode"), F("pump mode"))
MAKE_PSTR_LIST(solarPumpKick, F("pumpkick"), F("pumpkick"))
MAKE_PSTR_LIST(plainWaterMode, F("plainwatermode"), F("plain water mode"))
MAKE_PSTR_LIST(doubleMatchFlow, F("doublematchflow"), F("doublematchflow"))
MAKE_PSTR_LIST(solarPump2Mode, F("pump2mode"), F("pump 2 mode"))
MAKE_PSTR_LIST(solarPump2Kick, F("pump2kick"), F("pumpkick 2"))
// telegram 0x035F
MAKE_PSTR_LIST(cylPriority, F("cylpriority"), F("cylinder priority"))
// telegram 0x380
MAKE_PSTR_LIST(climateZone, F("climatezone"), F("climate zone"))
MAKE_PSTR_LIST(collector1Area, F("collector1area"), F("collector 1 area"))
MAKE_PSTR_LIST(collector1Type, F("collector1type"), F("collector 1 type"))
MAKE_PSTR_LIST(collector2Area, F("collector2area"), F("collector 2 area"))
MAKE_PSTR_LIST(collector2Type, F("collector2type"), F("collector 2 type"))
// telegram 0x0363 heatCounter
MAKE_PSTR_LIST(heatCntFlowTemp, F("heatcntflowtemp"), F("heat counter flow temperature"))
MAKE_PSTR_LIST(heatCntRetTemp, F("heatcntrettemp"), F("heat counter return temperature"))
MAKE_PSTR_LIST(heatCnt, F("heatcnt"), F("heat counter impulses"))
MAKE_PSTR_LIST(swapFlowTemp, F("swapflowtemp"), F("swap flow temperature (TS14)"))
MAKE_PSTR_LIST(swapRetTemp, F("swaprettemp"), F("swap return temperature (TS15)"))
// switch
MAKE_PSTR_LIST(activated, F("activated"), F("activated"))
MAKE_PSTR_LIST(status, F("status"), F("status"))
// unknown fields to track (SM10)
MAKE_PSTR_LIST(data11, F("data11"), F("unknown datafield 11"))
MAKE_PSTR_LIST(data12, F("data12"), F("unknown datafield 12"))
MAKE_PSTR_LIST(data8, F("data8"), F("unknown datafield 8"))
MAKE_PSTR_LIST(data0, F("data0"), F("unknown datafield 0"))
MAKE_PSTR_LIST(data1, F("data1"), F("unknown datafield 1"))
MAKE_PSTR_LIST(setting3, F("setting3"), F("unknown setting 3"))
MAKE_PSTR_LIST(setting4, F("setting4"), F("unknown setting 4"))
// RF sensor, id 0x40, telegram 0x435
MAKE_PSTR_LIST(RFTemp, F("rftemp"), F("RF room temperature sensor"));

370
src/locale_common.h Normal file
View File

@@ -0,0 +1,370 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
/*
* THIS FILE CONTAINS STANDARD STRING LITERALS THAT DON'T NEED LANGUAGE TRANSLATIONS
*/
// common words
MAKE_PSTR_WORD(debug)
MAKE_PSTR_WORD(exit)
MAKE_PSTR_WORD(help)
MAKE_PSTR_WORD(log)
MAKE_PSTR_WORD(logout)
MAKE_PSTR_WORD(enabled)
MAKE_PSTR_WORD(disabled)
MAKE_PSTR_WORD(set)
MAKE_PSTR_WORD(show)
MAKE_PSTR_WORD(su)
MAKE_PSTR_WORD(name)
MAKE_PSTR_WORD(scan)
MAKE_PSTR_WORD(password)
MAKE_PSTR_WORD(read)
MAKE_PSTR_WORD(version)
MAKE_PSTR_WORD(values)
MAKE_PSTR_WORD(system)
MAKE_PSTR_WORD(fetch)
MAKE_PSTR_WORD(restart)
MAKE_PSTR_WORD(format)
MAKE_PSTR_WORD(raw)
MAKE_PSTR_WORD(watch)
MAKE_PSTR_WORD(syslog)
MAKE_PSTR_WORD(send)
MAKE_PSTR_WORD(telegram)
MAKE_PSTR_WORD(bus_id)
MAKE_PSTR_WORD(tx_mode)
MAKE_PSTR_WORD(ems)
MAKE_PSTR_WORD(devices)
MAKE_PSTR_WORD(shower)
MAKE_PSTR_WORD(mqtt)
MAKE_PSTR_WORD(emsesp)
MAKE_PSTR_WORD(connected)
MAKE_PSTR_WORD(disconnected)
MAKE_PSTR_WORD(passwd)
MAKE_PSTR_WORD(hostname)
MAKE_PSTR_WORD(wifi)
MAKE_PSTR_WORD(reconnect)
MAKE_PSTR_WORD(ssid)
MAKE_PSTR_WORD(heartbeat)
MAKE_PSTR_WORD(users)
MAKE_PSTR_WORD(publish)
MAKE_PSTR_WORD(timeout)
MAKE_PSTR_WORD(board_profile)
MAKE_PSTR_WORD(setvalue)
// for commands
MAKE_PSTR_WORD(call)
MAKE_PSTR_WORD(cmd)
MAKE_PSTR_WORD(id)
MAKE_PSTR_WORD(hc)
MAKE_PSTR_WORD(wwc)
MAKE_PSTR_WORD(device)
MAKE_PSTR_WORD(data)
MAKE_PSTR_WORD(command)
MAKE_PSTR_WORD(commands)
MAKE_PSTR_WORD(info)
MAKE_PSTR_WORD(settings)
MAKE_PSTR_WORD(customizations)
MAKE_PSTR_WORD(value)
MAKE_PSTR_WORD(entities)
// devices
MAKE_PSTR_WORD(boiler)
MAKE_PSTR_WORD(thermostat)
MAKE_PSTR_WORD(switch)
MAKE_PSTR_WORD(solar)
MAKE_PSTR_WORD(mixer)
MAKE_PSTR_WORD(gateway)
MAKE_PSTR_WORD(controller)
MAKE_PSTR_WORD(connect)
MAKE_PSTR_WORD(heatpump)
MAKE_PSTR_WORD(generic)
MAKE_PSTR_WORD(analogsensor)
MAKE_PSTR_WORD(dallassensor)
MAKE_PSTR(number, "number")
MAKE_PSTR(enum, "enum")
MAKE_PSTR(text, "text")
// Console
MAKE_PSTR(EMSESP, "EMS-ESP")
MAKE_PSTR(host_fmt, "Host: %s")
MAKE_PSTR(port_fmt, "Port: %d")
MAKE_PSTR(hostname_fmt, "Hostname: %s")
MAKE_PSTR(board_profile_fmt, "Board Profile: %s")
MAKE_PSTR(mark_interval_fmt, "Mark interval: %lus")
MAKE_PSTR(wifi_ssid_fmt, "WiFi SSID: %s")
MAKE_PSTR(wifi_password_fmt, "WiFi Password: %S")
MAKE_PSTR(tx_mode_fmt, "Tx mode: %d")
MAKE_PSTR(bus_id_fmt, "Bus ID: %02X")
MAKE_PSTR(log_level_fmt, "Log level: %s")
MAKE_PSTR(cmd_optional, "[cmd]")
MAKE_PSTR(ha_optional, "[ha]")
MAKE_PSTR(deep_optional, "[deep]")
MAKE_PSTR(watchid_optional, "[ID]")
MAKE_PSTR(watch_format_optional, "[off | on | raw | unknown]")
MAKE_PSTR(invalid_watch, "Invalid watch type")
MAKE_PSTR(data_mandatory, "\"XX XX ...\"")
MAKE_PSTR(asterisks, "********")
MAKE_PSTR(n_mandatory, "<n>")
MAKE_PSTR(sensorid_optional, "[sensor ID]")
MAKE_PSTR(id_optional, "[id|hc]")
MAKE_PSTR(data_optional, "[data]")
MAKE_PSTR(offset_optional, "[offset]")
MAKE_PSTR(length_optional, "[length]")
MAKE_PSTR(typeid_mandatory, "<type ID>")
MAKE_PSTR(deviceid_mandatory, "<device ID>")
MAKE_PSTR(device_type_optional, "[device]")
MAKE_PSTR(invalid_log_level, "Invalid log level")
MAKE_PSTR(log_level_optional, "[level]")
MAKE_PSTR(name_mandatory, "<name>")
MAKE_PSTR(name_optional, "[name]")
MAKE_PSTR(new_password_prompt1, "Enter new password: ")
MAKE_PSTR(new_password_prompt2, "Retype new password: ")
MAKE_PSTR(password_prompt, "Password: ")
MAKE_PSTR(unset, "<unset>")
// more common names that don't need translations
MAKE_PSTR_LIST(1x3min, F("1x3min"))
MAKE_PSTR_LIST(2x3min, F("2x3min"))
MAKE_PSTR_LIST(3x3min, F("3x3min"))
MAKE_PSTR_LIST(4x3min, F("4x3min"))
MAKE_PSTR_LIST(5x3min, F("5x3min"))
MAKE_PSTR_LIST(6x3min, F("6x3min"))
MAKE_PSTR_LIST(auto, F("auto"))
MAKE_PSTR_LIST(na, F("n/a"))
MAKE_PSTR_LIST(rc3x, F("rc3x"))
MAKE_PSTR_LIST(rc20, F("rc20"))
MAKE_PSTR_LIST(fb10, F("fb10"))
MAKE_PSTR_LIST(fb100, F("fb100"))
MAKE_PSTR_LIST(dash, F("-"))
MAKE_PSTR_LIST(error, F("error"))
MAKE_PSTR_LIST(BLANK, F(""))
MAKE_PSTR_LIST(pwm, F("pwm"))
MAKE_PSTR_LIST(pwm_invers, F("pwm inverse"))
MAKE_PSTR_LIST(mpc, F("mpc"))
MAKE_PSTR_LIST(tempauto, F("temp auto"))
MAKE_PSTR_LIST(bypass, F("bypass"))
MAKE_PSTR_LIST(mixer, F("mixer"))
MAKE_PSTR_LIST(monovalent, F("monovalent"))
MAKE_PSTR_LIST(bivalent, F("bivalent"))
MAKE_PSTR_LIST(n_o, F("n_o"))
MAKE_PSTR_LIST(n_c, F("n_c"))
MAKE_PSTR_LIST(prog1, F("prog 1"))
MAKE_PSTR_LIST(prog2, F("prog 2"))
MAKE_PSTR_LIST(proga, F("prog a"))
MAKE_PSTR_LIST(progb, F("prog b"))
MAKE_PSTR_LIST(progc, F("prog c"))
MAKE_PSTR_LIST(progd, F("prog d"))
MAKE_PSTR_LIST(proge, F("prog e"))
MAKE_PSTR_LIST(progf, F("prog f"))
// templates - this are not translated and will be saved under optons_single
MAKE_PSTR_LIST(tpl_datetime, F("Format: < NTP | dd.mm.yyyy-hh:mm:ss-day(0-6)-dst(0/1) >"))
MAKE_PSTR_LIST(tpl_switchtime, F("Format: <nn> [ not_set | day hh:mm on|off ]"))
MAKE_PSTR_LIST(tpl_switchtime1, F("Format: <nn> [ not_set | day hh:mm Tn ]"))
MAKE_PSTR_LIST(tpl_holidays, F("Format: < dd.mm.yyyy-dd.mm.yyyy >"))
MAKE_PSTR_LIST(tpl_date, F("Format: < dd.mm.yyyy >"))
// Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp
// These don't need translating, it will mess up HA and the API
MAKE_PSTR(uom_blank, " ")
MAKE_PSTR(uom_percent, "%")
MAKE_PSTR(uom_degrees, "°C")
MAKE_PSTR(uom_hours, "hours")
MAKE_PSTR(uom_minutes, "minutes")
MAKE_PSTR(uom_seconds, "seconds")
MAKE_PSTR(uom_kwh, "kWh")
MAKE_PSTR(uom_wh, "Wh")
MAKE_PSTR(uom_bar, "bar")
MAKE_PSTR(uom_ua, "uA")
MAKE_PSTR(uom_lmin, "l/min")
MAKE_PSTR(uom_kw, "kW")
MAKE_PSTR(uom_w, "W")
MAKE_PSTR(uom_kb, "KB")
MAKE_PSTR(uom_dbm, "dBm")
MAKE_PSTR(uom_fahrenheit, "°F")
MAKE_PSTR(uom_mv, "mV")
MAKE_PSTR(uom_sqm, "sqm")
MAKE_PSTR(uom_m3, "m3")
MAKE_PSTR(uom_l, "l")
// commands
MAKE_PSTR(info_cmd, "lists all values")
MAKE_PSTR(commands_cmd, "lists all commands")
MAKE_PSTR(entities_cmd, "lists all entities")
// TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp
// use empty string if want to suppress showing tags
// mqtt tags must not have spaces
MAKE_PSTR(tag_none, "")
MAKE_PSTR(tag_heartbeat, "")
MAKE_PSTR(tag_boiler_data_ww, "dhw")
MAKE_PSTR(tag_device_data, "")
MAKE_PSTR(tag_device_data_ww, "dhw")
MAKE_PSTR(tag_hc1, "hc1")
MAKE_PSTR(tag_hc2, "hc2")
MAKE_PSTR(tag_hc3, "hc3")
MAKE_PSTR(tag_hc4, "hc4")
MAKE_PSTR(tag_hc5, "hc5")
MAKE_PSTR(tag_hc6, "hc6")
MAKE_PSTR(tag_hc7, "hc7")
MAKE_PSTR(tag_hc8, "hc8")
MAKE_PSTR(tag_wwc1, "wwc1")
MAKE_PSTR(tag_wwc2, "wwc2")
MAKE_PSTR(tag_wwc3, "wwc3")
MAKE_PSTR(tag_wwc4, "wwc4")
MAKE_PSTR(tag_wwc5, "wwc5")
MAKE_PSTR(tag_wwc6, "wwc6")
MAKE_PSTR(tag_wwc7, "wwc7")
MAKE_PSTR(tag_wwc8, "wwc8")
MAKE_PSTR(tag_wwc9, "wwc9")
MAKE_PSTR(tag_wwc10, "wwc10")
MAKE_PSTR(tag_ahs, "ahs")
MAKE_PSTR(tag_hs1, "hs1")
MAKE_PSTR(tag_hs2, "hs2")
MAKE_PSTR(tag_hs3, "hs3")
MAKE_PSTR(tag_hs4, "hs4")
MAKE_PSTR(tag_hs5, "hs5")
MAKE_PSTR(tag_hs6, "hs6")
MAKE_PSTR(tag_hs7, "hs7")
MAKE_PSTR(tag_hs8, "hs8")
MAKE_PSTR(tag_hs9, "hs9")
MAKE_PSTR(tag_hs10, "hs10")
MAKE_PSTR(tag_hs11, "hs11")
MAKE_PSTR(tag_hs12, "hs12")
MAKE_PSTR(tag_hs13, "hs13")
MAKE_PSTR(tag_hs14, "hs14")
MAKE_PSTR(tag_hs15, "hs15")
MAKE_PSTR(tag_hs16, "hs16")
// MQTT topics and prefixes
MAKE_PSTR(heating_active, "heating_active")
MAKE_PSTR(tapwater_active, "tapwater_active")
MAKE_PSTR(response, "response")
MAKE_PSTR(tag_boiler_data_ww_mqtt, "ww")
MAKE_PSTR(tag_device_data_ww_mqtt, "")
MAKE_PSTR_LIST(climate, F("HA climate config creation"))
// syslog
MAKE_PSTR_LIST(list_syslog_level, F("off"), F("emerg"), F("alert"), F("crit"), F("error"), F("warn"), F("notice"), F("info"), F("debug"), F("trace"), F("all"))
// sensors
MAKE_PSTR_LIST(list_sensortype, F("none"), F("digital in"), F("counter"), F("adc"), F("timer"), F("rate"), F("digital out"), F("pwm 0"), F("pwm 1"), F("pwm 2"))
// watch
MAKE_PSTR_LIST(list_watch, F("off"), F("on"), F("raw"), F("unknown"))
/*
* The rest below are Enums and generated from translations lists
*/
MAKE_PSTR_ENUM(enum_cylprio, FL_(cyl1), FL_(cyl2))
MAKE_PSTR_ENUM(enum_progMode, FL_(prog1), FL_(prog2))
MAKE_PSTR_ENUM(enum_progMode4, FL_(proga), FL_(progb), FL_(progc), FL_(progd), FL_(proge), FL_(progf))
MAKE_PSTR_ENUM(enum_climate, FL_(seltemp), FL_(roomtemp))
MAKE_PSTR_ENUM(enum_charge, FL_(chargepump), FL_(3wayvalve))
MAKE_PSTR_ENUM(enum_freq, FL_(off), FL_(1x3min), FL_(2x3min), FL_(3x3min), FL_(4x3min), FL_(5x3min), FL_(6x3min), FL_(continuous))
MAKE_PSTR_ENUM(enum_off_time_date_manual, FL_(off), FL_(time), FL_(date), FL_(manual))
MAKE_PSTR_ENUM(enum_comfort, FL_(hot), FL_(eco), FL_(intelligent))
MAKE_PSTR_ENUM(enum_comfort1, FL_(high_comfort), FL_(eco))
MAKE_PSTR_ENUM(enum_flow, FL_(off), FL_(flow), FL_(bufferedflow), FL_(buffer), FL_(layeredbuffer))
MAKE_PSTR_ENUM(enum_reset, FL_(dash), FL_(maintenance), FL_(error))
// thermostat lists
MAKE_PSTR_ENUM(enum_ibaMainDisplay,
FL_(internal_temperature),
FL_(internal_setpoint),
FL_(external_temperature),
FL_(burner_temperature),
FL_(ww_temperature),
FL_(functioning_mode),
FL_(time),
FL_(date),
FL_(smoke_temperature))
MAKE_PSTR_ENUM(enum_ibaLanguage, FL_(german), FL_(dutch), FL_(french), FL_(italian))
MAKE_PSTR_ENUM(enum_ibaLanguage_RC30, FL_(german), FL_(dutch))
MAKE_PSTR_ENUM(enum_floordrystatus, FL_(off), FL_(start), FL_(heat), FL_(hold), FL_(cool), FL_(end))
MAKE_PSTR_ENUM(enum_ibaBuildingType, FL_(light), FL_(medium), FL_(heavy))
MAKE_PSTR_ENUM(enum_PID, FL_(fast), FL_(medium), FL_(slow))
MAKE_PSTR_ENUM(enum_wwMode, FL_(off), FL_(normal), FL_(comfort), FL_(auto), FL_(own_prog), FL_(eco))
MAKE_PSTR_ENUM(enum_wwCircMode, FL_(off), FL_(on), FL_(auto), FL_(own_prog))
MAKE_PSTR_ENUM(enum_wwMode2, FL_(off), FL_(on), FL_(auto))
MAKE_PSTR_ENUM(enum_wwMode3, FL_(on), FL_(off), FL_(auto))
MAKE_PSTR_ENUM(enum_heatingtype, FL_(off), FL_(radiator), FL_(convector), FL_(floor))
MAKE_PSTR_ENUM(enum_summermode, FL_(summer), FL_(auto), FL_(winter))
MAKE_PSTR_ENUM(enum_hpoperatingmode, FL_(off), FL_(auto), FL_(heating), FL_(cooling))
MAKE_PSTR_ENUM(enum_summer, FL_(winter), FL_(summer))
MAKE_PSTR_ENUM(enum_operatingstate, FL_(heating), FL_(off), FL_(cooling))
MAKE_PSTR_ENUM(enum_mode, FL_(manual), FL_(auto)) // RC100, RC300, RC310
MAKE_PSTR_ENUM(enum_mode2, FL_(off), FL_(manual), FL_(auto)) // RC20
MAKE_PSTR_ENUM(enum_mode3, FL_(night), FL_(day), FL_(auto)) // RC35, RC30, RC25
MAKE_PSTR_ENUM(enum_mode4, FL_(nofrost), FL_(eco), FL_(heat), FL_(auto)) // JUNKERS
MAKE_PSTR_ENUM(enum_mode5, FL_(auto), FL_(off)) // CRF
MAKE_PSTR_ENUM(enum_mode6, FL_(nofrost), FL_(night), FL_(day)) // RC10
MAKE_PSTR_ENUM(enum_modetype, FL_(eco), FL_(comfort))
MAKE_PSTR_ENUM(enum_modetype3, FL_(night), FL_(day))
MAKE_PSTR_ENUM(enum_modetype4, FL_(nofrost), FL_(eco), FL_(heat))
MAKE_PSTR_ENUM(enum_modetype5, FL_(off), FL_(on))
MAKE_PSTR_ENUM(enum_reducemode, FL_(nofrost), FL_(reduce), FL_(room), FL_(outdoor))
MAKE_PSTR_ENUM(enum_reducemode1, FL_(outdoor), FL_(room), FL_(reduce)) // RC310 values: 1-3
MAKE_PSTR_ENUM(enum_nofrostmode, FL_(off), FL_(room), FL_(outdoor))
MAKE_PSTR_ENUM(enum_nofrostmode1, FL_(room), FL_(outdoor), FL_(room_outdoor))
MAKE_PSTR_ENUM(enum_controlmode, FL_(off), FL_(optimized), FL_(simple), FL_(mpc), FL_(room), FL_(power), FL_(constant))
MAKE_PSTR_ENUM(enum_controlmode1, FL_(weather_compensated), FL_(outside_basepoint), FL_(na), FL_(room)) // RC310 1-4
MAKE_PSTR_ENUM(enum_controlmode2, FL_(outdoor), FL_(room))
MAKE_PSTR_ENUM(enum_control, FL_(off), FL_(rc20), FL_(rc3x))
MAKE_PSTR_ENUM(enum_j_control, FL_(off), FL_(fb10), FL_(fb100))
MAKE_PSTR_ENUM(enum_switchmode, FL_(off), FL_(eco), FL_(comfort), FL_(heat))
MAKE_PSTR_ENUM(enum_dayOfWeek, FL_(day_mo), FL_(day_tu), FL_(day_we), FL_(day_th), FL_(day_fr), FL_(day_sa), FL_(day_su), FL_(all))
MAKE_PSTR_ENUM(enum_progMode2, FL_(own_1), FL_(family), FL_(morning), FL_(evening), FL_(am), FL_(pm), FL_(midday), FL_(singles), FL_(seniors), FL_(new), FL_(own_2))
MAKE_PSTR_ENUM(enum_progMode3, FL_(family), FL_(morning), FL_(evening), FL_(am), FL_(pm), FL_(midday), FL_(singles), FL_(seniors))
MAKE_PSTR_ENUM(enum_hybridStrategy, FL_(co2_optimized), FL_(cost_optimized), FL_(outside_temp_switched), FL_(co2_cost_mix))
// heat pump
MAKE_PSTR_ENUM(enum_hpactivity, FL_(none), FL_(heating), FL_(cooling), FL_(hot_water), FL_(pool))
// solar
MAKE_PSTR_ENUM(enum_solarmode, FL_(constant), FL_(pwm), FL_(analog))
MAKE_PSTR_ENUM(enum_collectortype, FL_(flat), FL_(vacuum))
MAKE_PSTR_ENUM(enum_wwStatus2, FL_(BLANK), FL_(BLANK), FL_(BLANK), FL_(no_heat), FL_(BLANK), FL_(BLANK), FL_(heatrequest), FL_(BLANK), FL_(disinfecting), FL_(hold))
// mixer
MAKE_PSTR_ENUM(enum_shunt, FL_(stopped), FL_(opening), FL_(closing), FL_(open), FL_(close))
MAKE_PSTR_ENUM(enum_wwProgMode, FL_(std_prog), FL_(own_prog))
// AM200 lists
MAKE_PSTR_ENUM(enum_vr2Config, FL_(off), FL_(bypass))
MAKE_PSTR_ENUM(enum_aPumpSignal, FL_(off), FL_(pwm), FL_(pwm_invers))
MAKE_PSTR_ENUM(enum_bufBypass, FL_(no), FL_(mixer), FL_(valve))
MAKE_PSTR_ENUM(enum_blockMode, FL_(off), FL_(auto), FL_(blocking))
MAKE_PSTR_ENUM(enum_bufConfig, FL_(monovalent), FL_(bivalent))
MAKE_PSTR_ENUM(enum_blockTerm, FL_(n_o), FL_(n_c))
#pragma GCC diagnostic pop

588
src/locale_translations.h Normal file
View File

@@ -0,0 +1,588 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Define languages here
// Makes sure they are also added in same order to languages[] in system.cpp
#define EMSESP_LOCALE_EN "en"
#define EMSESP_LOCALE_DE "de"
// translations are in order en, de
// if there is no translation, it will default to en
// General
MAKE_PSTR_LIST(on, F("on"), F("an"))
MAKE_PSTR_LIST(off, F("off"), F("aus"))
MAKE_PSTR_LIST(ON, F("ON"), F("AN"))
MAKE_PSTR_LIST(OFF, F("OFF"), F("AUS"))
// Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp
// uom - also used with HA see https://github.com/home-assistant/core/blob/d7ac4bd65379e11461c7ce0893d3533d8d8b8cbf/homeassistant/const.py#L384
MAKE_PSTR_LIST(minutes, F("minutes"), F("Minuten"))
MAKE_PSTR_LIST(hours, F("hours"), F("Stunden"))
MAKE_PSTR_LIST(days, F("days"), F("Tage"))
MAKE_PSTR_LIST(seconds, F("seconds"), F("Sekunden"))
// general
MAKE_PSTR_LIST(day_mo, F("mo"), F("Mo"))
MAKE_PSTR_LIST(day_tu, F("tu"), F("Di"))
MAKE_PSTR_LIST(day_we, F("we"), F("Mi"))
MAKE_PSTR_LIST(day_th, F("th"), F("Do"))
MAKE_PSTR_LIST(day_fr, F("fr"), F("Fr"))
MAKE_PSTR_LIST(day_sa, F("sa"), F("Sa"))
MAKE_PSTR_LIST(day_su, F("su"), F("So"))
MAKE_PSTR_LIST(all, F("all"), F("Alle"))
MAKE_PSTR_LIST(own_1, F("own 1"), F("Eigen 1"))
MAKE_PSTR_LIST(family, F("family"), F("Familie"))
MAKE_PSTR_LIST(morning, F("morning"), F("Morgends"))
MAKE_PSTR_LIST(evening, F("evening"), F("Abends"))
MAKE_PSTR_LIST(seniors, F("seniors"), F("Senioren"))
MAKE_PSTR_LIST(no, F("no"), F("nein"))
MAKE_PSTR_LIST(new, F("new"), F("Neu"))
MAKE_PSTR_LIST(own_2, F("own 2"), F("Eigen 2"))
MAKE_PSTR_LIST(singles, F("singles"), F("Singles"))
MAKE_PSTR_LIST(am, F("am"), F("Vormittag"))
MAKE_PSTR_LIST(pm, F("pm"), F("Nachmittag"))
MAKE_PSTR_LIST(midday, F("midday"), F("Mittag"))
MAKE_PSTR_LIST(unknown, F("unknown"), F("Unbekannt"))
MAKE_PSTR_LIST(flat, F("flat"), F("flach"))
MAKE_PSTR_LIST(vacuum, F("vacuum"), F("vakuum"))
MAKE_PSTR_LIST(co2_optimized, F("co2 optimized"), F("CO2 optimiert"))
MAKE_PSTR_LIST(cost_optimized, F("cost optimized"), F("kostenoptimiert"))
MAKE_PSTR_LIST(outside_temp_switched, F("outside temp switched"), F("Außentemp geschaltet"))
MAKE_PSTR_LIST(co2_cost_mix, F("co2 cost mix"), F("Kostenmix"))
MAKE_PSTR_LIST(analog, F("analog"), F("analog"))
MAKE_PSTR_LIST(normal, F("normal"), F("normal"))
MAKE_PSTR_LIST(blocking, F("blocking"), F("Blockierung"))
// boiler
MAKE_PSTR_LIST(time, F("time"), F("Zeit"))
MAKE_PSTR_LIST(date, F("date"), F("Datum"))
MAKE_PSTR_LIST(continuous, F("continuous"), F("kontinuierlich"))
MAKE_PSTR_LIST(3wayvalve, F("3-way valve"), F("3-Wege Ventil"))
MAKE_PSTR_LIST(chargepump, F("chargepump"), F("Ladepumpe"))
MAKE_PSTR_LIST(hot, F("hot"), F("Heiss"))
MAKE_PSTR_LIST(high_comfort, F("high comfort"), F("Heiss Komfort"))
MAKE_PSTR_LIST(eco, F("eco"), F("Eco"))
MAKE_PSTR_LIST(intelligent, F("intelligent"), F("Intellgent"))
MAKE_PSTR_LIST(flow, F("flow"), F("Fluss"))
MAKE_PSTR_LIST(manual, F("manual"), F("Manuell"))
MAKE_PSTR_LIST(buffer, F("buffer"), F("Speicher"))
MAKE_PSTR_LIST(bufferedflow, F("buffered flow"), F("Durchlaufspeicher"))
MAKE_PSTR_LIST(layeredbuffer, F("layered buffer"), F("Schichtspeicher"))
MAKE_PSTR_LIST(maintenance, F("maintenance"), F("Wartung"))
MAKE_PSTR_LIST(heating, F("heating"), F("Heizen"))
MAKE_PSTR_LIST(cooling, F("cooling"), F("K<EFBFBD>hlen"))
MAKE_PSTR_LIST(disinfecting, F("disinfecting"), F("desinfizieren"))
MAKE_PSTR_LIST(no_heat, F("no heat"), F("keine Hitze"))
MAKE_PSTR_LIST(heatrequest, F("heat request"), F("Wärmeanforderung"))
MAKE_PSTR_LIST(valve, F("valve"), F("Ventil"))
// heatpump
MAKE_PSTR_LIST(none, F("none"), F("keiner"))
MAKE_PSTR_LIST(hot_water, F("hot water"), F("heißes Wasser"))
MAKE_PSTR_LIST(pool, F("pool"), F("Schwimmbad"))
// thermostat
MAKE_PSTR_LIST(seltemp, F("selTemp"), F("Solltemperature"))
MAKE_PSTR_LIST(roomtemp, F("roomTemp"), F("Raumtemperatur"))
MAKE_PSTR_LIST(own_prog, F("own prog"), F("Eigenprog"))
MAKE_PSTR_LIST(std_prog, F("std prog"), F("Standardprog"))
MAKE_PSTR_LIST(light, F("light"), F("Leicht"))
MAKE_PSTR_LIST(medium, F("medium"), F("Mittel"))
MAKE_PSTR_LIST(heavy, F("heavy"), F("Schwer"))
MAKE_PSTR_LIST(start, F("start"), F("Start"))
MAKE_PSTR_LIST(heat, F("heat"), F("Heizen"))
MAKE_PSTR_LIST(hold, F("hold"), F("Halten"))
MAKE_PSTR_LIST(cool, F("cool"), F("Kühl"))
MAKE_PSTR_LIST(end, F("end"), F("Ende"))
MAKE_PSTR_LIST(german, F("german"), F("Deutsch"))
MAKE_PSTR_LIST(dutch, F("dutch"), F("Niederländisch"))
MAKE_PSTR_LIST(french, F("french"), F("Französisch"))
MAKE_PSTR_LIST(italian, F("italian"), F("Italienisch"))
MAKE_PSTR_LIST(high, F("high"), F("hoch"))
MAKE_PSTR_LIST(low, F("low"), F("niedrig"))
MAKE_PSTR_LIST(radiator, F("radiator"), F("Heizkörper"))
MAKE_PSTR_LIST(convector, F("convector"), F("Konvektor"))
MAKE_PSTR_LIST(floor, F("floor"), F("Fussboden"))
MAKE_PSTR_LIST(summer, F("summer"), F("Sommer"))
MAKE_PSTR_LIST(winter, F("winter"), F("Winter"))
MAKE_PSTR_LIST(outdoor, F("outdoor"), F("Aussentemperatur"))
MAKE_PSTR_LIST(room, F("room"), F("Raum"))
MAKE_PSTR_LIST(room_outdoor, F("room outdoor"), F("Raum+Au<41>en"))
MAKE_PSTR_LIST(power, F("power"), F("Leistung"))
MAKE_PSTR_LIST(constant, F("constant"), F("konstant"))
MAKE_PSTR_LIST(simple, F("simple"), F("einfach"))
MAKE_PSTR_LIST(optimized, F("optimized"), F("optimiert"))
MAKE_PSTR_LIST(nofrost, F("nofrost"), F("Frostschutz"))
MAKE_PSTR_LIST(comfort, F("comfort"), F("Komfort"))
MAKE_PSTR_LIST(night, F("night"), F("Nacht"))
MAKE_PSTR_LIST(day, F("day"), F("Tag"))
MAKE_PSTR_LIST(holiday, F("holiday"), F("Urlaub"))
MAKE_PSTR_LIST(reduce, F("reduce"), F("reduziert"))
MAKE_PSTR_LIST(noreduce, F("no reduce"), F("unreduziert"))
MAKE_PSTR_LIST(offset, F("offset"), F("Anhebung"))
MAKE_PSTR_LIST(design, F("design"), F("Auslegung"))
MAKE_PSTR_LIST(minflow, F("min flow"), F("minfluss"))
MAKE_PSTR_LIST(maxflow, F("max flow"), F("maxfluss"))
MAKE_PSTR_LIST(fast, F("fast"), F("schnell"))
MAKE_PSTR_LIST(slow, F("slow"), F("langsam"))
MAKE_PSTR_LIST(internal_temperature, F("internal temperature"), F("Interne Temperatur"))
MAKE_PSTR_LIST(internal_setpoint, F("internal setpoint"), F("Interner Sollwert"))
MAKE_PSTR_LIST(external_temperature, F("external temperature"), F("Externe Temperatur"))
MAKE_PSTR_LIST(burner_temperature, F("burner temperature"), F("Kesseltemperatur"))
MAKE_PSTR_LIST(ww_temperature, F("ww temperature"), F("Wassertemperatur"))
MAKE_PSTR_LIST(smoke_temperature, F("smoke temperature"), F("Abgastemperatur"))
MAKE_PSTR_LIST(weather_compensated, F("weather compensated"), F("Wetter kompensiert"))
MAKE_PSTR_LIST(outside_basepoint, F("outside basepoint"), F("außerhalb des Basispunktes"))
MAKE_PSTR_LIST(functioning_mode, F("functioning mode"), F("Funktionsweise"))
// mixer
MAKE_PSTR_LIST(stopped, F("stopped"), F("gestoppt"))
MAKE_PSTR_LIST(opening, F("opening"), F("öffnen"))
MAKE_PSTR_LIST(closing, F("closing"), F("schließen"))
MAKE_PSTR_LIST(open, F("open"), F("Offen"))
MAKE_PSTR_LIST(close, F("close"), F("Geschlossen"))
// Boiler
MAKE_PSTR_LIST(wwtapactivated, F("wwtapactivated"), F("turn on/off"), F("Aktiviere Warmwasser im Wartungsmodus"))
MAKE_PSTR_LIST(reset, F("reset"), F("Reset"))
MAKE_PSTR_LIST(oilPreHeat, F("oilpreheat"), F("oil preheating"), F("Ölvorwärmung"))
MAKE_PSTR_LIST(heatingActive, F("heatingactive"), F("heating active"), F("Heizung aktiv"))
MAKE_PSTR_LIST(tapwaterActive, F("tapwateractive"), F("tapwater active"), F("Warmwasser aktiv"))
MAKE_PSTR_LIST(selFlowTemp, F("selflowtemp"), F("selected flow temperature"), F("Sollwert Flusstemperatur"))
MAKE_PSTR_LIST(selBurnPow, F("selburnpow"), F("burner selected max power"), F("Sollwert Brennerleistung"))
MAKE_PSTR_LIST(heatingPumpMod, F("heatingpumpmod"), F("heating pump modulation"), F("Heizungspumpe 1 Modulation"))
MAKE_PSTR_LIST(heatingPump2Mod, F("heatingpump2mod"), F("heating pump 2 modulation"), F("Heizungspumpe 2 Modulation"))
MAKE_PSTR_LIST(outdoorTemp, F("outdoortemp"), F("outside temperature"), F("Aussentemperatur"))
MAKE_PSTR_LIST(curFlowTemp, F("curflowtemp"), F("current flow temperature"), F("aktuelle Flusstemperatur"))
MAKE_PSTR_LIST(retTemp, F("rettemp"), F("return temperature"), F("Rücklauftemperatur"))
MAKE_PSTR_LIST(switchTemp, F("switchtemp"), F("mixing switch temperature"), F("Mischer Schalttemperatur"))
MAKE_PSTR_LIST(sysPress, F("syspress"), F("system pressure"), F("Systemdruck"))
MAKE_PSTR_LIST(boilTemp, F("boiltemp"), F("actual boiler temperature"), F("Kesseltemperatur"))
MAKE_PSTR_LIST(exhaustTemp, F("exhausttemp"), F("exhaust temperature"), F("Auslasstemperatur"))
MAKE_PSTR_LIST(burnGas, F("burngas"), F("gas"), F("Gas"))
MAKE_PSTR_LIST(burnGas2, F("burngas2"), F("gas stage 2"), F("Gas Stufe 2"))
MAKE_PSTR_LIST(flameCurr, F("flamecurr"), F("flame current"), F("Flammstrom"))
MAKE_PSTR_LIST(heatingPump, F("heatingpump"), F("heating pump"), F("Heizungspumpe"))
MAKE_PSTR_LIST(fanWork, F("fanwork"), F("fan"), F("Gebläse"))
MAKE_PSTR_LIST(ignWork, F("ignwork"), F("ignition"), F("Zündung"))
MAKE_PSTR_LIST(heatingActivated, F("heatingactivated"), F("heating activated"), F("Heizen aktiviert"))
MAKE_PSTR_LIST(heatingTemp, F("heatingtemp"), F("heating temperature"), F("Kesseltemperatur"))
MAKE_PSTR_LIST(pumpModMax, F("pumpmodmax"), F("burner pump max power"), F("Kesselpumpen Maximalleistung"))
MAKE_PSTR_LIST(pumpModMin, F("pumpmodmin"), F("burner pump min power"), F("Kesselpumpen Minmalleistung"))
MAKE_PSTR_LIST(pumpDelay, F("pumpdelay"), F("pump delay"), F("Pumpennachlauf"))
MAKE_PSTR_LIST(burnMinPeriod, F("burnminperiod"), F("burner min period"), F("Antipendelzeit"))
MAKE_PSTR_LIST(burnMinPower, F("burnminpower"), F("burner min power"), F("minimale Brennerleistung"))
MAKE_PSTR_LIST(burnMaxPower, F("burnmaxpower"), F("burner max power"), F("maximale Brennerleistung"))
MAKE_PSTR_LIST(boilHystOn, F("boilhyston"), F("hysteresis on temperature"), F("Hysterese ein temperatur"))
MAKE_PSTR_LIST(boilHystOff, F("boilhystoff"), F("hysteresis off temperature"), F("Hysterese aus temperatur"))
MAKE_PSTR_LIST(setFlowTemp, F("setflowtemp"), F("set flow temperature"), F("Sollwert Flusstemperatur"))
MAKE_PSTR_LIST(setBurnPow, F("setburnpow"), F("burner set power"), F("Sollwert Brennerleistung"))
MAKE_PSTR_LIST(curBurnPow, F("curburnpow"), F("burner current power"), F("Brennerleistung"))
MAKE_PSTR_LIST(burnStarts, F("burnstarts"), F("burner starts"), F("Brenner # starts"))
MAKE_PSTR_LIST(burnWorkMin, F("burnworkmin"), F("total burner operating time"), F("Brenner Laufzeit"))
MAKE_PSTR_LIST(burn2WorkMin, F("burn2workmin"), F("burner stage 2 operating time"), F("Brenner Stufe 2 Laufzeit"))
MAKE_PSTR_LIST(heatWorkMin, F("heatworkmin"), F("total heat operating time"), F("Heizung Laufzeit"))
MAKE_PSTR_LIST(UBAuptime, F("ubauptime"), F("total UBA operating time"), F("gesamte Laufzeit"))
MAKE_PSTR_LIST(lastCode, F("lastcode"), F("last error code"), F("Fehlerspeicher"))
MAKE_PSTR_LIST(serviceCode, F("servicecode"), F("service code"), F("Statusmeldung"))
MAKE_PSTR_LIST(serviceCodeNumber, F("servicecodenumber"), F("service code number"), F("Statusmeldungsnummer"))
MAKE_PSTR_LIST(maintenanceMessage, F("maintenancemessage"), F("maintenance message"), F("Wartungsmeldung"))
MAKE_PSTR_LIST(maintenanceDate, F("maintenancedate"), F("next maintenance date"), F("Wartungsdatum"))
MAKE_PSTR_LIST(maintenanceType, F("maintenance"), F("maintenance scheduled"), F("Wartungsplan"))
MAKE_PSTR_LIST(maintenanceTime, F("maintenancetime"), F("time to next maintenance"), F("Wartung in"))
MAKE_PSTR_LIST(emergencyOps, F("emergencyops"), F("emergency operation"), F("Notoperation"))
MAKE_PSTR_LIST(emergencyTemp, F("emergencytemp"), F("emergency temperature"), F("Nottemperatur"))
// heatpump/compress specific
MAKE_PSTR_LIST(upTimeControl, F("uptimecontrol"), F("total operating time heat"), F("Betriebszeit total heizen"))
MAKE_PSTR_LIST(upTimeCompHeating, F("uptimecompheating"), F("operating time compressor heating"), F("Betriebszeit Kompressor heizen"))
MAKE_PSTR_LIST(upTimeCompCooling, F("uptimecompcooling"), F("operating time compressor cooling"), F("Betriebszeit Kompressor kühlen"))
MAKE_PSTR_LIST(upTimeCompWw, F("uptimecompww"), F("operating time compressor dhw"), F("Betriebszeit Kompressor"))
MAKE_PSTR_LIST(upTimeCompPool, F("uptimecomppool"), F("operating time compressor pool"), F("Betriebszeit Kompressor Pool"))
MAKE_PSTR_LIST(totalCompStarts, F("totalcompstarts"), F("total compressor control starts"), F("gesamt Kompressor Starts"))
MAKE_PSTR_LIST(heatingStarts, F("heatingstarts"), F("heating control starts"), F("Heizen Starts"))
MAKE_PSTR_LIST(coolingStarts, F("coolingstarts"), F("cooling control starts"), F("Kühlen Starts"))
MAKE_PSTR_LIST(poolStarts, F("poolstarts"), F("pool control starts"), F("Pool Starts"))
MAKE_PSTR_LIST(nrgConsTotal, F("nrgconstotal"), F("total energy consumption"), F("totaler Energieverbrauch"), F("totaler Energieverbrauch"))
MAKE_PSTR_LIST(nrgConsCompTotal, F("nrgconscomptotal"), F("total energy consumption compressor"), F("Energieverbrauch Kompressor total"))
MAKE_PSTR_LIST(nrgConsCompHeating, F("nrgconscompheating"), F("energy consumption compressor heating"), F("Energieverbrauch Kompressor heizen"))
MAKE_PSTR_LIST(nrgConsCompWw, F("nrgconscompww"), F("energy consumption compressor dhw"), F("Energieverbrauch Kompressor"))
MAKE_PSTR_LIST(nrgConsCompCooling, F("nrgconscompcooling"), F("energy consumption compressor cooling"), F("Energieverbrauch Kompressor kühlen"))
MAKE_PSTR_LIST(nrgConsCompPool, F("nrgconscomppool"), F("energy consumption compressor pool"), F("Energieverbrauch Kompressor Pool"))
MAKE_PSTR_LIST(nrgSuppTotal, F("nrgsupptotal"), F("total energy supplied"), F("gesamte Energieabgabe"))
MAKE_PSTR_LIST(nrgSuppHeating, F("nrgsuppheating"), F("total energy supplied heating"), F("gesamte Energieabgabe heizen"))
MAKE_PSTR_LIST(nrgSuppWw, F("nrgsuppww"), F("total energy warm supplied dhw"), F("gesamte Energieabgabe"))
MAKE_PSTR_LIST(nrgSuppCooling, F("nrgsuppcooling"), F("total energy supplied cooling"), F("gesamte Energieabgabe kühlen"))
MAKE_PSTR_LIST(nrgSuppPool, F("nrgsupppool"), F("total energy supplied pool"), F("gesamte Energieabgabe Pool"))
MAKE_PSTR_LIST(auxElecHeatNrgConsTotal,
F("auxelecheatnrgconstotal"),
F("total auxiliary electrical heater energy consumption"),
F("Energieverbrauch el. Zusatzheizung"))
MAKE_PSTR_LIST(auxElecHeatNrgConsHeating,
F("auxelecheatnrgconsheating"),
F("auxiliary electrical heater energy consumption heating"),
F("Energieverbrauch el. Zusatzheizung Heizen"))
MAKE_PSTR_LIST(auxElecHeatNrgConsWW, F("auxelecheatnrgconsww"), F("auxiliary electrical heater energy consumption dhw"), F("Energieverbrauch el. Zusatzheizung"))
MAKE_PSTR_LIST(auxElecHeatNrgConsPool,
F("auxelecheatnrgconspool"),
F("auxiliary electrical heater energy consumption pool"),
F("Energieverbrauch el. Zusatzheizung Pool"))
MAKE_PSTR_LIST(hpCompOn, F("hpcompon"), F("hp compressor"), F("HP Compressor")) // need DE
MAKE_PSTR_LIST(hpHeatingOn, F("hpheatingon"), F("hp heating"), F("HP Heating")) // need DE
MAKE_PSTR_LIST(hpCoolingOn, F("hpcoolingon"), F("hp cooling"), F("HP Cooling")) // need DE
MAKE_PSTR_LIST(hpWwOn, F("hpwwon"), F("hp dhw"), F("HP dhw")) // need DE
MAKE_PSTR_LIST(hpPoolOn, F("hppoolon"), F("hp pool"), F("HP Pool")) // need DE
MAKE_PSTR_LIST(hpBrinePumpSpd, F("hpbrinepumpspd"), F("brine pump speed"), F("Brine Pump Speed")) // need DE
MAKE_PSTR_LIST(hpCompSpd, F("hpcompspd"), F("compressor speed"), F("Compressor Speed")) // need DE
MAKE_PSTR_LIST(hpCircSpd, F("hpcircspd"), F("circulation pump speed"), F("Circulation pump Speed")) // need DE
MAKE_PSTR_LIST(hpBrineIn, F("hpbrinein"), F("brine in/evaporator"), F("Brine in/Evaporator")) // need DE
MAKE_PSTR_LIST(hpBrineOut, F("hpbrineout"), F("brine out/condenser"), F("Brine out/Condenser")) // need DE
MAKE_PSTR_LIST(hpSuctionGas, F("hpsuctiongas"), F("suction gas"), F("Suction gas")) // need DE
MAKE_PSTR_LIST(hpHotGas, F("hphotgas"), F("hot gas/compressed"), F("Hot gas/Compressed")) // need DE
MAKE_PSTR_LIST(hpSwitchValve, F("hpswitchvalve"), F("switch valve"), F("Switch Valve")) // need DE
MAKE_PSTR_LIST(hpActivity, F("hpactivity"), F("compressor activity"), F("Compressor Activity")) // need DE
MAKE_PSTR_LIST(hpPower, F("hppower"), F("compressor power output"), F("Leistung Wärmepumpe"))
MAKE_PSTR_LIST(hpTc0, F("hptc0"), F("heat carrier return (TC0)"), F("Wärmeträgerflüssigkeit Eingang (TC0)"))
MAKE_PSTR_LIST(hpTc1, F("hptc1"), F("heat carrier forward (TC1)"), F("Wärmeträgerflüssigkeit Ausgang (TC1)"))
MAKE_PSTR_LIST(hpTc3, F("hptc3"), F("condenser temperature (TC3)"), F("Verflüssigertemperatur (TC3)"))
MAKE_PSTR_LIST(hpTr3, F("hptr3"), F("refrigerant temperature liquid side (condenser output) (TR3)"), F("Temperaturfühler Kältemittel (Flüssigkeit) (TR3)"))
MAKE_PSTR_LIST(hpTr4, F("hptr4"), F("evaporator inlet temperature (TR4)"), F("Verdampfer Eintritt (TR4)"))
MAKE_PSTR_LIST(hpTr5, F("hptr5"), F("compressor Inlet temperature (TR5)"), F("Temperaturfühler Kompessoransaugleitung (TR5)"))
MAKE_PSTR_LIST(hpTr6, F("hptr6"), F("compressor outlet temperature (TR6)"), F("Temperaturfühler Kompressorausgangsleitung (TR6)"))
MAKE_PSTR_LIST(hpTr7, F("hptr7"), F("refrigerant temperature gas side (condenser input) (TR7)"), F("Temperaturfühler Kältemittel (Gas) (TR7)"))
MAKE_PSTR_LIST(hpTl2, F("hptl2"), F("air inlet temperature (TL2)"), F("Außenlufttemperaturfühler (TL2)"))
MAKE_PSTR_LIST(hpPl1, F("hppl1"), F("low pressure side temperature (PL1)"), F("Niedrigdruckfühler (PL1)"))
MAKE_PSTR_LIST(hpPh1, F("hpph1"), F("high pressure side temperature (PH1)"), F("Hochdruckfühler (PH1)"))
// hybrid heatpump
MAKE_PSTR_LIST(hybridStrategy, F("hybridstrategy"), F("hybrid control strategy")) // need DE
MAKE_PSTR_LIST(switchOverTemp, F("switchovertemp"), F("outside switchover temperature")) // need DE
MAKE_PSTR_LIST(energyCostRatio, F("energycostratio"), F("energy cost ratio")) // need DE
MAKE_PSTR_LIST(fossileFactor, F("fossilefactor"), F("fossile energy factor")) // need DE
MAKE_PSTR_LIST(electricFactor, F("electricfactor"), F("electric energy factor")) // need DE
MAKE_PSTR_LIST(delayBoiler, F("delayboiler"), F("delay boiler support")) // need DE
MAKE_PSTR_LIST(tempDiffBoiler, F("tempdiffboiler"), F("temp diff boiler support")) // need DE
// alternative heatsource AM200
MAKE_PSTR_LIST(aCylTopTemp, F("cyltoptemp"), F("cylinder top temperature"), F("Zylinder oben Temperatur"))
MAKE_PSTR_LIST(aCylCenterTemp, F("cylcentertemp"), F("cylinder center temperature"), F("Zylinder mitte Temperatur"))
MAKE_PSTR_LIST(aCylBottomTemp, F("cylbottomtemp"), F("cylinder bottom temperature"), F("Zylinder unten Temperatur"))
MAKE_PSTR_LIST(aFlowTemp, F("altflowtemp"), F("alternative hs flow temperature"), F("Alternativ hs Flusstemperatur"))
MAKE_PSTR_LIST(aRetTemp, F("altrettemp"), F("alternative hs return temperature"), F("Alternativ hs Rücktemperatur"))
MAKE_PSTR_LIST(sysFlowTemp, F("sysflowtemp"), F("system flow temperature"), F("System Flusstemperature"))
MAKE_PSTR_LIST(sysRetTemp, F("sysrettemp"), F("system return temperature"), F("System Rücktemperature"))
MAKE_PSTR_LIST(valveByPass, F("valvebypass"), F("bypass valve"), F("bypass Ventil"))
MAKE_PSTR_LIST(valveBuffer, F("valvebuffer"), F("buffer valve"), F("Puffer Ventil"))
MAKE_PSTR_LIST(valveReturn, F("valvereturn"), F("return valve"), F("Rückfluss Ventil"))
MAKE_PSTR_LIST(aPumpMod, F("altpumpmod"), F("alternative hs pump modulation"), F("Alternativ hs Pumpenmodulation"))
MAKE_PSTR_LIST(heatSource, F("heatsource"), F("alternative heating active"), F("Alternativ Heizung"))
MAKE_PSTR_LIST(vr2Config, F("vr2config"), F("vr2 configuration")) // need DE
MAKE_PSTR_LIST(ahsActivated, F("ahsactivated"), F("alternate heat source activation")) // need DE
MAKE_PSTR_LIST(aPumpConfig, F("apumpconfig"), F("primary pump config")) // need DE
MAKE_PSTR_LIST(aPumpSignal, F("apumpsignal"), F("output for pr1 pump")) // need DE
MAKE_PSTR_LIST(aPumpMin, F("apumpmin"), F("min output pump pr1")) // need DE
MAKE_PSTR_LIST(tempRise, F("temprise"), F("ahs return temp rise")) // need DE
MAKE_PSTR_LIST(setReturnTemp, F("setreturntemp"), F("set temp return")) // need DE
MAKE_PSTR_LIST(mixRuntime, F("mixruntime"), F("mixer run time")) // need DE
MAKE_PSTR_LIST(bufBypass, F("bufbypass"), F("buffer bypass config")) // need DE
MAKE_PSTR_LIST(bufMixRuntime, F("bufmixruntime"), F("bypass mixer run time")) // need DE
MAKE_PSTR_LIST(bufConfig, F("bufconfig"), F("dhw buffer config")) // need DE
MAKE_PSTR_LIST(blockMode, F("blockmode"), F("config htg. blocking mode")) // need DE
MAKE_PSTR_LIST(blockTerm, F("blockterm"), F("config of block terminal")) // need DE
MAKE_PSTR_LIST(blockHyst, F("blockhyst"), F("hyst. for bolier block")) // need DE
MAKE_PSTR_LIST(releaseWait, F("releasewait"), F("boiler release wait time")) // need DE
// the following are dhw for the boiler and automatically tagged with 'ww'
MAKE_PSTR_LIST(wwSelTempLow, F("wwseltemplow"), F("selected lower temperature")) // need DE
MAKE_PSTR_LIST(wwSelTempOff, F("wwseltempoff"), F("selected temperature for off")) // need DE
MAKE_PSTR_LIST(wwSelTempSingle, F("wwseltempsingle"), F("single charge temperature")) // need DE
MAKE_PSTR_LIST(wwCylMiddleTemp, F("wwcylmiddletemp"), F("cylinder middle temperature (TS3)")) // need DE
MAKE_PSTR_LIST(wwSelTemp, F("wwseltemp"), F("selected temperature"), F("gewählte Temperatur"))
MAKE_PSTR_LIST(wwSetTemp, F("wwsettemp"), F("set temperature"), F("Solltemperatur"))
MAKE_PSTR_LIST(wwType, F("wwtype"), F("type"), F("Typ"))
MAKE_PSTR_LIST(wwComfort, F("wwcomfort"), F("comfort"), F("Komfort"))
MAKE_PSTR_LIST(wwComfort1, F("wwcomfort1"), F("comfort mode"), F("Komfort mode"))
MAKE_PSTR_LIST(wwFlowTempOffset, F("wwflowtempoffset"), F("flow temperature offset"), F("Flusstemperaturanhebung"))
MAKE_PSTR_LIST(wwMaxPower, F("wwmaxpower"), F("max power"), F("max Leistung"))
MAKE_PSTR_LIST(wwCircPump, F("wwcircpump"), F("circulation pump available"), F("Zirkulationspumpe vorhanden"))
MAKE_PSTR_LIST(wwChargeType, F("wwchargetype"), F("charging type"), F("Ladungstyp"))
MAKE_PSTR_LIST(wwDisinfectionTemp, F("wwdisinfectiontemp"), F("disinfection temperature"), F("Desinfectionstemperatur"))
MAKE_PSTR_LIST(wwCircMode, F("wwcircmode"), F("circulation pump mode"), F("Zirkulationspumpenfrequenz"))
MAKE_PSTR_LIST(wwCirc, F("wwcirc"), F("circulation active"), F("Zirkulation aktiv"))
MAKE_PSTR_LIST(wwCurTemp, F("wwcurtemp"), F("current intern temperature"), F("aktuelle Warmwasser Temperatur intern"))
MAKE_PSTR_LIST(wwCurTemp2, F("wwcurtemp2"), F("current extern temperature"), F("aktuelle Warmwaser Temperatur extern"))
MAKE_PSTR_LIST(wwCurFlow, F("wwcurflow"), F("current tap water flow"), F("aktueller Durchfluss"))
MAKE_PSTR_LIST(wwStorageTemp1, F("wwstoragetemp1"), F("storage intern temperature"), F("interne Speichertemperature"))
MAKE_PSTR_LIST(wwStorageTemp2, F("wwstoragetemp2"), F("storage extern temperature"), F("externer Speichertemperatur"))
MAKE_PSTR_LIST(wwActivated, F("wwactivated"), F("activated"), F("aktiviert"))
MAKE_PSTR_LIST(wwOneTime, F("wwonetime"), F("one time charging"), F("Einmalladung"))
MAKE_PSTR_LIST(wwDisinfecting, F("wwdisinfecting"), F("disinfecting"), F("Desinfizieren"))
MAKE_PSTR_LIST(wwCharging, F("wwcharging"), F("charging"), F("Laden"))
MAKE_PSTR_LIST(wwChargeOptimization, F("wwchargeoptimization"), F("charge optimization"), F("charge optimization"))
MAKE_PSTR_LIST(wwRecharging, F("wwrecharging"), F("recharging"), F("Nachladen"))
MAKE_PSTR_LIST(wwTempOK, F("wwtempok"), F("temperature ok"), F("Temperatur ok"))
MAKE_PSTR_LIST(wwActive, F("wwactive"), F("active"), F("aktiv"))
MAKE_PSTR_LIST(ww3wayValve, F("ww3wayvalve"), F("3-way valve active"), F("3-Wegeventil aktiv"))
MAKE_PSTR_LIST(wwSetPumpPower, F("wwsetpumppower"), F("set pump power"), F("Soll Pumpenleistung"))
MAKE_PSTR_LIST(wwMixerTemp, F("wwmixertemp"), F("mixer temperature"), F("Mischertemperatur"))
MAKE_PSTR_LIST(wwStarts, F("wwstarts"), F("starts"), F("Anzahl starts"))
MAKE_PSTR_LIST(wwStarts2, F("wwstarts2"), F("control starts2"), F("Kreis 2 Anzahl Starts"))
MAKE_PSTR_LIST(wwWorkM, F("wwworkm"), F("active time"), F("aktive Zeit"))
MAKE_PSTR_LIST(wwHystOn, F("wwhyston"), F("hysteresis on temperature"), F("Hysterese Einschalttemperatur"))
MAKE_PSTR_LIST(wwHystOff, F("wwhystoff"), F("hysteresis off temperature"), F("Hysterese Ausschalttemperatur"))
MAKE_PSTR_LIST(wwProgMode, F("wwprogmode"), F("program"), F("Programmmodus"))
MAKE_PSTR_LIST(wwCircProg, F("wwcircprog"), F("circulation program"), F("Zirkulationsprogramm"))
MAKE_PSTR_LIST(wwMaxTemp, F("wwmaxtemp"), F("maximum temperature"), F("Maximale Temperatur"))
MAKE_PSTR_LIST(wwOneTimeKey, F("wwonetimekey"), F("one time key function"), F("Einmalladungstaste"))
// mqtt values / commands
MAKE_PSTR_LIST(switchtime, F("switchtime"), F("program switchtime"), F("Program Schaltzeit"))
MAKE_PSTR_LIST(switchtime1, F("switchtime1"), F("own1 program switchtime"), F("Program 1 Schaltzeit"))
MAKE_PSTR_LIST(switchtime2, F("switchtime2"), F("own2 program switchtime"), F("Programm 2 Schaltzeit"))
MAKE_PSTR_LIST(wwswitchtime, F("wwswitchtime"), F("program switchtime"), F("Programm Schaltzeit"))
MAKE_PSTR_LIST(wwcircswitchtime, F("wwcircswitchtime"), F("circulation program switchtime"), F("Zirculationsprogramm Schaltzeit"))
MAKE_PSTR_LIST(dateTime, F("datetime"), F("date/time"), F("Datum/Zeit"))
MAKE_PSTR_LIST(errorCode, F("errorcode"), F("error code"), F("Fehlermeldung"))
MAKE_PSTR_LIST(ibaMainDisplay, F("display"), F("display"), F("Anzeige"))
MAKE_PSTR_LIST(ibaLanguage, F("language"), F("language"), F("Sprache"))
MAKE_PSTR_LIST(ibaClockOffset, F("clockoffset"), F("clock offset"), F("Uhrkorrektur"))
MAKE_PSTR_LIST(ibaBuildingType, F("building"), F("building type"), F("Gebäude"))
MAKE_PSTR_LIST(heatingPID, F("heatingpid"), F("heating PID"), F("heating PID"))
MAKE_PSTR_LIST(ibaCalIntTemperature, F("intoffset"), F("internal temperature offset"), F("Korrektur interner Temperatur"))
MAKE_PSTR_LIST(ibaMinExtTemperature, F("minexttemp"), F("minimal external temperature"), F("min Aussentemperatur"))
MAKE_PSTR_LIST(backlight, F("backlight"), F("key backlight"), F("Gegenlicht"))
MAKE_PSTR_LIST(damping, F("damping"), F("damping outdoor temperature"), F("Dämpfung der Außentemperatur"))
MAKE_PSTR_LIST(tempsensor1, F("inttemp1"), F("temperature sensor 1"), F("Temperatursensor 1"))
MAKE_PSTR_LIST(tempsensor2, F("inttemp2"), F("temperature sensor 2"), F("Temperatursensor 2"))
MAKE_PSTR_LIST(dampedoutdoortemp, F("dampedoutdoortemp"), F("damped outdoor temperature"), F("gedämpfte Aussentemperatur"))
MAKE_PSTR_LIST(floordrystatus, F("floordry"), F("floor drying"), F("Estrichtrocknung"))
MAKE_PSTR_LIST(floordrytemp, F("floordrytemp"), F("floor drying temperature"), F("Estrichtrocknungs Temperatur"))
MAKE_PSTR_LIST(brightness, F("brightness"), F("screen brightness"), F("bildschirmhelligkeit"))
MAKE_PSTR_LIST(autodst, F("autodst"), F("automatic change daylight saving time"), F("automatische sommerzeit umstellung"))
MAKE_PSTR_LIST(preheating, F("preheating"), F("preheating in the clock program"), F("vorheizen im uhrenprogramm"))
MAKE_PSTR_LIST(offtemp, F("offtemp"), F("temperature when mode is off"), F("temperatur bei ausgeschaltetem modus"))
MAKE_PSTR_LIST(mixingvalves, F("mixingvalves"), F("mixing valves"), F("mischventile"))
// thermostat ww
MAKE_PSTR_LIST(wwMode, F("wwmode"), F("mode"), F("modus"))
MAKE_PSTR_LIST(wwSetTempLow, F("wwsettemplow"), F("set low temperature"), F("untere Solltemperatur"))
MAKE_PSTR_LIST(wwWhenModeOff, F("wwwhenmodeoff"), F("when thermostat mode off"), F("wenn Thermostatmodus ist aus"))
MAKE_PSTR_LIST(wwExtra1, F("wwextra1"), F("circuit 1 extra"), F("Kreis 1 Extra"))
MAKE_PSTR_LIST(wwExtra2, F("wwextra2"), F("circuit 2 extra"), F("Kreis 2 Extra"))
MAKE_PSTR_LIST(wwCharge, F("wwcharge"), F("charge")) // need DE
MAKE_PSTR_LIST(wwChargeDuration, F("wwchargeduration"), F("charge duration")) // need DE
MAKE_PSTR_LIST(wwDisinfect, F("wwdisinfect"), F("disinfection")) // need DE
MAKE_PSTR_LIST(wwDisinfectDay, F("wwdisinfectday"), F("disinfection day")) // need DE
MAKE_PSTR_LIST(wwDisinfectHour, F("wwdisinfecthour"), F("disinfection hour")) // need DE
MAKE_PSTR_LIST(wwDisinfectTime, F("wwdisinfecttime"), F("disinfection time")) // need DE
MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating")) // need DE
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time")) // need DE
// thermostat hc
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("selected room temperature"), F("Sollwert Raumtemperatur"))
MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("current room temperature"), F("aktuelle Raumtemperatur"))
MAKE_PSTR_LIST(mode, F("mode"), F("mode"), F("modus"))
MAKE_PSTR_LIST(modetype, F("modetype"), F("mode type"), F("modus Typ"))
MAKE_PSTR_LIST(fastheatup, F("fastheatup"), F("fast heatup"), F("schnelles Aufheizen"))
MAKE_PSTR_LIST(daytemp, F("daytemp"), F("day temperature"), F("Tagestemperatur"))
MAKE_PSTR_LIST(daylowtemp, F("daytemp2"), F("day temperature T2"), F("Tagestemperatur T2"))
MAKE_PSTR_LIST(daymidtemp, F("daytemp3"), F("day temperature T3"), F("Tagestemperatur T3"))
MAKE_PSTR_LIST(dayhightemp, F("daytemp4"), F("day temperature T4"), F("Tagestemperatur T4"))
MAKE_PSTR_LIST(heattemp, F("heattemp"), F("heat temperature"), F("Heizen Temperatur"))
MAKE_PSTR_LIST(nighttemp, F("nighttemp"), F("night temperature"), F("Nachttemperatur"))
MAKE_PSTR_LIST(nighttemp2, F("nighttemp"), F("night temperature T1"), F("Nachttemperatur T1"))
MAKE_PSTR_LIST(ecotemp, F("ecotemp"), F("eco temperature"), F("eco Temperatur"))
MAKE_PSTR_LIST(manualtemp, F("manualtemp"), F("manual temperature"), F("manuelle Temperatur"))
MAKE_PSTR_LIST(tempautotemp, F("tempautotemp"), F("temporary set temperature automode"), F("zwischenzeitliche Solltemperatur"))
MAKE_PSTR_LIST(remoteseltemp, F("remoteseltemp"), F("temporary set temperature from remote")) // need DE
MAKE_PSTR_LIST(comforttemp, F("comforttemp"), F("comfort temperature"), F("Komforttemperatur"))
MAKE_PSTR_LIST(summertemp, F("summertemp"), F("summer temperature"), F("Sommertemperatur"))
MAKE_PSTR_LIST(designtemp, F("designtemp"), F("design temperature"), F("design-Temperatur"))
MAKE_PSTR_LIST(offsettemp, F("offsettemp"), F("offset temperature"), F("Temperaturanhebung"))
MAKE_PSTR_LIST(minflowtemp, F("minflowtemp"), F("min flow temperature"), F("min Flusstemperatur"))
MAKE_PSTR_LIST(maxflowtemp, F("maxflowtemp"), F("max flow temperature"), F("max Flusstemperatur"))
MAKE_PSTR_LIST(roominfluence, F("roominfluence"), F("room influence"), F("Raumeinfluss"))
MAKE_PSTR_LIST(roominfl_factor, F("roominflfactor"), F("room influence factor"), F("Raumeinfluss Factor"))
MAKE_PSTR_LIST(curroominfl, F("curroominfl"), F("current room influence"), F("aktueller Raumeinfluss"))
MAKE_PSTR_LIST(nofrosttemp, F("nofrosttemp"), F("nofrost temperature"), F("Frostschutztemperatur"))
MAKE_PSTR_LIST(targetflowtemp, F("targetflowtemp"), F("target flow temperature"), F("berechnete Flusstemperatur"))
MAKE_PSTR_LIST(heatingtype, F("heatingtype"), F("heating type"), F("Heizungstyp"))
MAKE_PSTR_LIST(summersetmode, F("summersetmode"), F("set summer mode"), F("Einstellung Sommerbetrieb"))
MAKE_PSTR_LIST(hpoperatingmode, F("hpoperatingmode"), F("heatpump operating mode"), F("Wärmepumpe Betriebsmodus"))
MAKE_PSTR_LIST(hpoperatingstate, F("hpoperatingstate"), F("heatpump operating state"), F("heatpump operating state"))
MAKE_PSTR_LIST(controlmode, F("controlmode"), F("control mode"), F("Kontrollmodus"))
MAKE_PSTR_LIST(control, F("control"), F("control device"), F("Fernsteuerung"))
MAKE_PSTR_LIST(program, F("program"), F("program"), F("Programm"))
MAKE_PSTR_LIST(pause, F("pause"), F("pause time"), F("Pausenzeit"))
MAKE_PSTR_LIST(party, F("party"), F("party time"), F("Partyzeit"))
MAKE_PSTR_LIST(holidaytemp, F("holidaytemp"), F("holiday temperature"), F("Urlaubstemperatur"))
MAKE_PSTR_LIST(summermode, F("summermode"), F("summer mode"), F("Sommerbetrieb"))
MAKE_PSTR_LIST(holidaymode, F("holidaymode"), F("holiday mode"), F("Urlaubsbetrieb"))
MAKE_PSTR_LIST(flowtempoffset, F("flowtempoffset"), F("flow temperature offset for mixer"), F("Flusstemperaturanhebung"))
MAKE_PSTR_LIST(reducemode, F("reducemode"), F("reduce mode"), F("Absenkmodus"))
MAKE_PSTR_LIST(noreducetemp, F("noreducetemp"), F("no reduce below temperature"), F("Absenkung unterbrechen unter Temperatur"))
MAKE_PSTR_LIST(reducetemp, F("reducetemp"), F("off/reduce switch temperature"), F("Absenkmodus unter Temperatur"))
MAKE_PSTR_LIST(vacreducetemp, F("vacreducetemp"), F("vacations off/reduce switch temperature"), F("Urlaub Absenkmodus unter Temperatur"))
MAKE_PSTR_LIST(vacreducemode, F("vacreducemode"), F("vacations reduce mode"), F("Urlaub Absenkmodus"))
MAKE_PSTR_LIST(nofrostmode, F("nofrostmode"), F("nofrost mode"), F("Frostschutz Modus"))
MAKE_PSTR_LIST(remotetemp, F("remotetemp"), F("room temperature from remote"), F("Raumtemperatur der Fernsteuerung"))
MAKE_PSTR_LIST(wwHolidays, F("wwholidays"), F("holiday dates")) // need DE
MAKE_PSTR_LIST(wwVacations, F("wwvacations"), F("vacation dates")) // need DE
MAKE_PSTR_LIST(holidays, F("holidays"), F("holiday dates")) // need DE
MAKE_PSTR_LIST(vacations, F("vacations"), F("vacation dates")) // need DE
MAKE_PSTR_LIST(wwprio, F("wwprio"), F("dhw priority")) // need DE
MAKE_PSTR_LIST(nofrostmode1, F("nofrostmode1"), F("nofrost mode")) // need DE
MAKE_PSTR_LIST(reducehours, F("reducehours"), F("duration for nighttemp")) // need DE
MAKE_PSTR_LIST(reduceminutes, F("reduceminutes"), F("remaining time for nightmode")) // need DE
MAKE_PSTR_LIST(switchonoptimization, F("switchonoptimization"), F("switch-on optimization")) // need DE
// heatpump
MAKE_PSTR_LIST(airHumidity, F("airhumidity"), F("relative air humidity"), F("relative Luftfeuchte"))
MAKE_PSTR_LIST(dewTemperature, F("dewtemperature"), F("dew point temperature"), F("Taupunkttemperatur"))
// mixer
MAKE_PSTR_LIST(flowSetTemp, F("flowsettemp"), F("setpoint flow temperature"), F("Sollwert Flusstemperatur"))
MAKE_PSTR_LIST(flowTempHc, F("flowtemphc"), F("flow temperature (TC1)"), F("Flusstemperatur des hk (TC1)"))
MAKE_PSTR_LIST(pumpStatus, F("pumpstatus"), F("pump status (PC1)"), F("Pumpenstatus des hk (PC1)"))
MAKE_PSTR_LIST(mixerStatus, F("valvestatus"), F("mixing valve actuator (VC1)"), F("Mischerventil Position (VC1)"))
MAKE_PSTR_LIST(flowTempVf, F("flowtempvf"), F("flow temperature in header (T0/Vf)"), F("Flusstemperatur am Kessel (T0/Vf)"))
MAKE_PSTR_LIST(mixerSetTime, F("valvesettime"), F("time to set valve"), F("Zeit zum Einstellen des Ventils"))
// mixer prefixed with wwc
MAKE_PSTR_LIST(wwPumpStatus, F("pumpstatus"), F("pump status in assigned wwc (PC1)"), F("Pumpenstatus des wwk (PC1)"))
MAKE_PSTR_LIST(wwTempStatus, F("wwtempstatus"), F("temperature switch in assigned wwc (MC1)"), F("Temperaturschalter des wwk (MC1)"))
MAKE_PSTR_LIST(wwTemp, F("wwtemp"), F("current temperature"), F("aktuelle Temperatur"))
// mixer pool
MAKE_PSTR_LIST(poolSetTemp, F("poolsettemp"), F("pool set temperature")) // need DE
MAKE_PSTR_LIST(poolTemp, F("pooltemp"), F("pool temperature")) // need DE
MAKE_PSTR_LIST(poolShuntStatus, F("poolshuntstatus"), F("pool shunt status opening/closing")) // need DE
MAKE_PSTR_LIST(poolShunt, F("poolshunt"), F("pool shunt open/close (0% = pool / 100% = heat)")) // need DE
MAKE_PSTR_LIST(hydrTemp, F("hydrTemp"), F("hydraulic header temperature")) // need DE
// solar
MAKE_PSTR_LIST(cylMiddleTemp, F("cylmiddletemp"), F("cylinder middle temperature (TS3)"), F("cylinder middle temperature (TS3)")) // need DE
MAKE_PSTR_LIST(retHeatAssist, F("retheatassist"), F("return temperature heat assistance (TS4)"), F("return temperature heat assistance (TS4)")) // need DE
MAKE_PSTR_LIST(m1Valve, F("heatassistvalve"), F("heat assistance valve (M1)"), F("heat assistance valve (M1)")) // need DE
MAKE_PSTR_LIST(m1Power, F("heatassistpower"), F("heat assistance valve power (M1)"), F("heat assistance valve power (M1)")) // need DE
MAKE_PSTR_LIST(pumpMinMod, F("pumpminmod"), F("minimum pump modulation")) // need DE
MAKE_PSTR_LIST(maxFlow, F("maxflow"), F("maximum solar flow")) // need DE
MAKE_PSTR_LIST(solarPower, F("solarpower"), F("actual solar power")) // need DE
MAKE_PSTR_LIST(solarPumpTurnonDiff, F("turnondiff"), F("pump turn on difference")) // need DE
MAKE_PSTR_LIST(solarPumpTurnoffDiff, F("turnoffdiff"), F("pump turn off difference")) // need DE
MAKE_PSTR_LIST(pump2MinMod, F("pump2minmod"), F("minimum pump 2 modulation")) // need DE
MAKE_PSTR_LIST(solarPump2TurnonDiff, F("turnondiff2"), F("pump 2 turn on difference")) // need DE
MAKE_PSTR_LIST(solarPump2TurnoffDiff, F("turnoffdiff2"), F("pump 2 turn off difference")) // need DE
MAKE_PSTR_LIST(collectorTemp, F("collectortemp"), F("collector temperature (TS1)"), F("Kollektortemperatur (TS1)"))
MAKE_PSTR_LIST(collector2Temp, F("collector2temp"), F("collector 2 temperature (TS7)"), F("collector 2 temperature (TS7)"))
MAKE_PSTR_LIST(cylBottomTemp, F("cylbottomtemp"), F("cylinder bottom temperature (TS2)"), F("Speicher Bodentemperatur (TS2)"))
MAKE_PSTR_LIST(cyl2BottomTemp, F("cyl2bottomtemp"), F("second cylinder bottom temperature (TS5)"), F("2. Speicher Bodentemperatur (TS5)"))
MAKE_PSTR_LIST(heatExchangerTemp, F("heatexchangertemp"), F("heat exchanger temperature (TS6)"), F("wärmetauscher Temperatur (TS6)"))
MAKE_PSTR_LIST(collectorMaxTemp, F("collectormaxtemp"), F("maximum collector temperature"), F("maximale Kollektortemperatur"))
MAKE_PSTR_LIST(collectorMinTemp, F("collectormintemp"), F("minimum collector temperature"), F("minimale Kollektortemperatur"))
MAKE_PSTR_LIST(cylMaxTemp, F("cylmaxtemp"), F("maximum cylinder temperature"), F("maximale Speichertemperatur"))
MAKE_PSTR_LIST(solarPumpMod, F("solarpumpmod"), F("pump modulation (PS1)"), F("Pumpenmodulation (PS1)"))
MAKE_PSTR_LIST(cylPumpMod, F("cylpumpmod"), F("cylinder pump modulation (PS5)"), F("Speicherpumpenmodulation (PS5)"))
MAKE_PSTR_LIST(solarPump, F("solarpump"), F("pump (PS1)"), F("Pumpe (PS1)"))
MAKE_PSTR_LIST(solarPump2, F("solarpump2"), F("pump 2 (PS4)"), F("pump 2 (PS4)"))
MAKE_PSTR_LIST(solarPump2Mod, F("solarpump2mod"), F("pump 2 modulation (PS4)"), F("pump 2 modulation (PS4)"))
MAKE_PSTR_LIST(valveStatus, F("valvestatus"), F("valve status"), F("ventilstatus"))
MAKE_PSTR_LIST(cylHeated, F("cylheated"), F("cyl heated"), F("Speichertemperatur erreicht"))
MAKE_PSTR_LIST(collectorShutdown, F("collectorshutdown"), F("collector shutdown"), F("Kollektorabschaltung"))
MAKE_PSTR_LIST(pumpWorkTime, F("pumpworktime"), F("pump working time"), F("Pumpenlaufzeit"))
MAKE_PSTR_LIST(pump2WorkTime, F("pump2worktime"), F("pump 2 working time"), F("Pumpe 2 Laufzeit"))
MAKE_PSTR_LIST(m1WorkTime, F("m1worktime"), F("differential control working time"), F("Differenzregelung Arbeitszeit"))
MAKE_PSTR_LIST(energyLastHour, F("energylasthour"), F("energy last hour"), F("Energie letzte Std"))
MAKE_PSTR_LIST(energyTotal, F("energytotal"), F("total energy"), F("Gesamtenergie"))
MAKE_PSTR_LIST(energyToday, F("energytoday"), F("total energy today"), F("Energie heute"))
// solar ww
MAKE_PSTR_LIST(cyl1, F("cyl 1"), F("Zyl_1"))
MAKE_PSTR_LIST(cyl2, F("cyl 2"), F("Zyl_2"))
MAKE_PSTR_LIST(wwTemp1, F("wwtemp1"), F("temperature 1"), F("Temperatur 1"))
MAKE_PSTR_LIST(wwTemp3, F("wwtemp3"), F("temperature 3"), F("Temperatur 3"))
MAKE_PSTR_LIST(wwTemp4, F("wwtemp4"), F("temperature 4"), F("Temperatur 4"))
MAKE_PSTR_LIST(wwTemp5, F("wwtemp5"), F("temperature 5"), F("Temperatur 5"))
MAKE_PSTR_LIST(wwTemp7, F("wwtemp7"), F("temperature 7"), F("Temperatur 7"))
MAKE_PSTR_LIST(wwPump, F("wwpump"), F("pump"), F("Pumpe"))
// solar ww and mixer wwc
MAKE_PSTR_LIST(wwMinTemp, F("wwmintemp"), F("minimum temperature"), F("minimale Temperatur"))
MAKE_PSTR_LIST(wwRedTemp, F("wwredtemp"), F("reduced temperature"), F("redizierte Temperatur"))
MAKE_PSTR_LIST(wwDailyTemp, F("wwdailytemp"), F("daily temperature"), F("tägl. Temperatur"))
MAKE_PSTR_LIST(wwKeepWarm, F("wwkeepwarm"), F("keep warm"), F("Warmhalten"))
MAKE_PSTR_LIST(wwStatus2, F("wwstatus2"), F("status 2"), F("Status 2"))
MAKE_PSTR_LIST(wwPumpMod, F("wwpumpmod"), F("pump modulation"), F("Pumpen Modulation"))
MAKE_PSTR_LIST(wwFlow, F("wwflow"), F("flow rate"), F("Flussrate"))
// extra mixer ww
MAKE_PSTR_LIST(wwRequiredTemp, F("wwrequiredtemp"), F("required temperature"), F("benötigte Temperatur"))
MAKE_PSTR_LIST(wwDiffTemp, F("wwdifftemp"), F("start differential temperature"), F("Start Differential Temperatur"))
// SM100
MAKE_PSTR_LIST(heatTransferSystem, F("heattransfersystem"), F("heattransfer system"), F("Wärmetransfer System"))
MAKE_PSTR_LIST(externalCyl, F("externalcyl"), F("external cylinder"), F("Externer Speicher"))
MAKE_PSTR_LIST(thermalDisinfect, F("thermaldisinfect"), F("thermal disinfection"), F("Thermische Desinfektion"))
MAKE_PSTR_LIST(heatMetering, F("heatmetering"), F("heatmetering"), F("Wärmemessung"))
MAKE_PSTR_LIST(solarIsEnabled, F("solarenabled"), F("solarmodule enabled"), F("Solarmodul aktiviert"))
// telegram 0x035A
MAKE_PSTR_LIST(solarPumpMode, F("solarpumpmode"), F("pump mode"), F("solar Pumpen Einst."))
MAKE_PSTR_LIST(solarPumpKick, F("pumpkick"), F("pump kick"), F("pump kick"))
MAKE_PSTR_LIST(plainWaterMode, F("plainwatermode"), F("plain water mode"), F("plain water mode"))
MAKE_PSTR_LIST(doubleMatchFlow, F("doublematchflow"), F("doublematchflow"), F("doublematchflow"))
MAKE_PSTR_LIST(solarPump2Mode, F("pump2mode"), F("pump 2 mode"), F("pump 2 mode"))
MAKE_PSTR_LIST(solarPump2Kick, F("pump2kick"), F("pump kick 2"), F("pump kick 2"))
// telegram 0x035F
MAKE_PSTR_LIST(cylPriority, F("cylpriority"), F("cylinder priority"), F("Speicher Priorität"))
// telegram 0x380
MAKE_PSTR_LIST(climateZone, F("climatezone"), F("climate zone"), F("Klimazone"))
MAKE_PSTR_LIST(collector1Area, F("collector1area"), F("collector 1 area"), F("Kollektor 1 Fläche"))
MAKE_PSTR_LIST(collector1Type, F("collector1type"), F("collector 1 type"), F("Kollektor 1 Type"))
MAKE_PSTR_LIST(collector2Area, F("collector2area"), F("collector 2 area"), F("Kollektor 2 Fläche"))
MAKE_PSTR_LIST(collector2Type, F("collector2type"), F("collector 2 type"), F("Kollektor 2 Type"))
// telegram 0x0363 heatCounter
MAKE_PSTR_LIST(heatCntFlowTemp, F("heatcntflowtemp"), F("heat counter flow temperature"), F("Wärmezähler Fluss-Temperatur"))
MAKE_PSTR_LIST(heatCntRetTemp, F("heatcntrettemp"), F("heat counter return temperature"), F("Wärmezähler Rückfluss-Temperatur"))
MAKE_PSTR_LIST(heatCnt, F("heatcnt"), F("heat counter impulses"), F("Wärmezäler Impulse"))
MAKE_PSTR_LIST(swapFlowTemp, F("swapflowtemp"), F("swap flow temperature (TS14)"), F("Austausch Fluss-Temperatur (TS14)"))
MAKE_PSTR_LIST(swapRetTemp, F("swaprettemp"), F("swap return temperature (TS15)"), F("Austausch Rückfluss-Temperatur (TS15)"))
// switch
MAKE_PSTR_LIST(activated, F("activated"), F("activated"), F("aktiviert"))
MAKE_PSTR_LIST(status, F("status"), F("status"), F("Status"))
// RF sensor, id 0x40, telegram 0x435
MAKE_PSTR_LIST(RFTemp, F("rftemp"), F("RF room temperature sensor"), F("RF Raumtemperatur Sensor"))
// unknown fields to track (SM10)
MAKE_PSTR_LIST(data11, F("data11"), F("unknown datafield 11"))
MAKE_PSTR_LIST(data12, F("data12"), F("unknown datafield 12"))
MAKE_PSTR_LIST(data8, F("data8"), F("unknown datafield 8"))
MAKE_PSTR_LIST(data0, F("data0"), F("unknown datafield 0"))
MAKE_PSTR_LIST(data1, F("data1"), F("unknown datafield 1"))
MAKE_PSTR_LIST(setting3, F("setting3"), F("unknown setting 3"))
MAKE_PSTR_LIST(setting4, F("setting4"), F("unknown setting 4"))

View File

@@ -26,6 +26,7 @@ namespace emsesp {
AsyncMqttClient * Mqtt::mqttClient_; AsyncMqttClient * Mqtt::mqttClient_;
// static parameters we make global // static parameters we make global
std::string Mqtt::system_hostname_; // copy from System::hostname()
std::string Mqtt::mqtt_base_; std::string Mqtt::mqtt_base_;
uint8_t Mqtt::mqtt_qos_; uint8_t Mqtt::mqtt_qos_;
bool Mqtt::mqtt_retain_; bool Mqtt::mqtt_retain_;
@@ -109,7 +110,7 @@ void Mqtt::subscribe(const std::string & topic) {
} }
// resubscribe to all MQTT topics // resubscribe to all MQTT topics
// if it's already in the queue, ignore it // if it's already in the queue then just ignore it
void Mqtt::resubscribe() { void Mqtt::resubscribe() {
if (mqtt_subfunctions_.empty()) { if (mqtt_subfunctions_.empty()) {
return; return;
@@ -277,7 +278,7 @@ void Mqtt::on_message(const char * topic, const char * payload, size_t len) cons
return; return;
} }
// check first againts any of our subscribed topics // check first against any of our subscribed topics
for (const auto & mf : mqtt_subfunctions_) { for (const auto & mf : mqtt_subfunctions_) {
// add the base back // add the base back
char full_topic[MQTT_TOPIC_MAX_SIZE]; char full_topic[MQTT_TOPIC_MAX_SIZE];
@@ -420,6 +421,9 @@ void Mqtt::load_settings() {
publish_time_other_ = mqttSettings.publish_time_other * 1000; publish_time_other_ = mqttSettings.publish_time_other * 1000;
publish_time_sensor_ = mqttSettings.publish_time_sensor * 1000; publish_time_sensor_ = mqttSettings.publish_time_sensor * 1000;
}); });
// get a local copy of the system hostname
system_hostname_ = EMSESP::system_.hostname();
} }
void Mqtt::start() { void Mqtt::start() {
@@ -576,28 +580,31 @@ void Mqtt::on_connect() {
publish(F_(info), doc.as<JsonObject>()); // topic called "info" publish(F_(info), doc.as<JsonObject>()); // topic called "info"
if (ha_enabled_) { if (ha_enabled_) {
queue_unsubscribe_message(discovery_prefix_ + "/climate/" + mqtt_base_ + "/#"); LOG_INFO(F("start removing topics %s/+/%s/#"), discovery_prefix_.c_str(), system_hostname_.c_str());
queue_unsubscribe_message(discovery_prefix_ + "/sensor/" + mqtt_base_ + "/#"); queue_unsubscribe_message(discovery_prefix_ + "/climate/" + system_hostname_ + "/#");
queue_unsubscribe_message(discovery_prefix_ + "/binary_sensor/" + mqtt_base_ + "/#"); queue_unsubscribe_message(discovery_prefix_ + "/sensor/" + system_hostname_ + "/#");
queue_unsubscribe_message(discovery_prefix_ + "/number/" + mqtt_base_ + "/#"); queue_unsubscribe_message(discovery_prefix_ + "/binary_sensor/" + system_hostname_ + "/#");
queue_unsubscribe_message(discovery_prefix_ + "/select/" + mqtt_base_ + "/#"); queue_unsubscribe_message(discovery_prefix_ + "/number/" + system_hostname_ + "/#");
queue_unsubscribe_message(discovery_prefix_ + "/switch/" + mqtt_base_ + "/#"); queue_unsubscribe_message(discovery_prefix_ + "/select/" + system_hostname_ + "/#");
queue_unsubscribe_message(discovery_prefix_ + "/switch/" + system_hostname_ + "/#");
EMSESP::reset_mqtt_ha(); // re-create all HA devices if there are any EMSESP::reset_mqtt_ha(); // re-create all HA devices if there are any
ha_status(); // create the EMS-ESP device in HA, which is MQTT retained ha_status(); // create the EMS-ESP device in HA, which is MQTT retained
ha_climate_reset(true); ha_climate_reset(true);
} else { } else {
queue_subscribe_message(discovery_prefix_ + "/climate/" + mqtt_base_ + "/#"); // TODO commented out - not sure why we need to subscribe if not using discovery. Check with Michael!
queue_subscribe_message(discovery_prefix_ + "/sensor/" + mqtt_base_ + "/#"); /*
queue_subscribe_message(discovery_prefix_ + "/binary_sensor/" + mqtt_base_ + "/#"); queue_subscribe_message(discovery_prefix_ + "/climate/" + system_hostname_ + "/#");
queue_subscribe_message(discovery_prefix_ + "/number/" + mqtt_base_ + "/#"); queue_subscribe_message(discovery_prefix_ + "/sensor/" + system_hostname_ + "/#");
queue_subscribe_message(discovery_prefix_ + "/select/" + mqtt_base_ + "/#"); queue_subscribe_message(discovery_prefix_ + "/binary_sensor/" + system_hostname_ + "/#");
queue_subscribe_message(discovery_prefix_ + "/switch/" + mqtt_base_ + "/#"); queue_subscribe_message(discovery_prefix_ + "/number/" + system_hostname_ + "/#");
LOG_INFO(F("start removing topics %s/+/%s/#"), discovery_prefix_.c_str(), mqtt_base_.c_str()); queue_subscribe_message(discovery_prefix_ + "/select/" + system_hostname_ + "/#");
queue_subscribe_message(discovery_prefix_ + "/switch/" + system_hostname_ + "/#");
*/
} }
// send initial MQTT messages for some of our services // send initial MQTT messages for some of our services
EMSESP::shower_.set_shower_state(false, true); // Send shower_activated as false EMSESP::shower_.set_shower_state(false, true); // Send shower_activated as false
EMSESP::system_.send_heartbeat(); // send heatbeat EMSESP::system_.send_heartbeat(); // send heartbeat
// re-subscribe to all custom registered MQTT topics // re-subscribe to all custom registered MQTT topics
resubscribe(); resubscribe();
@@ -641,7 +648,7 @@ void Mqtt::ha_status() {
ids.add("ems-esp"); ids.add("ems-esp");
char topic[MQTT_TOPIC_MAX_SIZE]; char topic[MQTT_TOPIC_MAX_SIZE];
snprintf(topic, sizeof(topic), "sensor/%s/system/config", mqtt_base_.c_str()); snprintf(topic, sizeof(topic), "sensor/%s/system/config", system_hostname_.c_str());
Mqtt::publish_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag Mqtt::publish_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
// create the sensors - must match the MQTT payload keys // create the sensors - must match the MQTT payload keys
@@ -810,7 +817,7 @@ void Mqtt::process_queue() {
if (message->topic.find(discovery_prefix_) == 0) { if (message->topic.find(discovery_prefix_) == 0) {
strlcpy(topic, message->topic.c_str(), sizeof(topic)); // leave topic as it is strlcpy(topic, message->topic.c_str(), sizeof(topic)); // leave topic as it is
} else { } else {
snprintf(topic, MQTT_TOPIC_MAX_SIZE, "%s/%s", mqtt_base_.c_str(), message->topic.c_str()); snprintf(topic, MQTT_TOPIC_MAX_SIZE, "%s/%s", mqtt_base_.c_str(), message->topic.c_str()); // uses base
} }
// if this has already been published and we're waiting for an ACK, don't publish again // if this has already been published and we're waiting for an ACK, don't publish again
@@ -919,7 +926,8 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
} }
// calculate the min and max // calculate the min and max
int16_t dv_set_min, dv_set_max; int16_t dv_set_min;
int16_t dv_set_max;
(void)dv.get_min_max(dv_set_min, dv_set_max); (void)dv.get_min_max(dv_set_min, dv_set_max);
// determine if we're creating the command topics which we use special HA configs // determine if we're creating the command topics which we use special HA configs
@@ -928,7 +936,7 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
publish_ha_sensor_config(dv.type, publish_ha_sensor_config(dv.type,
dv.tag, dv.tag,
dv.full_name, Helpers::translated_fword(dv.fullname),
dv.device_type, dv.device_type,
dv.short_name, dv.short_name,
dv.uom, dv.uom,
@@ -957,19 +965,19 @@ void Mqtt::publish_system_ha_sensor_config(uint8_t type, const __FlashStringHelp
// note: some extra string copying done here, it looks messy but does help with heap fragmentation issues // note: some extra string copying done here, it looks messy but does help with heap fragmentation issues
void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice::DeviceValueType void Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdevice::DeviceValueType
uint8_t tag, // EMSdevice::DeviceValueTAG uint8_t tag, // EMSdevice::DeviceValueTAG
const __FlashStringHelper * name, // fullname const __FlashStringHelper * const fullname, // fullname, already translated
const uint8_t device_type, // EMSdevice::DeviceType const uint8_t device_type, // EMSdevice::DeviceType
const __FlashStringHelper * entity, // shortname const __FlashStringHelper * const entity, // same as shortname
const uint8_t uom, // EMSdevice::DeviceValueUOM (0=NONE) const uint8_t uom, // EMSdevice::DeviceValueUOM (0=NONE)
const bool remove, // true if we want to remove this topic const bool remove, // true if we want to remove this topic
const bool has_cmd, const bool has_cmd,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
uint8_t options_size, uint8_t options_size,
const int16_t dv_set_min, const int16_t dv_set_min,
const int16_t dv_set_max, const int16_t dv_set_max,
const JsonObject & dev_json) { const JsonObject & dev_json) {
// ignore if name (fullname) is empty // ignore if name (fullname) is empty
if (name == nullptr) { if (fullname == nullptr) {
return; return;
} }
@@ -977,7 +985,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
char device_name[50]; char device_name[50];
strlcpy(device_name, EMSdevice::device_type_2_device_name(device_type).c_str(), sizeof(device_name)); strlcpy(device_name, EMSdevice::device_type_2_device_name(device_type).c_str(), sizeof(device_name));
// create entity by add the hc/wwc tag if present, seperating with a . // create entity by add the hc/wwc tag if present, separating with a .
char new_entity[50]; char new_entity[50];
if (tag >= DeviceValueTAG::TAG_HC1) { if (tag >= DeviceValueTAG::TAG_HC1) {
snprintf(new_entity, sizeof(new_entity), "%s.%s", EMSdevice::tag_to_string(tag).c_str(), read_flash_string(entity).c_str()); snprintf(new_entity, sizeof(new_entity), "%s.%s", EMSdevice::tag_to_string(tag).c_str(), read_flash_string(entity).c_str());
@@ -1007,28 +1015,28 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
// number - https://www.home-assistant.io/integrations/number.mqtt // number - https://www.home-assistant.io/integrations/number.mqtt
// https://developers.home-assistant.io/docs/core/entity/number // https://developers.home-assistant.io/docs/core/entity/number
snprintf(topic, sizeof(topic), "number/%s/%s/config", mqtt_base_.c_str(), uniq); snprintf(topic, sizeof(topic), "number/%s/%s/config", system_hostname_.c_str(), uniq);
break; break;
case DeviceValueType::BOOL: case DeviceValueType::BOOL:
// switch - https://www.home-assistant.io/integrations/switch.mqtt // switch - https://www.home-assistant.io/integrations/switch.mqtt
snprintf(topic, sizeof(topic), "switch/%s/%s/config", mqtt_base_.c_str(), uniq); snprintf(topic, sizeof(topic), "switch/%s/%s/config", system_hostname_.c_str(), uniq);
break; break;
case DeviceValueType::ENUM: case DeviceValueType::ENUM:
// select - https://www.home-assistant.io/integrations/select.mqtt // select - https://www.home-assistant.io/integrations/select.mqtt
snprintf(topic, sizeof(topic), "select/%s/%s/config", mqtt_base_.c_str(), uniq); snprintf(topic, sizeof(topic), "select/%s/%s/config", system_hostname_.c_str(), uniq);
break; break;
default: default:
// plain old sensor // plain old sensor
snprintf(topic, sizeof(topic), "sensor/%s/%s/config", mqtt_base_.c_str(), uniq); snprintf(topic, sizeof(topic), "sensor/%s/%s/config", system_hostname_.c_str(), uniq);
break; break;
} }
} else { } else {
// plain old read only device entity // plain old read only device entity
if (type == DeviceValueType::BOOL) { if (type == DeviceValueType::BOOL) {
snprintf(topic, sizeof(topic), "binary_sensor/%s/%s/config", mqtt_base_.c_str(), uniq); // binary sensor snprintf(topic, sizeof(topic), "binary_sensor/%s/%s/config", system_hostname_.c_str(), uniq); // binary sensor
} else { } else {
use_ha_sensor = true; use_ha_sensor = true;
snprintf(topic, sizeof(topic), "sensor/%s/%s/config", mqtt_base_.c_str(), uniq); // normal HA sensor, not a boolean one snprintf(topic, sizeof(topic), "sensor/%s/%s/config", system_hostname_.c_str(), uniq); // normal HA sensor, not a boolean one
} }
} }
@@ -1065,7 +1073,7 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
if (type == DeviceValueType::ENUM) { if (type == DeviceValueType::ENUM) {
JsonArray option_list = doc.createNestedArray("options"); JsonArray option_list = doc.createNestedArray("options");
for (uint8_t i = 0; i < options_size; i++) { for (uint8_t i = 0; i < options_size; i++) {
option_list.add(options[i]); option_list.add(Helpers::translated_word(options[i]));
} }
} else if (type != DeviceValueType::STRING) { } else if (type != DeviceValueType::STRING) {
// Must be Numeric.... // Must be Numeric....
@@ -1104,22 +1112,21 @@ void Mqtt::publish_ha_sensor_config(uint8_t type,
doc["stat_t"] = stat_t; doc["stat_t"] = stat_t;
// friendly name = <tag> <name> // friendly name = <tag> <name>
char short_name[70]; char ha_name[70];
if (have_tag) { if (have_tag) {
snprintf(short_name, sizeof(short_name), "%s %s", EMSdevice::tag_to_string(tag).c_str(), read_flash_string(name).c_str()); snprintf(ha_name, sizeof(ha_name), "%s %s", EMSdevice::tag_to_string(tag).c_str(), read_flash_string(fullname).c_str());
} else { } else {
snprintf(short_name, sizeof(short_name), "%s", read_flash_string(name).c_str()); snprintf(ha_name, sizeof(ha_name), "%s", read_flash_string(fullname).c_str());
} }
ha_name[0] = toupper(ha_name[0]); // capitalize first letter
doc["name"] = ha_name;
// entity id = emsesp_<device>_<tag>_<name> // entity id is generated from the name, see https://www.home-assistant.io/docs/mqtt/discovery/#use-object_id-to-influence-the-entity-id
char long_name[130]; // so we override it to make it unique using entity_id
snprintf(long_name, sizeof(long_name), "%s_%s", device_name, short_name); // emsesp_<device>_<tag>_<name>
// snprintf(long_name, sizeof(long_name), "emsesp_%s_%s", device_name, short_name); //wouldn't it be better? char object_id[130];
doc["object_id"] = long_name; snprintf(object_id, sizeof(object_id), "emsesp_%s_%s", device_name, ha_name);
doc["object_id"] = object_id;
// name (friendly name) = <tag> <name>
short_name[0] = toupper(short_name[0]); // capitalize first letter
doc["name"] = short_name;
// value template // value template
// if its nested mqtt format then use the appended entity name, otherwise take the original // if its nested mqtt format then use the appended entity name, otherwise take the original

View File

@@ -94,13 +94,13 @@ class Mqtt {
publish_ha_sensor_config(DeviceValue & dv, const std::string & model, const std::string & brand, const bool remove, const bool create_device_config = false); publish_ha_sensor_config(DeviceValue & dv, const std::string & model, const std::string & brand, const bool remove, const bool create_device_config = false);
static void publish_ha_sensor_config(uint8_t type, static void publish_ha_sensor_config(uint8_t type,
uint8_t tag, uint8_t tag,
const __FlashStringHelper * name, const __FlashStringHelper * const fullname,
const uint8_t device_type, const uint8_t device_type,
const __FlashStringHelper * entity, const __FlashStringHelper * const entity,
const uint8_t uom, const uint8_t uom,
const bool remove, const bool remove,
const bool has_cmd, const bool has_cmd,
const __FlashStringHelper * const * options, const __FlashStringHelper * const ** options,
uint8_t options_size, uint8_t options_size,
const int16_t dv_set_min, const int16_t dv_set_min,
const int16_t dv_set_max, const int16_t dv_set_max,
@@ -286,6 +286,8 @@ class Mqtt {
static bool ha_climate_reset_; static bool ha_climate_reset_;
// settings, copied over // settings, copied over
static std::string system_hostname_;
static std::string mqtt_base_; static std::string mqtt_base_;
static uint8_t mqtt_qos_; static uint8_t mqtt_qos_;
static bool mqtt_retain_; static bool mqtt_retain_;

View File

@@ -41,6 +41,11 @@
namespace emsesp { namespace emsesp {
// Languages supported. Note: the order is important and must match locale_translations.h
const char * const languages[] = {EMSESP_LOCALE_EN, EMSESP_LOCALE_DE};
size_t num_languages = sizeof(languages) / sizeof(const char *);
uuid::log::Logger System::logger_{F_(system), uuid::log::Facility::KERN}; uuid::log::Logger System::logger_{F_(system), uuid::log::Facility::KERN};
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
@@ -51,6 +56,17 @@ uuid::syslog::SyslogService System::syslog_;
PButton System::myPButton_; PButton System::myPButton_;
bool System::restart_requested_ = false; bool System::restart_requested_ = false;
// find the index of the language
// 0 = EN, 1 = DE, etc...
uint8_t System::language_index() {
for (uint8_t i = 0; i < num_languages; i++) {
if (languages[i] == locale()) {
return i;
}
}
return 0; // EN
}
// send on/off to a gpio pin // send on/off to a gpio pin
// value: true = HIGH, false = LOW // value: true = HIGH, false = LOW
bool System::command_pin(const char * value, const int8_t id) { bool System::command_pin(const char * value, const int8_t id) {
@@ -161,7 +177,7 @@ bool System::command_publish(const char * value, const int8_t id) {
// syslog level // syslog level
bool System::command_syslog_level(const char * value, const int8_t id) { bool System::command_syslog_level(const char * value, const int8_t id) {
uint8_t s = 0xff; uint8_t s = 0xff;
if (Helpers::value2enum(value, s, FL_(enum_syslog_level))) { if (Helpers::value2enum(value, s, FL_(list_syslog_level))) {
bool changed = false; bool changed = false;
EMSESP::webSettingsService.update( EMSESP::webSettingsService.update(
[&](WebSettings & settings) { [&](WebSettings & settings) {
@@ -184,17 +200,17 @@ bool System::command_syslog_level(const char * value, const int8_t id) {
bool System::command_watch(const char * value, const int8_t id) { bool System::command_watch(const char * value, const int8_t id) {
uint8_t w = 0xff; uint8_t w = 0xff;
uint16_t i = Helpers::hextoint(value); uint16_t i = Helpers::hextoint(value);
if (Helpers::value2enum(value, w, FL_(enum_watch))) { if (Helpers::value2enum(value, w, FL_(list_watch))) {
if (w == 0 || EMSESP::watch() == EMSESP::Watch::WATCH_OFF) { if (w == 0 || EMSESP::watch() == EMSESP::Watch::WATCH_OFF) {
EMSESP::watch_id(0); EMSESP::watch_id(0);
} }
if (Mqtt::publish_single() && w != EMSESP::watch()) { if (Mqtt::publish_single() && w != EMSESP::watch()) {
if (Mqtt::publish_single2cmd()) { if (Mqtt::publish_single2cmd()) {
Mqtt::publish(F("system/watch"), Mqtt::publish(F("system/watch"),
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : read_flash_string(FL_(enum_watch)[w]).c_str()); EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : read_flash_string(FL_(list_watch)[w]).c_str());
} else { } else {
Mqtt::publish(F("system_data/watch"), Mqtt::publish(F("system_data/watch"),
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : read_flash_string(FL_(enum_watch)[w]).c_str()); EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(w) : read_flash_string(FL_(list_watch)[w]).c_str());
} }
} }
EMSESP::watch(w); EMSESP::watch(w);
@@ -288,21 +304,21 @@ void System::syslog_init() {
if (Mqtt::publish_single()) { if (Mqtt::publish_single()) {
if (Mqtt::publish_single2cmd()) { if (Mqtt::publish_single2cmd()) {
Mqtt::publish(F("system/syslog"), syslog_enabled_ ? read_flash_string(FL_(enum_syslog_level)[syslog_level_ + 1]).c_str() : "off"); Mqtt::publish(F("system/syslog"), syslog_enabled_ ? read_flash_string(FL_(list_syslog_level)[syslog_level_ + 1]).c_str() : "off");
if (EMSESP::watch_id() == 0 || EMSESP::watch() == 0) { if (EMSESP::watch_id() == 0 || EMSESP::watch() == 0) {
Mqtt::publish(F("system/watch"), Mqtt::publish(F("system/watch"),
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch()) EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch())
: read_flash_string(FL_(enum_watch)[EMSESP::watch()]).c_str()); : read_flash_string(FL_(list_watch)[EMSESP::watch()]).c_str());
} else { } else {
Mqtt::publish(F("system/watch"), Helpers::hextoa(EMSESP::watch_id())); Mqtt::publish(F("system/watch"), Helpers::hextoa(EMSESP::watch_id()));
} }
} else { } else {
Mqtt::publish(F("system_data/syslog"), syslog_enabled_ ? read_flash_string(FL_(enum_syslog_level)[syslog_level_ + 1]).c_str() : "off"); Mqtt::publish(F("system_data/syslog"), syslog_enabled_ ? read_flash_string(FL_(list_syslog_level)[syslog_level_ + 1]).c_str() : "off");
if (EMSESP::watch_id() == 0 || EMSESP::watch() == 0) { if (EMSESP::watch_id() == 0 || EMSESP::watch() == 0) {
Mqtt::publish(F("system_data/watch"), Mqtt::publish(F("system_data/watch"),
EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch()) EMSESP::system_.enum_format() == ENUM_FORMAT_INDEX ? Helpers::itoa(EMSESP::watch())
: read_flash_string(FL_(enum_watch)[EMSESP::watch()]).c_str()); : read_flash_string(FL_(list_watch)[EMSESP::watch()]).c_str());
} else { } else {
Mqtt::publish(F("system_data/watch"), Helpers::hextoa(EMSESP::watch_id())); Mqtt::publish(F("system_data/watch"), Helpers::hextoa(EMSESP::watch_id()));
} }
@@ -342,6 +358,8 @@ void System::reload_settings() {
eth_power_ = settings.eth_power; eth_power_ = settings.eth_power;
eth_phy_addr_ = settings.eth_phy_addr; eth_phy_addr_ = settings.eth_phy_addr;
eth_clock_mode_ = settings.eth_clock_mode; eth_clock_mode_ = settings.eth_clock_mode;
locale_ = settings.locale;
}); });
} }
@@ -412,6 +430,12 @@ void System::start() {
// button single click // button single click
void System::button_OnClick(PButton & b) { void System::button_OnClick(PButton & b) {
LOG_DEBUG(F("Button pressed - single click")); LOG_DEBUG(F("Button pressed - single click"));
#ifdef EMSESP_DEBUG
#ifndef EMSESP_STANDALONE
Test::listDir(LittleFS, FS_CONFIG_DIRECTORY, 3);
#endif
#endif
} }
// button double click // button double click
@@ -431,11 +455,6 @@ void System::button_OnVLongPress(PButton & b) {
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
LOG_WARNING(F("Performing factory reset...")); LOG_WARNING(F("Performing factory reset..."));
EMSESP::console_.loop(); EMSESP::console_.loop();
#ifdef EMSESP_DEBUG
Test::listDir(LittleFS, FS_CONFIG_DIRECTORY, 3);
#endif
EMSESP::esp8266React.factoryReset(); EMSESP::esp8266React.factoryReset();
#endif #endif
} }
@@ -803,6 +822,7 @@ void System::show_system(uuid::console::Shell & shell) {
shell.printfln(F(" SDK version: %s"), ESP.getSdkVersion()); shell.printfln(F(" SDK version: %s"), ESP.getSdkVersion());
shell.printfln(F(" CPU frequency: %lu MHz"), ESP.getCpuFreqMHz()); shell.printfln(F(" CPU frequency: %lu MHz"), ESP.getCpuFreqMHz());
shell.printfln(F(" Free heap: %lu bytes"), (uint32_t)ESP.getFreeHeap()); shell.printfln(F(" Free heap: %lu bytes"), (uint32_t)ESP.getFreeHeap());
shell.printfln(F(" FS used/total: %lu/%lu (bytes)"), LittleFS.usedBytes(), LittleFS.totalBytes());
shell.println(); shell.println();
shell.println("Network:"); shell.println("Network:");
@@ -1089,7 +1109,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
if (EMSESP::system_.syslog_enabled_) { if (EMSESP::system_.syslog_enabled_) {
node["syslog started"] = syslog_.started(); node["syslog started"] = syslog_.started();
node["syslog level"] = FL_(enum_syslog_level)[syslog_.log_level() + 1]; node["syslog level"] = FL_(list_syslog_level)[syslog_.log_level() + 1];
node["syslog ip"] = syslog_.ip(); node["syslog ip"] = syslog_.ip();
node["syslog queue"] = syslog_.queued(); node["syslog queue"] = syslog_.queued();
} }
@@ -1145,6 +1165,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp
node = output.createNestedObject("Settings"); node = output.createNestedObject("Settings");
EMSESP::webSettingsService.read([&](WebSettings & settings) { EMSESP::webSettingsService.read([&](WebSettings & settings) {
node["board profile"] = settings.board_profile; node["board profile"] = settings.board_profile;
node["locale"] = settings.locale;
node["tx mode"] = settings.tx_mode; node["tx mode"] = settings.tx_mode;
node["ems bus id"] = settings.ems_bus_id; node["ems bus id"] = settings.ems_bus_id;
node["shower timer"] = settings.shower_timer; node["shower timer"] = settings.shower_timer;

View File

@@ -203,6 +203,16 @@ class System {
return fahrenheit_; return fahrenheit_;
} }
uint8_t language_index();
void locale(String locale) {
locale_ = locale;
}
std::string locale() {
return std::string(locale_.c_str());
}
void healthcheck(uint8_t healthcheck) { void healthcheck(uint8_t healthcheck) {
healthcheck_ = healthcheck; healthcheck_ = healthcheck;
} }
@@ -257,6 +267,7 @@ class System {
// EMS-ESP settings // EMS-ESP settings
// copies from WebSettings class in WebSettingsService.h and loaded with reload_settings() // copies from WebSettings class in WebSettingsService.h and loaded with reload_settings()
std::string hostname_ = FACTORY_WIFI_HOSTNAME; std::string hostname_ = FACTORY_WIFI_HOSTNAME;
String locale_;
bool hide_led_; bool hide_led_;
uint8_t led_gpio_; uint8_t led_gpio_;
bool analog_enabled_; bool analog_enabled_;

View File

@@ -596,10 +596,12 @@ void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const ui
} else { } else {
increment_telegram_write_fail_count(); // another Tx fail increment_telegram_write_fail_count(); // another Tx fail
} }
LOG_ERROR(F("Last Tx %s operation failed after %d retries. Ignoring request: %s"), LOG_ERROR(F("Last Tx %s operation failed after %d retries. Ignoring request: %s"),
(operation == Telegram::Operation::TX_WRITE) ? F("Write") : F("Read"), (operation == Telegram::Operation::TX_WRITE) ? F("Write") : F("Read"),
MAXIMUM_TX_RETRIES, MAXIMUM_TX_RETRIES,
telegram_last_->to_string().c_str()); telegram_last_->to_string().c_str());
if (operation == Telegram::Operation::TX_READ) { if (operation == Telegram::Operation::TX_READ) {
EMSESP::rxservice_.add_empty(telegram_last_->dest, telegram_last_->src, telegram_last_->type_id, telegram_last_->offset); EMSESP::rxservice_.add_empty(telegram_last_->dest, telegram_last_->src, telegram_last_->type_id, telegram_last_->offset);
} }

View File

@@ -305,12 +305,12 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
uint16_t temp; uint16_t temp;
float doub; float doub;
temp = 0x0201; // decimal 513 temp = 0x0201; // decimal 513
doub = Helpers::round2(temp, 10); // divide by 10 doub = Helpers::transformNumFloat(temp, 10); // divide by 10
shell.printfln("Round test from x%02X to %d to %f", temp, temp, doub); shell.printfln("Round test from x%02X to %d to %f", temp, temp, doub);
doub = Helpers::round2(temp, 10); // divide by 10 doub = Helpers::transformNumFloat(temp, 10); // divide by 10
shell.printfln("Round test div10 from x%02X to %d to %f", temp, temp, doub); shell.printfln("Round test div10 from x%02X to %d to %f", temp, temp, doub);
temp = 0x63; temp = 0x63;
doub = Helpers::round2(temp, 2); // divide by 2 doub = Helpers::transformNumFloat(temp, 2); // divide by 2
shell.printfln("Round test div2 from x%02X to %d to %f", temp, temp, doub); shell.printfln("Round test div2 from x%02X to %d to %f", temp, temp, doub);
} }
@@ -448,7 +448,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
if (command == "boiler") { if (command == "boiler") {
shell.printfln(F("Testing boiler...")); shell.printfln(F("Testing boiler..."));
Mqtt::ha_enabled(false); // Mqtt::ha_enabled(false);
Mqtt::ha_enabled(true);
Mqtt::nested_format(1); Mqtt::nested_format(1);
run_test("boiler"); run_test("boiler");

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.4.2b5" #define EMSESP_APP_VERSION "3.5.0b0"

View File

@@ -149,7 +149,7 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
obj["t"] = sensor.type(); obj["t"] = sensor.type();
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) { if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) {
obj["v"] = Helpers::round2(sensor.value(), 0); // is optional and is a float obj["v"] = Helpers::transformNumFloat(sensor.value(), 0); // is optional and is a float
} else { } else {
obj["v"] = 0; // must have a value for web sorting to work obj["v"] = 0; // must have a value for web sorting to work
} }

View File

@@ -37,6 +37,7 @@ WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, Securit
} }
void WebSettings::read(WebSettings & settings, JsonObject & root) { void WebSettings::read(WebSettings & settings, JsonObject & root) {
root["locale"] = settings.locale;
root["tx_mode"] = settings.tx_mode; root["tx_mode"] = settings.tx_mode;
root["ems_bus_id"] = settings.ems_bus_id; root["ems_bus_id"] = settings.ems_bus_id;
root["syslog_enabled"] = settings.syslog_enabled; root["syslog_enabled"] = settings.syslog_enabled;
@@ -107,10 +108,10 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
check_flag(prev, settings.tx_mode, ChangeFlags::UART); check_flag(prev, settings.tx_mode, ChangeFlags::UART);
prev = settings.rx_gpio; prev = settings.rx_gpio;
settings.rx_gpio = root["rx_gpio"] | default_rx_gpio; settings.rx_gpio = root["rx_gpio"] | default_rx_gpio;
check_flag(prev, settings.rx_gpio, ChangeFlags::RESTART); check_flag(prev, settings.rx_gpio, ChangeFlags::UART); // no need to restart
prev = settings.tx_gpio; prev = settings.tx_gpio;
settings.tx_gpio = root["tx_gpio"] | default_tx_gpio; settings.tx_gpio = root["tx_gpio"] | default_tx_gpio;
check_flag(prev, settings.tx_gpio, ChangeFlags::RESTART); check_flag(prev, settings.tx_gpio, ChangeFlags::UART); // no need to restart
// syslog // syslog
prev = settings.syslog_enabled; prev = settings.syslog_enabled;
@@ -203,8 +204,17 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
settings.low_clock = root["low_clock"] | false; settings.low_clock = root["low_clock"] | false;
check_flag(prev, settings.low_clock, ChangeFlags::RESTART); check_flag(prev, settings.low_clock, ChangeFlags::RESTART);
String old_local = settings.locale;
settings.locale = root["locale"] | EMSESP_DEFAULT_LOCALE;
EMSESP::system_.locale(settings.locale);
#ifndef EMSESP_STANDALONE
if (!old_local.equals(settings.locale)) {
add_flags(ChangeFlags::MQTT);
}
#endif
// //
// without checks... // without checks or necessary restarts...
// //
settings.trace_raw = root["trace_raw"] | EMSESP_DEFAULT_TRACELOG_RAW; settings.trace_raw = root["trace_raw"] | EMSESP_DEFAULT_TRACELOG_RAW;
EMSESP::trace_raw(settings.trace_raw); EMSESP::trace_raw(settings.trace_raw);
@@ -269,6 +279,10 @@ void WebSettingsService::onUpdate() {
EMSESP::system_.led_init(true); // reload settings EMSESP::system_.led_init(true); // reload settings
} }
if (WebSettings::has_flags(WebSettings::ChangeFlags::MQTT)) {
emsesp::EMSESP::mqtt_.reset_mqtt(); // reload MQTT, init HA etc
}
WebSettings::reset_flags(); WebSettings::reset_flags();
} }

View File

@@ -29,6 +29,7 @@ namespace emsesp {
class WebSettings { class WebSettings {
public: public:
String locale;
uint8_t tx_mode; uint8_t tx_mode;
uint8_t ems_bus_id; uint8_t ems_bus_id;
bool shower_timer; bool shower_timer;
@@ -81,6 +82,7 @@ class WebSettings {
SHOWER = (1 << 4), // 16 SHOWER = (1 << 4), // 16
LED = (1 << 5), // 32 LED = (1 << 5), // 32
BUTTON = (1 << 6), // 64 BUTTON = (1 << 6), // 64
MQTT = (1 << 7), // 128
RESTART = 0xFF RESTART = 0xFF
}; };