Merge pull request #1302 from MichaelDvP/dev2

network connection and powerentities
This commit is contained in:
Proddy
2023-09-20 20:08:22 +02:00
committed by GitHub
47 changed files with 661 additions and 354 deletions

View File

@@ -1,11 +1,20 @@
# Changelog
## [3.6.1]
## [3.6.2]
## **IMPORTANT! BREAKING CHANGES**
## Added
- power entities
- optional input of BSSID for AP connection
- return empty json if no entries in scheduler/custom/analogsnesor/temperaturesensor
## Fixed
- wifi full scan to get strongest AP
- add missing dhw tags
## Changed
- mqtt queue max 300 messages, check heap and maxAlloc

View File

@@ -28,7 +28,7 @@
"@prefresh/vite": "^2.4.1",
"@table-library/react-table-library": "4.1.7",
"@types/lodash-es": "^4.17.9",
"@types/node": "^20.6.2",
"@types/node": "^20.6.3",
"@types/react": "^18.2.22",
"@types/react-dom": "^18.2.7",
"@types/react-router-dom": "^5.3.3",
@@ -69,9 +69,9 @@
"npm-run-all": "^4.1.5",
"prettier": "^3.0.3",
"rollup-plugin-visualizer": "^5.9.2",
"terser": "^5.19.4",
"terser": "^5.20.0",
"vite": "^4.4.9",
"vite-plugin-svgr": "^3.2.0",
"vite-plugin-svgr": "^4.0.0",
"vite-tsconfig-paths": "^4.2.1"
},
"packageManager": "yarn@3.4.1"

View File

@@ -15,15 +15,15 @@ import { PROJECT_NAME } from 'api/env';
import { ValidatedPasswordField, ValidatedTextField } from 'components';
import { AuthenticationContext } from 'contexts/authentication';
import { ReactComponent as DEflag } from 'i18n/DE.svg';
import { ReactComponent as FRflag } from 'i18n/FR.svg';
import { ReactComponent as GBflag } from 'i18n/GB.svg';
import { ReactComponent as ITflag } from 'i18n/IT.svg';
import { ReactComponent as NLflag } from 'i18n/NL.svg';
import { ReactComponent as NOflag } from 'i18n/NO.svg';
import { ReactComponent as PLflag } from 'i18n/PL.svg';
import { ReactComponent as SVflag } from 'i18n/SV.svg';
import { ReactComponent as TRflag } from 'i18n/TR.svg';
import DEflag from 'i18n/DE.svg';
import FRflag from 'i18n/FR.svg';
import GBflag from 'i18n/GB.svg';
import ITflag from 'i18n/IT.svg';
import NLflag from 'i18n/NL.svg';
import NOflag from 'i18n/NO.svg';
import PLflag from 'i18n/PL.svg';
import SVflag from 'i18n/SV.svg';
import TRflag from 'i18n/TR.svg';
import { I18nContext } from 'i18n/i18n-react';
import { loadLocaleAsync } from 'i18n/i18n-util.async';
import { onEnterCallback, updateValue } from 'utils';
@@ -115,39 +115,39 @@ const SignIn: FC = () => {
<TextField name="locale" variant="outlined" value={locale} onChange={onLocaleSelected} size="small" select>
<MenuItem key="de" value="de">
<DEflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={DEflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;DE
</MenuItem>
<MenuItem key="en" value="en">
<GBflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={GBflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;EN
</MenuItem>
<MenuItem key="fr" value="fr">
<FRflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={FRflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;FR
</MenuItem>
<MenuItem key="it" value="it">
<ITflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={ITflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;IT
</MenuItem>
<MenuItem key="nl" value="nl">
<NLflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={NLflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;NL
</MenuItem>
<MenuItem key="no" value="no">
<NOflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={NOflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;NO
</MenuItem>
<MenuItem key="pl" value="pl">
<PLflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={PLflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;PL
</MenuItem>
<MenuItem key="sv" value="sv">
<SVflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={SVflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;SV
</MenuItem>
<MenuItem key="tr" value="tr">
<TRflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={TRflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;TR
</MenuItem>
</TextField>

View File

@@ -19,15 +19,15 @@ import type { Locales } from 'i18n/i18n-types';
import type { FC, ChangeEventHandler } from 'react';
import { AuthenticatedContext } from 'contexts/authentication';
import { ReactComponent as DEflag } from 'i18n/DE.svg';
import { ReactComponent as FRflag } from 'i18n/FR.svg';
import { ReactComponent as GBflag } from 'i18n/GB.svg';
import { ReactComponent as ITflag } from 'i18n/IT.svg';
import { ReactComponent as NLflag } from 'i18n/NL.svg';
import { ReactComponent as NOflag } from 'i18n/NO.svg';
import { ReactComponent as PLflag } from 'i18n/PL.svg';
import { ReactComponent as SVflag } from 'i18n/SV.svg';
import { ReactComponent as TRflag } from 'i18n/TR.svg';
import DEflag from 'i18n/DE.svg';
import FRflag from 'i18n/FR.svg';
import GBflag from 'i18n/GB.svg';
import ITflag from 'i18n/IT.svg';
import NLflag from 'i18n/NL.svg';
import NOflag from 'i18n/NO.svg';
import PLflag from 'i18n/PL.svg';
import SVflag from 'i18n/SV.svg';
import TRflag from 'i18n/TR.svg';
import { I18nContext } from 'i18n/i18n-react';
import { loadLocaleAsync } from 'i18n/i18n-util.async';
@@ -75,39 +75,39 @@ const LayoutAuthMenu: FC = () => {
select
>
<MenuItem key="de" value="de">
<DEflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={DEflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;DE
</MenuItem>
<MenuItem key="en" value="en">
<GBflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={GBflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;EN
</MenuItem>
<MenuItem key="fr" value="fr">
<FRflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={FRflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;FR
</MenuItem>
<MenuItem key="it" value="it">
<ITflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={ITflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;IT
</MenuItem>
<MenuItem key="nl" value="nl">
<NLflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={NLflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;NL
</MenuItem>
<MenuItem key="no" value="no">
<NOflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={NOflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;NO
</MenuItem>
<MenuItem key="pl" value="pl">
<PLflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={PLflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;PL
</MenuItem>
<MenuItem key="sv" value="sv">
<SVflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={SVflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;SV
</MenuItem>
<MenuItem key="tr" value="tr">
<TRflag style={{ width: 16, verticalAlign: 'middle' }} />
<img src={TRflag} style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;TR
</MenuItem>
</TextField>

View File

@@ -82,7 +82,8 @@ const WiFiSettingsForm: FC = () => {
if (selectedNetwork) {
updateState('networkSettings', (current_data) => ({
ssid: selectedNetwork.ssid,
password: '',
bssid: selectedNetwork.bssid,
password: current_data ? current_data.password : '',
hostname: current_data?.hostname,
static_ip_config: false,
enableIPv6: false,
@@ -117,6 +118,12 @@ const WiFiSettingsForm: FC = () => {
} catch (errors: any) {
setFieldErrors(errors);
}
deselectNetwork();
};
const setCancel = async () => {
deselectNetwork();
await loadData();
};
const restart = async () => {
@@ -139,10 +146,17 @@ const WiFiSettingsForm: FC = () => {
</ListItemAvatar>
<ListItemText
primary={selectedNetwork.ssid}
secondary={'Security: ' + networkSecurityMode(selectedNetwork) + ', Ch: ' + selectedNetwork.channel}
secondary={
'Security: ' +
networkSecurityMode(selectedNetwork) +
', Ch: ' +
selectedNetwork.channel +
', bssid: ' +
selectedNetwork.bssid
}
/>
<ListItemSecondaryAction>
<IconButton onClick={deselectNetwork}>
<IconButton onClick={setCancel}>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
@@ -160,6 +174,16 @@ const WiFiSettingsForm: FC = () => {
margin="normal"
/>
)}
<ValidatedTextField
fieldErrors={fieldErrors}
name="bssid"
label={'BSSID (' + LL.NETWORK_BLANK_BSSID() + ')'}
fullWidth
variant="outlined"
value={data.bssid}
onChange={updateFormValue}
margin="normal"
/>
{(!selectedNetwork || !isNetworkOpen(selectedNetwork)) && (
<ValidatedPasswordField
fieldErrors={fieldErrors}
@@ -296,7 +320,7 @@ const WiFiSettingsForm: FC = () => {
</MessageBox>
)}
{!restartNeeded && dirtyFlags && dirtyFlags.length !== 0 && (
{!restartNeeded && (selectedNetwork || (dirtyFlags && dirtyFlags.length !== 0)) && (
<ButtonRow>
<Button
startIcon={<CancelIcon />}

View File

@@ -65,7 +65,9 @@ const WiFiNetworkSelector: FC<WiFiNetworkSelectorProps> = ({ networkList }) => {
</ListItemAvatar>
<ListItemText
primary={network.ssid}
secondary={'Security: ' + networkSecurityMode(network) + ', Ch: ' + network.channel}
secondary={
'Security: ' + networkSecurityMode(network) + ', Ch: ' + network.channel + ', bssid: ' + network.bssid
}
/>
<ListItemIcon>
<Badge badgeContent={network.rssi + 'dBm'}>

View File

@@ -282,6 +282,7 @@ const de: Translation = {
NETWORK_SCANNER: 'Netzwerk Suche',
NETWORK_NO_WIFI: 'Keine WiFi Netzwerke gefunden',
NETWORK_BLANK_SSID: 'Freilassen um WiFi zu deaktivieren und ETH zu aktivieren',
NETWORK_BLANK_BSSID: 'Freilassen um nur SSID für die Verbindung zu nutzen',
TX_POWER: 'Tx Leistung',
HOSTNAME: 'Hostname',
NETWORK_DISABLE_SLEEP: 'Deaktiviere WiFi Schlafmodus',

View File

@@ -282,6 +282,7 @@ const en: Translation = {
NETWORK_SCANNER: 'Network Scanner',
NETWORK_NO_WIFI: 'No WiFi networks found',
NETWORK_BLANK_SSID: 'leave blank to disable WiFi and enable ETH',
NETWORK_BLANK_BSSID: 'leave blank to use only SSID',
TX_POWER: 'Tx Power',
HOSTNAME: 'Hostname',
NETWORK_DISABLE_SLEEP: 'Disable WiFi Sleep Mode',

View File

@@ -282,6 +282,7 @@ const fr: Translation = {
NETWORK_SCANNER: 'Scan réseau',
NETWORK_NO_WIFI: 'Pas de réseau WiFi trouvé',
NETWORK_BLANK_SSID: 'laisser vide pour désactiver le WiFi', // and enable ETH // TODO translate
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
TX_POWER: 'Puissance Tx',
HOSTNAME: 'Nom d\'hôte',
NETWORK_DISABLE_SLEEP: 'Désactiver le mode veille du WiFi',

View File

@@ -284,6 +284,7 @@ const it: Translation = {
NETWORK_SCANNER: 'Scansione Rete',
NETWORK_NO_WIFI: 'Nessuana rete WiFi trovata',
NETWORK_BLANK_SSID: 'lasciare vuoto per disattivare WiFi',
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
TX_POWER: 'Potenza Tx',
HOSTNAME: 'Nome ospite',
NETWORK_DISABLE_SLEEP: 'Disabilita la modalità sospensione Wi-Fi',

View File

@@ -282,6 +282,7 @@ const nl: Translation = {
NETWORK_SCANNER: 'Netwerk Scanner',
NETWORK_NO_WIFI: 'Geen WiFi networken gevonden',
NETWORK_BLANK_SSID: 'laat leeg om WiFi uit te schakelen',
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
TX_POWER: 'Tx Vermogen',
HOSTNAME: 'Hostname',
NETWORK_DISABLE_SLEEP: 'WiFi Sleep Mode uitzetten',

View File

@@ -282,6 +282,7 @@ const no: Translation = {
NETWORK_SCANNER: 'Nettverk Scanner',
NETWORK_NO_WIFI: 'Ingen trådløse nett funnet',
NETWORK_BLANK_SSID: 'la feltet være blankt for å deaktivisere trådløst nettverk', // TODO translate
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
TX_POWER: 'Tx Effekt',
HOSTNAME: 'Hostname',
NETWORK_DISABLE_SLEEP: 'Hindre at trådløst nettverk går i Sleep Mode',

View File

@@ -282,6 +282,7 @@ const pl: BaseTranslation = {
NETWORK_SCANNER: 'Skaner sieci WiFi',
NETWORK_NO_WIFI: 'Brak sieci WiFi w zasięgu',
NETWORK_BLANK_SSID: 'pozostaw puste aby wyłączyć WiFi', // and enable ETH // TODO translate
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
TX_POWER: 'Moc nadawania',
HOSTNAME: 'Nazwa w sieci',
NETWORK_DISABLE_SLEEP: 'Wyłącz tryb uśpienia WiFi',

View File

@@ -282,6 +282,7 @@ const sv: Translation = {
NETWORK_SCANNER: 'Hittade nätverk',
NETWORK_NO_WIFI: 'Inga WiFi-nätverk hittades',
NETWORK_BLANK_SSID: 'lämna blankt för att inaktivera WiFi', // and enable ETH // TODO translate
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
TX_POWER: 'Tx Effekt',
HOSTNAME: 'Värdnamn',
NETWORK_DISABLE_SLEEP: 'Inaktivera sömnläge',

View File

@@ -282,6 +282,7 @@ const tr: Translation = {
NETWORK_SCANNER: 'Ağ Tarayıcısı',
NETWORK_NO_WIFI: 'Hiçbir Kablosuz Ağ bulunamadı',
NETWORK_BLANK_SSID: 'Kablosuz ağı devre dışı bırakmak için boş bırakın', // TODO translate
NETWORK_BLANK_BSSID: 'leave blank to use only SSID', // TODO translate
TX_POWER: 'Aktarım gücü',
HOSTNAME: 'Ana Makine Adı',
NETWORK_DISABLE_SLEEP: 'Kablosuz uyku modunu devre dışına al',

View File

@@ -37,6 +37,7 @@ export interface NetworkStatus {
export interface NetworkSettings {
ssid: string;
bssid: string;
password: string;
hostname: string;
static_ip_config: boolean;

View File

@@ -5,6 +5,7 @@ import type { NetworkSettings } from 'types';
export const createNetworkSettingsValidator = (networkSettings: NetworkSettings) =>
new Schema({
ssid: [{ type: 'string', max: 32, message: 'SSID must be 32 characters or less' }],
bssid: [{ type: 'string', max: 17, message: 'BSSID must be 17 characters or empty' }],
password: { type: 'string', max: 64, message: 'Password must be 64 characters or less' },
hostname: [{ required: true, message: 'Hostname is required' }, HOSTNAME_VALIDATOR],
...(networkSettings.static_ip_config && {

View File

@@ -893,22 +893,22 @@ __metadata:
languageName: node
linkType: hard
"@floating-ui/core@npm:^1.4.1":
version: 1.4.1
resolution: "@floating-ui/core@npm:1.4.1"
"@floating-ui/core@npm:^1.4.2":
version: 1.5.0
resolution: "@floating-ui/core@npm:1.5.0"
dependencies:
"@floating-ui/utils": ^0.1.1
checksum: 6a738ff3b5bcca2470904a2462a2700e32081f6e681e077fd63c8d0b389439511a2a16187589df156fac6e8f47d56bdc0afea64303b9341fb5886cff82d87758
"@floating-ui/utils": ^0.1.3
checksum: bca811cefd09c3f56c4cf58c3e94826c1ce4a0b40124e9030ddca2ef1cc68b4ddc5ba5b4d7cc94c9555aea6876d2428a77a2ae261fe5b39c79df247a9518b053
languageName: node
linkType: hard
"@floating-ui/dom@npm:^1.5.1":
version: 1.5.2
resolution: "@floating-ui/dom@npm:1.5.2"
version: 1.5.3
resolution: "@floating-ui/dom@npm:1.5.3"
dependencies:
"@floating-ui/core": ^1.4.1
"@floating-ui/utils": ^0.1.1
checksum: ce0e7dca2d36667ef4a72a2200bd7c49bf1b1bb94a5a09efc27e9d225175d92f41f00a037f1ef060f8fe78af242bc0889e4b12dd0be4dcd7a772f4a63804e693
"@floating-ui/core": ^1.4.2
"@floating-ui/utils": ^0.1.3
checksum: e5f30b911f939e40003851077bba441f269ae689bdc43c674bee43aa98fc6b7a5f59be432d27b7be599b1e4ab7b15c752875ea777a89cff01d157e593b78b25b
languageName: node
linkType: hard
@@ -924,10 +924,10 @@ __metadata:
languageName: node
linkType: hard
"@floating-ui/utils@npm:^0.1.1":
version: 0.1.1
resolution: "@floating-ui/utils@npm:0.1.1"
checksum: 3fca5a8bce10de87f78c9b9377db7d5a4c992f98adc3722e46725d9bd2a3a1051bb1c512caf5fe293752c660455df5f7b6a2153802f9299572fac3b565f4c407
"@floating-ui/utils@npm:^0.1.3":
version: 0.1.3
resolution: "@floating-ui/utils@npm:0.1.3"
checksum: 82df69ee3770d2c7c12124874215ac59d5e37680399fa948f2e355a800d18f305443754371083a7e546f879c7142e5e257e3595a5a852dbbfdcd3ec81d923fa3
languageName: node
linkType: hard
@@ -1344,9 +1344,9 @@ __metadata:
languageName: node
linkType: hard
"@rollup/pluginutils@npm:^5.0.2":
version: 5.0.3
resolution: "@rollup/pluginutils@npm:5.0.3"
"@rollup/pluginutils@npm:^5.0.4":
version: 5.0.4
resolution: "@rollup/pluginutils@npm:5.0.4"
dependencies:
"@types/estree": ^1.0.0
estree-walker: ^2.0.2
@@ -1356,131 +1356,134 @@ __metadata:
peerDependenciesMeta:
rollup:
optional: true
checksum: ceccecb6f9b0d53d2745b0e84c4618c669edd6fb66a769955aec38ff534fd811230bf6113545886c7dbaf657245a92714cc897206a2234e63c6f2bbe51c0d4f3
checksum: 4114d0dbc22623d33ee38885e90afada4d96fae92e9645693fe438f6313832377ffb6b2809d90e96cc269339a54e2c0c46a739f621d9041050b0b751020f726b
languageName: node
linkType: hard
"@svgr/babel-plugin-add-jsx-attribute@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:7.0.0"
"@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 66714c2961f21409b0d33f0f65cf52f2496838b4ed056e98c872faa9f60754fae491ca4397717991eaa9884a0a44ae8920fd550101c9877759bd73f361a49800
checksum: a50bd0baa34faf16bcba712091f94c7f0e230431fe99a9dfc3401fa92823ad3f68495b86ab9bf9044b53839e8c416cfbb37eb3f246ff33f261e0fa9ee1779c5b
languageName: node
linkType: hard
"@svgr/babel-plugin-remove-jsx-attribute@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:7.0.0"
"@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 8b2320919d918e83d8b5fc9d194a4354e3aac98801863defe4f732954bb48b665812a5e3813f2eaf8bdb0c8d78f0a2c9934675a2df5248b99d2eb7a33688d408
checksum: 8a98e59bd9971e066815b4129409932f7a4db4866834fe75677ea6d517972fb40b380a69a4413189f20e7947411f9ab1b0f029dd5e8068686a5a0188d3ccd4c7
languageName: node
linkType: hard
"@svgr/babel-plugin-remove-jsx-empty-expression@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:7.0.0"
"@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: c9d338206aade1bd280a4d45ec3f80f72b91e0a27502d38eeb68024e5fa21b0fcd20f72b6e591eb0e82cca9793012680888e66c2fd04bdcf17e79385f512e946
checksum: 517dcca75223bd05d3f056a8514dbba3031278bea4eadf0842c576d84f4651e7a4e0e7082d3ee4ef42456de0f9c4531d8a1917c04876ca64b014b859ca8f1bde
languageName: node
linkType: hard
"@svgr/babel-plugin-replace-jsx-attribute-value@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:7.0.0"
"@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 9a39807bd09fb00c121e2b6952e24b90b6d9cd2318105176b93ccc4e1ec5b87b9999b96bce6f9f5e7769033583565908b440951de89ac9c3cb82ea0e0a3db686
checksum: 004bd1892053b7e9c1b0bb14acc44e77634ec393722b87b1e4fae53e2c35122a2dd0d5c15e9070dbeec274e22e7693a2b8b48506733a8009ee92b12946fcb10a
languageName: node
linkType: hard
"@svgr/babel-plugin-svg-dynamic-title@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:7.0.0"
"@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 49dd7907a63bd7643e6081d0bc4daee23e3fc095b6eafc58760f5d67314eee1ea60a6788ccbe68e2457f083ea31522c847119fe48eb6e2dc20956b9bb3316cbb
checksum: 80e0a7fcf902f984c705051ca5c82ea6050ccbb70b651a8fea6d0eb5809e4dac274b49ea6be2d87f1eb9dfc0e2d6cdfffe1669ec2117f44b67a60a07d4c0b8b8
languageName: node
linkType: hard
"@svgr/babel-plugin-svg-em-dimensions@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:7.0.0"
"@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 9d5b569b75a612074b03aab20837dd1858f97d002b05fc9a2ec939aebbc8053e893960e264a1f2261bf0c426e4f8fa93c72313bcf7dface89fc09bc643147ebd
checksum: 73e92c8277a89279745c0c500f59f083279a8dc30cd552b22981fade2a77628fb2bd2819ee505725fcd2e93f923e3790b52efcff409a159e657b46604a0b9a21
languageName: node
linkType: hard
"@svgr/babel-plugin-transform-react-native-svg@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:7.0.0"
"@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0":
version: 8.1.0
resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 9091bd61d787e8506965f10a946dec463881b337aa435eedb0d5423ece1d0589fa643c2e01003cbb3447d3dbdf5d937ff7bae487a3098abbbe94ac04c84022d8
checksum: 655ed6bc7a208ceaa4ecff0a54ccc36008c3cb31efa90d11e171cab325ebbb21aa78f09c7b65f9b3ddeda3a85f348c0c862902c48be13c14b4de165c847974e3
languageName: node
linkType: hard
"@svgr/babel-plugin-transform-svg-component@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-plugin-transform-svg-component@npm:7.0.0"
"@svgr/babel-plugin-transform-svg-component@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/babel-plugin-transform-svg-component@npm:8.0.0"
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 715c371bdae660fa9452083f2be6c1736d9ad516dc7134656c6e70374799de94eacda596504394aa6934aacb6da9099acd99569089220d66aaf91b34aa934c7b
checksum: 4ac00bb99a3db4ef05e4362f116a3c608ee365a2d26cf7318d8d41a4a5b30a02c80455cce0e62c65b60ed815b5d632bedabac2ccd4b56f998fadef5286e3ded4
languageName: node
linkType: hard
"@svgr/babel-preset@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/babel-preset@npm:7.0.0"
"@svgr/babel-preset@npm:8.1.0":
version: 8.1.0
resolution: "@svgr/babel-preset@npm:8.1.0"
dependencies:
"@svgr/babel-plugin-add-jsx-attribute": ^7.0.0
"@svgr/babel-plugin-remove-jsx-attribute": ^7.0.0
"@svgr/babel-plugin-remove-jsx-empty-expression": ^7.0.0
"@svgr/babel-plugin-replace-jsx-attribute-value": ^7.0.0
"@svgr/babel-plugin-svg-dynamic-title": ^7.0.0
"@svgr/babel-plugin-svg-em-dimensions": ^7.0.0
"@svgr/babel-plugin-transform-react-native-svg": ^7.0.0
"@svgr/babel-plugin-transform-svg-component": ^7.0.0
"@svgr/babel-plugin-add-jsx-attribute": 8.0.0
"@svgr/babel-plugin-remove-jsx-attribute": 8.0.0
"@svgr/babel-plugin-remove-jsx-empty-expression": 8.0.0
"@svgr/babel-plugin-replace-jsx-attribute-value": 8.0.0
"@svgr/babel-plugin-svg-dynamic-title": 8.0.0
"@svgr/babel-plugin-svg-em-dimensions": 8.0.0
"@svgr/babel-plugin-transform-react-native-svg": 8.1.0
"@svgr/babel-plugin-transform-svg-component": 8.0.0
peerDependencies:
"@babel/core": ^7.0.0-0
checksum: 7d0755e2f007d4108b9ccbd7ccb2de2787ed3aa54cf873426bb211666996fe7a4fde73710a76bbdc169e1e72d7eca1dec5a6b26f14ab3124ff154ecbe387b69a
checksum: 49367d3ad0831f79b1056871b91766246f449d4d1168623af5e283fbaefce4a01d77ab00de6b045b55e956f9aae27895823198493cd232d88d3435ea4517ffc5
languageName: node
linkType: hard
"@svgr/core@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/core@npm:7.0.0"
"@svgr/core@npm:^8.1.0":
version: 8.1.0
resolution: "@svgr/core@npm:8.1.0"
dependencies:
"@babel/core": ^7.21.3
"@svgr/babel-preset": ^7.0.0
"@svgr/babel-preset": 8.1.0
camelcase: ^6.2.0
cosmiconfig: ^8.1.3
checksum: 347617081188fc0ed5de53a8643b70949c8737a1b5baf6e4a2dd23ecb8311de111d4e76f8f005959ec66e7d53a5f8155249f6b947c8111042b978fc798f53c4c
snake-case: ^3.0.4
checksum: 6a2f6b1bc79bce39f66f088d468985d518005fc5147ebf4f108570a933818b5951c2cb7da230ddff4b7c8028b5a672b2d33aa2acce012b8b9770073aa5a2d041
languageName: node
linkType: hard
"@svgr/hast-util-to-babel-ast@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/hast-util-to-babel-ast@npm:7.0.0"
"@svgr/hast-util-to-babel-ast@npm:8.0.0":
version: 8.0.0
resolution: "@svgr/hast-util-to-babel-ast@npm:8.0.0"
dependencies:
"@babel/types": ^7.21.3
entities: ^4.4.0
checksum: 2d6880fac9445559cc2e29f87782a52c37d2db7b99a4892f65def1e79a8239d7961c483934ff9ce2d37cb087f5b34c80ca5a51f7bc9eaceacfe0bd66e4e64373
checksum: f4165b583ba9eaf6719e598977a7b3ed182f177983e55f9eb55a6a73982d81277510e9eb7ab41f255151fb9ed4edd11ac4bef95dd872f04ed64966d8c85e0f79
languageName: node
linkType: hard
"@svgr/plugin-jsx@npm:^7.0.0":
version: 7.0.0
resolution: "@svgr/plugin-jsx@npm:7.0.0"
"@svgr/plugin-jsx@npm:^8.1.0":
version: 8.1.0
resolution: "@svgr/plugin-jsx@npm:8.1.0"
dependencies:
"@babel/core": ^7.21.3
"@svgr/babel-preset": ^7.0.0
"@svgr/hast-util-to-babel-ast": ^7.0.0
"@svgr/babel-preset": 8.1.0
"@svgr/hast-util-to-babel-ast": 8.0.0
svg-parser: ^2.0.4
checksum: bd649a306b83bc355315265046461cfa089c81604785b081fe0ccffd0112dc8bfad1e19d8e042d85339792458ab2e9022f8bf29fdd64bfea90718a40553ce00e
peerDependencies:
"@svgr/core": "*"
checksum: 07b4d9e00de795540bf70556fa2cc258774d01e97a12a26234c6fdf42b309beb7c10f31ee24d1a71137239347b1547b8bb5587d3a6de10669f95dcfe99cddc56
languageName: node
linkType: hard
@@ -1591,10 +1594,10 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^20.6.2":
version: 20.6.2
resolution: "@types/node@npm:20.6.2"
checksum: e490a743f97779797e1cccb2cba9eb7b753c376a401e88fd3ba9b999e0e8f9851417f250639663e42e5d068f885b650972f8edbd9a3175c2f7b14e4ef206479c
"@types/node@npm:^20.6.3":
version: 20.6.3
resolution: "@types/node@npm:20.6.3"
checksum: d76d07e37cffebdd55a2836dde25d892d3144e030516fed7a70390fc51ab07bdd58fa674c19b50bcf0751af8e5e15ccd01a83804b88511ba821db42f2f3bd0bd
languageName: node
linkType: hard
@@ -1832,7 +1835,7 @@ __metadata:
"@table-library/react-table-library": 4.1.7
"@types/babel__core": ^7
"@types/lodash-es": ^4.17.9
"@types/node": ^20.6.2
"@types/node": ^20.6.3
"@types/react": ^18.2.22
"@types/react-dom": ^18.2.7
"@types/react-router-dom": ^5.3.3
@@ -1866,11 +1869,11 @@ __metadata:
react-toastify: ^9.1.3
rollup-plugin-visualizer: ^5.9.2
sockette: ^2.0.6
terser: ^5.19.4
terser: ^5.20.0
typesafe-i18n: ^5.26.2
typescript: ^5.2.2
vite: ^4.4.9
vite-plugin-svgr: ^3.2.0
vite-plugin-svgr: ^4.0.0
vite-tsconfig-paths: ^4.2.1
languageName: unknown
linkType: soft
@@ -2649,6 +2652,16 @@ __metadata:
languageName: node
linkType: hard
"dot-case@npm:^3.0.4":
version: 3.0.4
resolution: "dot-case@npm:3.0.4"
dependencies:
no-case: ^3.0.4
tslib: ^2.0.3
checksum: 5b859ea65097a7ea870e2c91b5768b72ddf7fa947223fd29e167bcdff58fe731d941c48e47a38ec8aa8e43044c8fbd15cd8fa21689a526bc34b6548197cd5b05
languageName: node
linkType: hard
"eastasianwidth@npm:^0.2.0":
version: 0.2.0
resolution: "eastasianwidth@npm:0.2.0"
@@ -4424,6 +4437,15 @@ __metadata:
languageName: node
linkType: hard
"lower-case@npm:^2.0.2":
version: 2.0.2
resolution: "lower-case@npm:2.0.2"
dependencies:
tslib: ^2.0.3
checksum: 3d925e090315cf7dc1caa358e0477e186ffa23947740e4314a7429b6e62d72742e0bbe7536a5ae56d19d7618ce998aba05caca53c2902bd5742fdca5fc57fd7b
languageName: node
linkType: hard
"lru-cache@npm:^5.1.1":
version: 5.1.1
resolution: "lru-cache@npm:5.1.1"
@@ -4709,6 +4731,16 @@ __metadata:
languageName: node
linkType: hard
"no-case@npm:^3.0.4":
version: 3.0.4
resolution: "no-case@npm:3.0.4"
dependencies:
lower-case: ^2.0.2
tslib: ^2.0.3
checksum: 8ef545f0b3f8677c848f86ecbd42ca0ff3cd9dd71c158527b344c69ba14710d816d8489c746b6ca225e7b615108938a0bda0a54706f8c255933703ac1cf8e703
languageName: node
linkType: hard
"node-gyp@npm:latest":
version: 9.4.0
resolution: "node-gyp@npm:9.4.0"
@@ -5691,6 +5723,16 @@ __metadata:
languageName: node
linkType: hard
"snake-case@npm:^3.0.4":
version: 3.0.4
resolution: "snake-case@npm:3.0.4"
dependencies:
dot-case: ^3.0.4
tslib: ^2.0.3
checksum: ab19a913969f58f4474fe9f6e8a026c8a2142a01f40b52b79368068343177f818cdfef0b0c6b9558f298782441d5ca8ed5932eb57822439fad791d866e62cecd
languageName: node
linkType: hard
"sockette@npm:^2.0.6":
version: 2.0.6
resolution: "sockette@npm:2.0.6"
@@ -6014,9 +6056,9 @@ __metadata:
languageName: node
linkType: hard
"terser@npm:^5.19.4":
version: 5.19.4
resolution: "terser@npm:5.19.4"
"terser@npm:^5.20.0":
version: 5.20.0
resolution: "terser@npm:5.20.0"
dependencies:
"@jridgewell/source-map": ^0.3.3
acorn: ^8.8.2
@@ -6024,7 +6066,7 @@ __metadata:
source-map-support: ~0.5.20
bin:
terser: bin/terser
checksum: 39c6687609f5b9061f2fb82bee02d2f9d7756fcb5bd50c67da1482f52cf5977e03e0c5df5cb4ce17e549428024c8859075137c461ec4a9ae8cf91a505759255a
checksum: ab70d1009fc9d39b89b3fbe5be12d55ade4574df0978de53e046ce109f45d5623fcbbddcb70453e1d95d4967338dab9e41bcff94c1ec636a27c52ef7f6db3936
languageName: node
linkType: hard
@@ -6093,7 +6135,7 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0":
"tslib@npm:^2.0.3, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0":
version: 2.6.2
resolution: "tslib@npm:2.6.2"
checksum: e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb
@@ -6271,16 +6313,16 @@ __metadata:
languageName: node
linkType: hard
"vite-plugin-svgr@npm:^3.2.0":
version: 3.2.0
resolution: "vite-plugin-svgr@npm:3.2.0"
"vite-plugin-svgr@npm:^4.0.0":
version: 4.0.0
resolution: "vite-plugin-svgr@npm:4.0.0"
dependencies:
"@rollup/pluginutils": ^5.0.2
"@svgr/core": ^7.0.0
"@svgr/plugin-jsx": ^7.0.0
"@rollup/pluginutils": ^5.0.4
"@svgr/core": ^8.1.0
"@svgr/plugin-jsx": ^8.1.0
peerDependencies:
vite: ^2.6.0 || 3 || 4
checksum: f801759810be82e997acb26b6b0f8c6dc012d7bcb4d430e1e75ef210f6f05580c589b7f65c9729fe4993fa919433903b71a74ddfc490e41af69720cf857de9d9
checksum: 9b6009302479ed48d102108afe4ad7a2a4969ea6835cd835640d621c50bb46659bb5c199d571ab14006d928766f32bb8f8857cfd682cfe9078080147a6f626d8
languageName: node
linkType: hard

View File

@@ -129,8 +129,6 @@ bool MqttClient::connect() {
_onError(0, Error::OUT_OF_MEMORY);
}
EMC_SEMAPHORE_GIVE();
} else if (_state <= State::connected) { // already connected or connecting
result = true;
}
return result;
}

View File

@@ -22,6 +22,8 @@ void NetworkSettingsService::begin() {
WiFi.mode(WIFI_MODE_MAX);
WiFi.mode(WIFI_MODE_NULL);
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); // default is FAST_SCAN
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); // is default, no need to set
WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, _1));
@@ -58,25 +60,36 @@ void NetworkSettingsService::manageSTA() {
if (_state.staticIPConfig) {
WiFi.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); // configure for static IP
}
WiFi.setHostname(_state.hostname.c_str()); // set hostname
// www.esp32.com/viewtopic.php?t=12055
read([&](NetworkSettings & networkSettings) {
if (networkSettings.bandwidth20) {
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT20);
} else {
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT40);
if (_state.bandwidth20) {
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT20);
} else {
esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT40);
}
if (_state.nosleep) {
WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE
}
// attempt to connect to the network
uint mac[6];
if (!_state.bssid.isEmpty() && sscanf(_state.bssid.c_str(), "%X:%X:%X:%X:%X:%X", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6) {
uint8_t mac1[6];
for (uint8_t i = 0; i < 6; i++) {
mac1[i] = (uint8_t)mac[i];
}
if (networkSettings.nosleep) {
WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE
}
WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); // attempt to connect to the network
esp_wifi_set_max_tx_power(networkSettings.tx_power * 4); // set power after wifi is startet for C3
});
WiFi.begin(_state.ssid.c_str(), _state.password.c_str(), 0, mac1);
} else {
WiFi.begin(_state.ssid.c_str(), _state.password.c_str());
}
// set power after wifi is startet, fixed value for C3_V1
#ifdef BOARD_C3_MINI_V1
// v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979
WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
#else
// esp_wifi_set_max_tx_power(_state.tx_power * 4);
WiFi.setTxPower((wifi_power_t)(_state.tx_power * 4));
#endif
}
}
@@ -89,4 +102,8 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event) {
_stopping = false;
}
}
// wait 3 seconds before reconnecting
// if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
// _lastConnectionAttempt = millis();
// }
}

View File

@@ -31,6 +31,7 @@ class NetworkSettings {
public:
// core wifi configuration
String ssid;
String bssid;
String password;
String hostname;
bool staticIPConfig;
@@ -52,6 +53,7 @@ class NetworkSettings {
static void read(NetworkSettings & settings, JsonObject & root) {
// connection settings
root["ssid"] = settings.ssid;
root["bssid"] = settings.bssid;
root["password"] = settings.password;
root["hostname"] = settings.hostname;
root["static_ip_config"] = settings.staticIPConfig;
@@ -75,6 +77,7 @@ class NetworkSettings {
auto enableCORS = settings.enableCORS;
auto CORSOrigin = settings.CORSOrigin;
settings.ssid = root["ssid"] | FACTORY_WIFI_SSID;
settings.bssid = root["bssid"] | "";
settings.password = root["password"] | FACTORY_WIFI_PASSWORD;
settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME;
settings.staticIPConfig = root["static_ip_config"] | false;

View File

@@ -1,6 +1,8 @@
#include <RestartService.h>
#include <esp_ota_ops.h>
#include "../../src/emsesp_stub.hpp"
using namespace std::placeholders; // for `_1` etc
RestartService::RestartService(AsyncWebServer * server, SecurityManager * securityManager) {
@@ -11,6 +13,7 @@ RestartService::RestartService(AsyncWebServer * server, SecurityManager * securi
}
void RestartService::restart(AsyncWebServerRequest * request) {
emsesp::EMSESP::system_.store_nvs_values();
request->onDisconnect(RestartService::restartNow);
request->send(200);
}
@@ -19,6 +22,7 @@ void RestartService::partition(AsyncWebServerRequest * request) {
const esp_partition_t * factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
if (factory_partition) {
esp_ota_set_boot_partition(factory_partition);
emsesp::EMSESP::system_.store_nvs_values();
request->onDisconnect(RestartService::restartNow);
request->send(200);
return;
@@ -35,6 +39,7 @@ void RestartService::partition(AsyncWebServerRequest * request) {
return;
}
esp_ota_set_boot_partition(ota_partition);
emsesp::EMSESP::system_.store_nvs_values();
request->onDisconnect(RestartService::restartNow);
request->send(200);
}

View File

@@ -1,6 +1,8 @@
#include <UploadFileService.h>
#include <esp_ota_ops.h>
#include "../../src/emsesp_stub.hpp"
using namespace std::placeholders; // for `_1` etc
static bool is_firmware = false;
@@ -112,6 +114,7 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) {
// did we complete uploading a json file?
if (request->_tempFile) {
request->_tempFile.close(); // close the file handle as the upload is now done
emsesp::EMSESP::system_.store_nvs_values();
request->onDisconnect(RestartService::restartNow);
AsyncWebServerResponse * response = request->beginResponse(200);
request->send(response);
@@ -121,6 +124,7 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) {
// check if it was a firmware upgrade
// if no error, send the success response as a JSON
if (is_firmware && !request->_tempObject) {
emsesp::EMSESP::system_.store_nvs_values();
request->onDisconnect(RestartService::restartNow);
AsyncWebServerResponse * response = request->beginResponse(200);
request->send(response);

View File

@@ -116,7 +116,7 @@ board_build.partitions = esp32_partition_16M.csv
build_flags = ${common.build_flags}
[env:lolin_c3_mini]
extends = espressi32_base
extends = espressi32_base_tasmota
board = lolin_c3_mini
board_upload.flash_size = 4MB
board_build.partitions = esp32_asym_partition_4M.csv
@@ -125,14 +125,14 @@ build_flags = ${common.build_flags}
; lolin C3 mini v1 needs special wifi init.
; https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi
[env:lolin_c3_mini_v1]
extends = espressi32_base
extends = espressi32_base_tasmota
board = lolin_c3_mini
board_upload.flash_size = 4MB
board_build.partitions = esp32_asym_partition_4M.csv
build_flags = ${common.build_flags} -DBOARD_C3_MINI_V1
[env:lolin_s2_mini]
extends = espressi32_base
extends = espressi32_base_tasmota
board = lolin_s2_mini
board_upload.flash_size = 4MB
board_build.partitions = esp32_asym_partition_4M.csv

View File

@@ -160,6 +160,9 @@ void AnalogSensor::reload() {
#endif
sensor.polltime_ = 0;
sensor.poll_ = digitalRead(sensor.gpio());
if (double_t val = EMSESP::nvs_.getDouble(sensor.name().c_str(), 0)) {
sensor.set_value(val);
}
publish_sensor(sensor);
} else if (sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) {
LOG_DEBUG("Adding analog Timer/Rate sensor on GPIO %02d", sensor.gpio());
@@ -274,7 +277,8 @@ void AnalogSensor::measure() {
} else if (!sensor.poll_) { // falling edge
if (sensor.type() == AnalogType::COUNTER) {
sensor.set_value(old_value + sensor.factor());
} else if (sensor.type() == AnalogType::RATE) { // dafault uom: Hz (1/sec) with factor 1
// EMSESP::nvs_.putDouble(sensor.name().c_str(), sensor.value());
} else if (sensor.type() == AnalogType::RATE) { // default uom: Hz (1/sec) with factor 1
sensor.set_value(sensor.factor() * 1000 / (sensor.polltime_ - sensor.last_polltime_));
} else if (sensor.type() == AnalogType::TIMER) { // default seconds with factor 1
sensor.set_value(sensor.factor() * (sensor.polltime_ - sensor.last_polltime_) / 1000);
@@ -290,6 +294,25 @@ void AnalogSensor::measure() {
}
}
}
// store counter-values only every hour to reduce flash wear
static uint8_t lastSaveHour = 0;
time_t now = time(nullptr);
tm * tm_ = localtime(&now);
if (tm_->tm_hour != lastSaveHour) {
lastSaveHour = tm_->tm_hour;
store_counters();
}
}
// store counters to NVS, called every hour, on restart and update
void AnalogSensor::store_counters() {
for (auto & sensor : sensors_) {
if (sensor.type() == AnalogType::COUNTER) {
if (sensor.value() != EMSESP::nvs_.getDouble(sensor.name().c_str())) {
EMSESP::nvs_.putDouble(sensor.name().c_str(), sensor.value());
}
}
}
}
void AnalogSensor::loop() {
@@ -315,10 +338,14 @@ bool AnalogSensor::update(uint8_t gpio, const std::string & name, double offset,
found_sensor = true; // found the record
// see if it's marked for deletion
if (deleted) {
EMSESP::nvs_.remove(AnalogCustomization.name.c_str());
LOG_DEBUG("Removing analog sensor GPIO %02d", gpio);
settings.analogCustomizations.remove(AnalogCustomization);
} else {
// update existing record
if (name != AnalogCustomization.name) {
EMSESP::nvs_.remove(AnalogCustomization.name.c_str());
}
AnalogCustomization.name = name;
AnalogCustomization.offset = offset;
AnalogCustomization.factor = factor;
@@ -598,7 +625,7 @@ void AnalogSensor::publish_values(const bool force) {
// searches by name
bool AnalogSensor::get_value_info(JsonObject & output, const char * cmd, const int8_t id) const {
if (sensors_.empty()) {
return false;
return true;
}
// make a copy of the string command for parsing
char command_s[30];
@@ -656,10 +683,10 @@ bool AnalogSensor::get_value_info(JsonObject & output, const char * cmd, const i
}
// creates JSON doc from values
// returns false if there are no sensors
// returns true if there are no sensors
bool AnalogSensor::command_info(const char * value, const int8_t id, JsonObject & output) const {
if (sensors_.empty()) {
return false;
return true;
}
for (const auto & sensor : sensors_) {

View File

@@ -23,10 +23,6 @@
#include "mqtt.h"
#include "console.h"
#ifndef EMSESP_STANDALONE
#include "driver/adc.h"
#endif
#include <uuid/log.h>
namespace emsesp {
@@ -158,6 +154,7 @@ class AnalogSensor {
bool update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted = false);
bool get_value_info(JsonObject & output, const char * cmd, const int8_t id) const;
void store_counters();
#if defined(EMSESP_TEST)
void test();

View File

@@ -540,22 +540,21 @@ bool Command::device_has_commands(const uint8_t device_type) {
return true; // we always have System
}
// if there are no entries to scheduler/custom/temperaturesensor/analogsensor, don't error but return a message
if (device_type == EMSdevice::DeviceType::SCHEDULER) {
return EMSESP::webSchedulerService.has_commands();
return true;
}
if (device_type == EMSdevice::DeviceType::CUSTOM) {
// if there are no custom entities, don't error but return a message
return true;
// return (EMSESP::webCustomEntityService.count_entities() != 0);
}
if (device_type == EMSdevice::DeviceType::TEMPERATURESENSOR) {
return (EMSESP::temperaturesensor_.have_sensors());
return true;
}
if (device_type == EMSdevice::DeviceType::ANALOGSENSOR) {
return (EMSESP::analogsensor_.have_sensors());
return EMSESP::system_.analog_enabled();
}
for (const auto & emsdevice : EMSESP::emsdevices) {
@@ -575,14 +574,10 @@ bool Command::device_has_commands(const uint8_t device_type) {
// list sensors and EMS devices
void Command::show_devices(uuid::console::Shell & shell) {
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SYSTEM));
if (EMSESP::webSchedulerService.has_commands()) {
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
}
if (EMSESP::temperaturesensor_.have_sensors()) {
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
}
if (EMSESP::analogsensor_.have_sensors()) {
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM));
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
if (EMSESP::analogsensor_.analog_enabled()) {
shell.printf("%s ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR));
}
@@ -610,40 +605,35 @@ void Command::show_all(uuid::console::Shell & shell) {
show(shell, EMSdevice::DeviceType::SYSTEM, true);
// show Custom
if (EMSESP::webCustomEntityService.has_commands()) {
shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM));
shell.println(COLOR_RESET);
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.println(COLOR_RESET);
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::CUSTOM, true);
}
shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM));
shell.println(COLOR_RESET);
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.println(COLOR_RESET);
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::CUSTOM, true);
// show scheduler
if (EMSESP::webSchedulerService.has_commands()) {
shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
shell.println(COLOR_RESET);
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.println(COLOR_RESET);
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::SCHEDULER, true);
}
shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::SCHEDULER));
shell.println(COLOR_RESET);
shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.println(COLOR_RESET);
shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED);
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::SCHEDULER, true);
// show sensors
if (EMSESP::temperaturesensor_.have_sensors()) {
shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::TEMPERATURESENSOR, true);
}
if (EMSESP::analogsensor_.have_sensors()) {
shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::TEMPERATURESENSOR));
shell.print(COLOR_RESET);
show(shell, EMSdevice::DeviceType::TEMPERATURESENSOR, true);
if (EMSESP::analogsensor_.analog_enabled()) {
shell.print(COLOR_BOLD_ON);
shell.print(COLOR_YELLOW);
shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::ANALOGSENSOR));

View File

@@ -342,7 +342,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
DeviceValueNumOp::DV_NUMOP_DIV60,
FL_(upTimeCompCooling),
DeviceValueUOM::MINUTES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&upTimeCompWw_,
DeviceValueType::TIME,
DeviceValueNumOp::DV_NUMOP_DIV60,
@@ -362,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, &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_BOILER_DATA_WW, &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);
@@ -371,11 +371,11 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
DeviceValueType::ULONG,
FL_(auxElecHeatNrgConsHeating),
DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &auxElecHeatNrgConsWW_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsWW), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &auxElecHeatNrgConsPool_, DeviceValueType::ULONG, FL_(auxElecHeatNrgConsPool), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppTotal_, DeviceValueType::ULONG, FL_(nrgSuppTotal), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppHeating_, DeviceValueType::ULONG, FL_(nrgSuppHeating), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgSuppWw_, DeviceValueType::ULONG, FL_(nrgSuppWw), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppCooling_, DeviceValueType::ULONG, FL_(nrgSuppCooling), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgSuppPool_, DeviceValueType::ULONG, FL_(nrgSuppPool), DeviceValueUOM::KWH);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpPower_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hpPower), DeviceValueUOM::KW);
@@ -383,7 +383,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
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, FL_(hpHeatingOn), 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, FL_(hpWwOn), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &hpWwOn_, DeviceValueType::BOOL, FL_(hpWwOn), 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, FL_(hpBrinePumpSpd), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &hpSwitchValve_, DeviceValueType::BOOL, FL_(hpSwitchValve), DeviceValueUOM::NONE);
@@ -466,7 +466,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
FL_(maxHeatHeat),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_maxHeatHeat));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&maxHeatDhw_,
DeviceValueType::ENUM,
FL_(enum_maxHeat),
@@ -750,7 +750,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
register_device_value(
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxPower_, DeviceValueType::UINT, FL_(wwMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_ww_maxpower), 0, 254);
register_device_value(
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 70);
DeviceValueTAG::TAG_BOILER_DATA_WW, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_ww_maxtemp), 0, 80);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW,
&wwCircPump_,
DeviceValueType::BOOL,
@@ -849,6 +849,43 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
EMSESP::send_read_request(0x15, device_id); // read maintenance data 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)
if (model() != EMS_DEVICE_FLAG_HEATPUMP) {
register_telegram_type(0x04, "UBAFactory", true, MAKE_PF_CB(process_UBAFactory));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nrgHeat_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgHeat), DeviceValueUOM::KWH, MAKE_CF_CB(set_nrgHeat), 0, 10000000UL);
register_device_value(DeviceValueTAG::TAG_BOILER_DATA_WW, &nrgWw_, DeviceValueType::ULONG, DeviceValueNumOp::DV_NUMOP_DIV100, FL_(nrgWw), DeviceValueUOM::KWH, MAKE_CF_CB(set_nrgWw), 0, 10000000UL);
nrgHeatF_ = EMSESP::nvs_.getDouble(FL_(nrgHeat)[0], 0);
nrgWwF_ = EMSESP::nvs_.getDouble(FL_(nrgWw)[0], 0);
nomPower_ = EMSESP::nvs_.getUChar(FL_(nomPower)[0], 0);
if (nrgHeatF_ < 0 || nrgHeatF_ >= EMS_VALUE_ULLONG_NOTSET) {
nrgHeatF_ = 0;
}
if (nrgWwF_ < 0 || nrgWwF_ >= EMS_VALUE_ULLONG_NOTSET) {
nrgWwF_ = 0;
}
if (nomPower_ == EMS_VALUE_UINT_NOTSET) {
nomPower_ = 0;
}
store_energy();
// update/publish the values
has_update(nrgHeat_, (uint32_t)(nrgHeatF_ + 0.5));
has_update(nrgWw_, (uint32_t)(nrgWwF_ + 0.5));
has_update(&nomPower_);
}
}
void Boiler::store_energy() {
// only write if something is changed
if (nrgHeatF_ != EMSESP::nvs_.getDouble(FL_(nrgHeat)[0]) || nrgWwF_ != EMSESP::nvs_.getDouble(FL_(nrgWw)[0])
|| nomPower_ != EMSESP::nvs_.getUChar(FL_(nomPower)[0])) {
EMSESP::nvs_.putDouble(FL_(nrgHeat)[0], nrgHeatF_);
EMSESP::nvs_.putDouble(FL_(nrgWw)[0], nrgWwF_);
EMSESP::nvs_.putUChar(FL_(nomPower)[0], nomPower_);
LOG_DEBUG("energy values stored");
}
}
// Check if hot tap water or heating is active
@@ -894,6 +931,48 @@ void Boiler::check_active() {
Mqtt::queue_publish(F_(tapwater_active), Helpers::render_boolean(s, b));
EMSESP::tap_water_active(b); // let EMS-ESP know, used in the Shower class
}
// calculate energy for boiler 0x08 from stored modulation an time in units of 0.01 Wh
if (model() != EMS_DEVICE_FLAG_HEATPUMP) {
// remember values from last call
static uint32_t powLastReadTime_ = uuid::get_uptime();
static uint8_t heatBurnPow = 0;
static uint8_t wwBurnPow = 0;
static uint8_t lastSaveHour = 0;
// store in units of 0.01 kWh, resolution needed: 0.01 Wh = 0.01 Ws / 3600 = (% * kW * ms) / 3600
nrgHeatF_ += ((double)((uint32_t)heatBurnPow * nomPower_ * (uuid::get_uptime() - powLastReadTime_)) / 3600) / 1000UL;
nrgWwF_ += ((double)((uint32_t)wwBurnPow * nomPower_ * (uuid::get_uptime() - powLastReadTime_)) / 3600) / 1000UL;
has_update(nrgHeat_, (uint32_t)(nrgHeatF_ + 0.5));
has_update(nrgWw_, (uint32_t)(nrgWwF_ + 0.5));
// check for store values
time_t now = time(nullptr);
tm * tm_ = localtime(&now);
if (tm_->tm_hour != lastSaveHour) {
lastSaveHour = tm_->tm_hour;
store_energy();
} else if (curBurnPow_ == 0 && (heatBurnPow + wwBurnPow) > 0) { // on burner switch off
store_energy();
}
// store new modulation and time
heatBurnPow = heatingActive_ ? curBurnPow_ : 0;
wwBurnPow = tapwaterActive_ ? curBurnPow_ : 0;
powLastReadTime_ = uuid::get_uptime();
}
}
// 0x04
// boiler(0x08) -W-> Me(0x0B), ?(0x04), data: 13 96 09 81 00 64 64 35 05 64 5A 22 00 00 00 00 00 00 00 00 B7
// offset 4 - nominal Power kW, could be zero, 5 - min. Burner, 6 - max. Burner
void Boiler::process_UBAFactory(std::shared_ptr<const Telegram> telegram) {
uint8_t nomPower = nomPower_;
if (!telegram->read_value(nomPower, 4)) {
return;
}
// Update nominal Power only if not already set in nvs and we have a valid value
if (nomPower > 0 && nomPower_ == 0) {
has_update(nomPower_, nomPower);
}
toggle_fetch(telegram->type_id, false); // only read once
}
// 0x18
@@ -936,7 +1015,9 @@ void Boiler::process_UBAMonitorFast(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, serviceCodeNumber_, 20);
check_active(); // do a quick check to see if the hot water or heating is active
if (telegram->offset <= 4 && telegram->offset + telegram->message_length > 5) {
check_active(); // do a quick check to see if the hot water or heating is active
}
}
/*
@@ -1075,7 +1156,9 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram
boilerState_ |= state & 0x04 ? 0x02 : 0;
}
check_active(); // do a quick check to see if the hot water or heating is active
if (telegram->offset <= 10 && telegram->offset + telegram->message_length > 11) {
check_active(); // do a quick check to see if the hot water or heating is active
}
}
/*
@@ -2642,4 +2725,43 @@ bool Boiler::set_wwAltOpPrio(const char * value, const int8_t id) {
return false;
}
// energy counters. Setting an invalid value does not update, but trigger a store.
bool Boiler::set_nrgHeat(const char * value, const int8_t id) {
float v;
if (!Helpers::value2float(value, v)) {
return false;
}
if (v >= 0) {
nrgHeatF_ = v * 100;
has_update(nrgHeat_, (uint32_t)(nrgHeatF_ + 0.5));
}
store_energy();
return true;
}
bool Boiler::set_nrgWw(const char * value, const int8_t id) {
float v;
if (!Helpers::value2float(value, v)) {
return false;
}
if (v >= 0) {
nrgWwF_ = v * 100;
has_update(nrgWw_, (uint32_t)(nrgWwF_ + 0.5));
}
store_energy();
return true;
}
bool Boiler::set_nomPower(const char * value, const int8_t id) {
int v;
if (!Helpers::value2number(value, v)) {
return false;
}
if (v > 0 && v < EMS_VALUE_UINT_NOTSET) {
has_update(nomPower_, (uint8_t)v);
}
store_energy();
return true;
}
} // namespace emsesp

View File

@@ -36,6 +36,7 @@ class Boiler : public EMSdevice {
}
void check_active();
void store_energy();
uint8_t boilerState_ = EMS_VALUE_UINT_NOTSET; // Boiler state flag - FOR INTERNAL USE
@@ -258,6 +259,13 @@ class Boiler : public EMSdevice {
uint8_t keepWarmTemp_;
uint8_t setReturnTemp_;
// special
double nrgHeatF_;
double nrgWwF_;
uint32_t nrgHeat_;
uint32_t nrgWw_;
uint8_t nomPower_;
/*
// Hybrid heatpump with telegram 0xBB is readable and writeable in boiler and thermostat
// thermostat always overwrites settings in boiler
@@ -272,6 +280,7 @@ class Boiler : public EMSdevice {
uint8_t tempDiffBoiler_; // relative temperature degrees
*/
void process_UBAFactory(std::shared_ptr<const Telegram> telegram);
void process_UBAParameterWW(std::shared_ptr<const Telegram> telegram);
void process_UBAMonitorFast(std::shared_ptr<const Telegram> telegram);
void process_UBATotalUptime(std::shared_ptr<const Telegram> telegram);
@@ -468,6 +477,11 @@ class Boiler : public EMSdevice {
bool set_delayBoiler(const char * value, const int8_t id);
bool set_tempDiffBoiler(const char * value, const int8_t id);
*/
bool set_nrgHeat(const char * value, const int8_t id);
bool set_nrgWw(const char * value, const int8_t id);
bool set_nomPower(const char * value, const int8_t id);
};
} // namespace emsesp

View File

@@ -488,7 +488,7 @@ void EMSdevice::add_device_value(uint8_t tag, // to b
uint8_t uom, // unit of measure from DeviceValueUOM
const cmd_function_p f, // command function pointer
int16_t min, // min allowed value
uint16_t max // max allowed value
uint32_t max // max allowed value
) {
// initialize the device value depending on it's type
// ignoring DeviceValueType::CMD and DeviceValueType::TIME
@@ -605,7 +605,7 @@ void EMSdevice::register_device_value(uint8_t tag,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max) {
uint32_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);
};
@@ -628,7 +628,7 @@ void EMSdevice::register_device_value(uint8_t tag,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max) {
uint32_t max) {
add_device_value(tag, value_p, type, nullptr, nullptr, numeric_operator, name, uom, f, min, max);
}
@@ -645,7 +645,7 @@ void EMSdevice::register_device_value(uint8_t tag,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max) {
uint32_t max) {
add_device_value(tag, value_p, type, nullptr, nullptr, 0, name, uom, f, min, max);
};
@@ -660,7 +660,7 @@ void EMSdevice::register_device_value(uint8_t tag,
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max) {
uint32_t max) {
add_device_value(tag, value_p, type, options, nullptr, 0, name, uom, f, min, max);
}
@@ -939,7 +939,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
}
int16_t dv_set_min;
uint16_t dv_set_max;
uint32_t dv_set_max;
if (dv.get_min_max(dv_set_min, dv_set_max)) {
obj["m"] = dv_set_min;
obj["x"] = dv_set_max;
@@ -1033,7 +1033,7 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
if (dv.has_cmd && (obj["v"].is<float>() || obj["v"].is<int>())) {
// set the min and max values if there are any and if entity has a value
int16_t dv_set_min;
uint16_t dv_set_max;
uint32_t dv_set_max;
if (dv.get_min_max(dv_set_min, dv_set_max)) {
obj["mi"] = dv_set_min;
obj["ma"] = dv_set_max;
@@ -1059,7 +1059,7 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
});
}
void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint16_t max) {
void EMSdevice::set_climate_minmax(uint8_t tag, int16_t min, uint32_t max) {
for (auto & dv : devicevalues_) {
if (dv.tag == tag && (strcmp(dv.short_name, FL_(haclimate[0])) == 0)) {
if (dv.min != min || dv.max != max) {
@@ -1236,7 +1236,7 @@ void EMSdevice::dump_value_info() {
// min/max range
int16_t dv_set_min;
uint16_t dv_set_max;
uint32_t dv_set_max;
if (dv.get_min_max(dv_set_min, dv_set_max)) {
Serial.print(" (>=");
Serial.print(dv_set_min);
@@ -1473,7 +1473,7 @@ bool EMSdevice::get_value_info(JsonObject & output, const char * cmd, const int8
// set the min and max only for commands
if (dv.has_cmd) {
int16_t dv_set_min;
uint16_t dv_set_max;
uint32_t dv_set_max;
if (dv.get_min_max(dv_set_min, dv_set_max)) {
json["min"] = dv_set_min;
json["max"] = dv_set_max;

View File

@@ -155,6 +155,22 @@ class EMSdevice {
}
}
inline void has_update(uint16_t & value, uint16_t newvalue) {
if (value != newvalue) {
value = newvalue;
has_update_ = true;
publish_value((void *)&value);
}
}
inline void has_update(uint32_t & value, uint32_t newvalue) {
if (value != newvalue) {
value = newvalue;
has_update_ = true;
publish_value((void *)&value);
}
}
inline void has_enumupdate(std::shared_ptr<const Telegram> telegram, uint8_t & value, const uint8_t index, int8_t s = 0) {
if (telegram->read_enumvalue(value, index, s)) {
has_update_ = true;
@@ -190,7 +206,7 @@ class EMSdevice {
void list_device_entries(JsonObject & output) const;
void add_handlers_ignored(const uint16_t handler);
void set_climate_minmax(uint8_t tag, int16_t min, uint16_t max);
void set_climate_minmax(uint8_t tag, int16_t min, uint32_t max);
void setCustomizationEntity(const std::string & entity_id);
void getCustomizationEntities(std::vector<std::string> & entity_ids);
@@ -216,7 +232,7 @@ class EMSdevice {
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
uint32_t max);
void register_device_value(uint8_t tag,
void * value_p,
@@ -226,7 +242,7 @@ class EMSdevice {
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
uint32_t max);
void
register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const ** options, const char * const * name, uint8_t uom, const cmd_function_p f);
@@ -249,7 +265,7 @@ class EMSdevice {
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
uint32_t max);
// single list of options
void register_device_value(uint8_t tag,
@@ -269,14 +285,14 @@ class EMSdevice {
uint8_t uom,
const cmd_function_p f,
int16_t min,
uint16_t max);
uint32_t max);
// no options, optional function f
void register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * 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 char * const * name, uint8_t uom, const cmd_function_p f, int16_t min, uint16_t max);
register_device_value(uint8_t tag, void * value_p, uint8_t type, const char * const * name, uint8_t uom, const cmd_function_p f, int16_t min, uint32_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, const uint8_t value, const uint16_t validate_typeid) const;

View File

@@ -36,7 +36,7 @@ DeviceValue::DeviceValue(uint8_t device_type,
uint8_t uom,
bool has_cmd,
int16_t min,
uint16_t max,
uint32_t max,
uint8_t state)
: device_type(device_type)
, tag(tag)
@@ -261,7 +261,7 @@ bool DeviceValue::has_tag() const {
// converts to signed int, which means rounding to an whole integer
// returns false if there is no min/max needed
// Types BOOL, ENUM, STRING and CMD are not used
bool DeviceValue::get_min_max(int16_t & dv_set_min, uint16_t & dv_set_max) {
bool DeviceValue::get_min_max(int16_t & dv_set_min, uint32_t & dv_set_max) {
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
@@ -340,7 +340,7 @@ bool DeviceValue::get_custom_min(int16_t & val) {
}
// extract custom max from custom_fullname
bool DeviceValue::get_custom_max(uint16_t & val) {
bool DeviceValue::get_custom_max(uint32_t & val) {
auto max_pos = custom_fullname.find('<');
bool has_max = (max_pos != std::string::npos);
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;

View File

@@ -159,7 +159,7 @@ class DeviceValue {
uint8_t uom; // DeviceValueUOM::*
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
int16_t min; // min range
uint16_t max; // max range
uint32_t max; // max range
uint8_t state; // DeviceValueState::*
DeviceValue(uint8_t device_type,
@@ -175,16 +175,16 @@ class DeviceValue {
uint8_t uom,
bool has_cmd,
int16_t min,
uint16_t max,
uint32_t max,
uint8_t state);
bool hasValue() const;
bool has_tag() const;
bool get_min_max(int16_t & dv_set_min, uint16_t & dv_set_max);
bool get_min_max(int16_t & dv_set_min, uint32_t & dv_set_max);
void set_custom_minmax();
bool get_custom_min(int16_t & val);
bool get_custom_max(uint16_t & val);
bool get_custom_max(uint32_t & val);
std::string get_custom_fullname() const;
std::string get_fullname() const;
static std::string get_name(std::string & entity);

View File

@@ -69,6 +69,7 @@ System EMSESP::system_; // core system services
TemperatureSensor EMSESP::temperaturesensor_; // Temperature sensors
AnalogSensor EMSESP::analogsensor_; // Analog sensors
Shower EMSESP::shower_; // Shower logic
Preferences EMSESP::nvs_; // NV Storage
// static/common variables
uint16_t EMSESP::watch_id_ = WATCH_ID_NONE; // for when log is TRACE. 0 means no trace set
@@ -1486,6 +1487,7 @@ void EMSESP::start() {
system_.system_restart();
};
nvs_.begin("ems-esp");
webSettingsService.begin(); // load EMS-ESP Application settings...
// do any system upgrades

View File

@@ -36,6 +36,7 @@
#ifndef EMSESP_STANDALONE
#include <uuid/telnet.h>
#endif
#include <Preferences.h>
#include <ESP8266React.h>
@@ -225,6 +226,7 @@ class EMSESP {
static Shower shower_;
static RxService rxservice_;
static TxService txservice_;
static Preferences nvs_;
// web controllers
static ESP8266React esp8266React;

View File

@@ -345,7 +345,7 @@ char * Helpers::render_value(char * result, const uint32_t value, const int8_t f
}
result[0] = '\0';
uint32_t new_value = fahrenheit ? format ? value * 1.8 + 32 * format * (fahrenheit - 1) : value * 1.8 + 32 * (fahrenheit - 1) : value;
char s[10] = {0};
char s[14] = {0};
#ifndef EMSESP_STANDALONE
if (!format) {
@@ -354,6 +354,9 @@ char * Helpers::render_value(char * result, const uint32_t value, const int8_t f
strlcpy(result, ltoa(new_value / format, s, 10), sizeof(s));
strlcat(result, ".", sizeof(s));
strlcat(result, itoa(((new_value % format) * 10) / format, s, 10), sizeof(s));
if (format == 100) {
strlcat(result, itoa(new_value % 10, s, 10), sizeof(s));
}
} else {
strlcpy(result, ltoa(new_value * format * -1, s, 10), sizeof(s));
}

View File

@@ -68,9 +68,9 @@ MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehen
MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "publiceer alles naar MQTT", "", "opublikuj wszystko na MQTT", "Publiser alt til MQTT", "", "Hepsini MQTTye gönder", "pubblica tutto su MQTT") // TODO translate
MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema") // TODO translate
MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "activeer tijdschema item", "", "aktywuj wybrany harmonogram", "", "", "program öğesini etkinleştir", "abilitare l'elemento programmato") // TODO translate
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "", "imposta valori personalizzati su EMS") // TODO translate
MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoek om antwoord", "", "", "", "", "") // TODO translate
MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "", "", "", "", "") // TODO translate
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS") // TODO translate
MAKE_WORD_TRANSLATION(commands_response, "get response","Hole Antwort","Verzoek om antwoord", "", "", "", "gelen cevap", "") // TODO translate
MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "", "", "", "", "", "", "soğuk su gönder", "") // TODO translate
// tags
MAKE_WORD_TRANSLATION(tag_boiler_data_ww, "dhw", "WW", "dhw", "VV", "CWU", "dhw", "ecs", "SKS", "dhw")
@@ -197,13 +197,13 @@ MAKE_WORD_TRANSLATION(deltaP4, "deltaP-4", "deltaP-4", "deltaP-4", "", "", "delt
MAKE_WORD_TRANSLATION(none, "none", "keine", "geen", "ingen", "brak", "ingen", "aucun", "hiçbiri", "nessuno")
MAKE_WORD_TRANSLATION(hot_water, "hot water", "Warmwasser", "warm water", "varmvatten", "c.w.u.", "varmtvann", "eau chaude", "sıcak su", "acqua calda")
MAKE_WORD_TRANSLATION(pool, "pool", "Pool", "zwembad", "pool", "basen", "basseng", "piscine", "havuz", "piscina")
MAKE_WORD_TRANSLATION(outside_temp_alt, "outside temperature alt.", "Außentemp. alternativ", "alternatieve buitentemperatuur", "Alternativ utomhustemp.", "temp. zewn. alternat.", "alternativ utendørstemp.", "température extérieure alternative", "alternatif dış sıcaklık", "temperatura esterna alternativa") // TODO translate
MAKE_WORD_TRANSLATION(outside_temp_par, "outside temperature parallel", "Außentemp. parallel", "buitentemperatuur parallel", "Parallell utomhustemp.", "temp. zewn. równoległa", "parallell utendørstemp.", "température extérieure parallèle", "paralel dış sıcaklık", "temperatura esterna parallela") // TODO translate
MAKE_WORD_TRANSLATION(hp_prefered, "heatpump prefered", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita") // TODO translate
MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv ketel", "Värmepanna enbart", "tylko kocioł", "kun kjele", "chaudière uniquement", "sadece kazan", "solo caldaia") // TODO translate
MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita") // TODO translate
MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore") // TODO translate
MAKE_WORD_TRANSLATION(perm, "perm. reduced", "perm. reduziert", "permanent gereduceerd", "Permanent reducerad", "stale zmniejszona wydajność", "permanent redusert", "réduction permanente", "sürekli azaltılmış", "riduzione permanente") // TODO translate
MAKE_WORD_TRANSLATION(outside_temp_alt, "outside temperature alt.", "Außentemp. alternativ", "alternatieve buitentemperatuur", "Alternativ utomhustemp.", "temp. zewn. alternat.", "alternativ utendørstemp.", "température extérieure alternative", "alternatif dış sıcaklık", "temperatura esterna alternativa")
MAKE_WORD_TRANSLATION(outside_temp_par, "outside temperature parallel", "Außentemp. parallel", "buitentemperatuur parallel", "Parallell utomhustemp.", "temp. zewn. równoległa", "parallell utendørstemp.", "température extérieure parallèle", "paralel dış sıcaklık", "temperatura esterna parallela")
MAKE_WORD_TRANSLATION(hp_prefered, "heatpump prefered", "Wärmepumpe bevorzugt", "voorkeur warmtepomp", "Värmepump föredraget", "preferowana pompa ciepła", "varmepumpe prioritert", "pompe à chaleur préférée", "tercih edilen pompa", "pompa di calore preferita")
MAKE_WORD_TRANSLATION(boiler_only, "boiler only", "nur Kessel", "uitsluitend cv ketel", "Värmepanna enbart", "tylko kocioł", "kun kjele", "chaudière uniquement", "sadece kazan", "solo caldaia")
MAKE_WORD_TRANSLATION(reduced_output, "reduced output", "Reduzierte Leistung", "gereduceerde output", "Reducerad produktion", "zmniejszona wydajność", "redusert ytelse", "sortie réduite", "düşürülmüş çıkış", "riduzione uscita")
MAKE_WORD_TRANSLATION(switchoff, "switch off hp", "WP ausschalten", "WP uitschakelen", "Värmepump avstängd", "wyłącz pompę ciepła", "slå av varmepumpe", "éteindre la PAC", "ısı pompasını kapat", "spegnimento pompa calore")
MAKE_WORD_TRANSLATION(perm, "perm. reduced", "perm. reduziert", "permanent gereduceerd", "Permanent reducerad", "stale zmniejszona wydajność", "permanent redusert", "réduction permanente", "sürekli azaltılmış", "riduzione permanente")
// thermostat
MAKE_WORD_TRANSLATION(seltemp, "selTemp", "Solltemperatur", "doeltemperatuur", "Börtemperatur", "temperatura zadana", "innstilt temperatur", "consigne température", "ayarlanmış sıcaklık", "temperatura di consegna")
@@ -450,19 +450,19 @@ MAKE_TRANSLATION(fossileFactor, "fossilefactor", "fossile energy factor", "Energ
MAKE_TRANSLATION(electricFactor, "electricfactor", "electric energy factor", "Energiefaktor elektrisch", "Energiefactor electrisch", "Elektrisk energifaktor", "udział energii elektrycznej", "elektrisk energifaktor", "facteur énergie électrique", "elektrik enerjisi faktörü", "fattore energia elettrica")
MAKE_TRANSLATION(delayBoiler, "delayboiler", "delay boiler support", "Verzögerungs-Option", "Vertragingsoptie", "Fördröjningsoption", "opcja opóźnienia", "Fördörjningsoption", "option retardement chaudière", "kazan desteğini ötele", "opzione ritardo caldaia")
MAKE_TRANSLATION(tempDiffBoiler, "tempdiffboiler", "temp diff boiler support", "Temperaturdifferenz-Option", "Verschiltemperatuuroptie", "Temperaturskillnadsoption", "opcja różnicy temperatur", "temperatursforskjell kjele", "option différence température", "sıcaklık farkı kazan desteği", "opzione differenza temperatura")
MAKE_TRANSLATION(lowNoiseMode, "lownoisemode", "low noise mode", "Geräuscharmer Betrieb", "Stil bedrijf", "Tyst läge", "tryb cichy", "stillemodus", "mode faible bruit", "düşük ses modu", "modalità a basso rumore") // TODO translate
MAKE_TRANSLATION(lowNoiseStart, "lownoisestart", "low noise starttime", "Start geräuscharmer Betrieb", "Start stil bedrijf", "Tyst läge starttid", "początek trybu cichego", "stille modu starttid", "heure démarrage faible bruit", "düşük ses başlangıç", "ora di avvio a basso rumore") // TODO translate
MAKE_TRANSLATION(lowNoiseStop, "lownoisestop", "low noise stoptime", "Stopp geräuscharmer Betrieb", "Stop stil bedrijf", "Tyst läge stopptid", "koniec trybu cichego", "stille modus stopptid", "heure arrêt faible bruit", "düşük ses bitiş", "ora di arresto funzionamento silenzioso") // TODO translate
MAKE_TRANSLATION(energyPriceGas, "energypricegas", "energy price gas", "Energiepreis Gas", "Energieprijs gas", "Gaspris", "cena energii z gazu", "energipris gass", "prix énergie gaz", "gaz enerjisi fiyatı", "prezzo energia gas") // TODO translate
MAKE_TRANSLATION(energyPriceEl, "energypriceel", "energy price electric", "Energiepreis Eletrizität", "energieprijs electriciteit", "Elpris", "cena energii elektrycznej", "strømpris", "prix énergie électrique", "elektrik enerjisi fiyatı", "prezzo energia elettrica") // TODO translate
MAKE_TRANSLATION(energyPricePV, "energyfeedpv", "feed in PV", "PV Einspeisevergütung", "PV teruglevertarief", "PV Energi", "zasilanie energią PV", "strømpris PV", "alimentation PV", "giren güneş enerjisi", "energia fotovoltaico") // TODO translate
MAKE_TRANSLATION(hybridDHW, "hybriddhw", "hybrid DHW", "Hybrid Warmwasser", "Hybride ww", "Hybridläge varmvatten", "hybrydowa c.w.u.", "hybridmodus varmtvann", "ecs hybride", "hibrit SKS", "ACS ibrida") // TODO translate
MAKE_TRANSLATION(airPurgeMode, "airpurgemode", "air purge mode", "Luftspülung", "Luchtzuivering", "Luftreningsläge", "tryb oczyszczania powietrza", "luftsrensningsmodus", "mode purge air", "hava temizleme modu", "modalita spurgo aria") // TODO translate
MAKE_TRANSLATION(heatPumpOutput, "heatpumpoutput", "heatpump output", "WP Leistung", "WP output", "Värmepumpseffekt", "moc wyjściowa pompy ciepła", "varmepumpeeffekt", "sortie pompe à chaleur", "ısı pompası çıkışı", "prestazione pompa calore") // TODO translate
MAKE_TRANSLATION(coolingCircuit, "coolingcircuit", "cooling circuit", "Kühlkreislauf", "Koelcircuit", "Kylkrets", "obwód chłodzący", "kjølekrets", "circuit refroidissement", "soğutma devresi", "circuito raffreddante") // TODO translate
MAKE_TRANSLATION(compStartMod, "compstartmod", "compressor start modulation", "Kompressor Startleistung", "Beginvermogen compressor", "Kompressor startmodulering", "początkowa modulacja sprężarki", "kompressor startmodulering", "modulation démarrage compresseur", "kazan başlangıç modülasyonu", "avvio modulazione compressore") // TODO translate
MAKE_TRANSLATION(heatDrainPan, "heatdrainpan", "heat drain pan", "Wärmeausgleichsgefäß", "Vereffeningsvat", "Uppvärm. dränering", "zbiornik wyrównawczy ciepła", "oppvarming drenering", "bac récupération chaleur", "ısı tahliye tablası", "serbatoio scarico condensa") // TODO translate
MAKE_TRANSLATION(heatCable, "heatcable", "heating cable", "Heizband", "heating cable", "värmekabel", "przewód grzejny", "varmekabel", "câble chauffant", "ısıtma kablosu", "cavo riscaldante") // TODO translate
MAKE_TRANSLATION(lowNoiseMode, "lownoisemode", "low noise mode", "Geräuscharmer Betrieb", "Stil bedrijf", "Tyst läge", "tryb cichy", "stillemodus", "mode faible bruit", "düşük ses modu", "modalità a basso rumore")
MAKE_TRANSLATION(lowNoiseStart, "lownoisestart", "low noise starttime", "Start geräuscharmer Betrieb", "Start stil bedrijf", "Tyst läge starttid", "początek trybu cichego", "stille modu starttid", "heure démarrage faible bruit", "düşük ses başlangıç", "ora di avvio a basso rumore")
MAKE_TRANSLATION(lowNoiseStop, "lownoisestop", "low noise stoptime", "Stopp geräuscharmer Betrieb", "Stop stil bedrijf", "Tyst läge stopptid", "koniec trybu cichego", "stille modus stopptid", "heure arrêt faible bruit", "düşük ses bitiş", "ora di arresto funzionamento silenzioso")
MAKE_TRANSLATION(energyPriceGas, "energypricegas", "energy price gas", "Energiepreis Gas", "Energieprijs gas", "Gaspris", "cena energii z gazu", "energipris gass", "prix énergie gaz", "gaz enerjisi fiyatı", "prezzo energia gas")
MAKE_TRANSLATION(energyPriceEl, "energypriceel", "energy price electric", "Energiepreis Eletrizität", "energieprijs electriciteit", "Elpris", "cena energii elektrycznej", "strømpris", "prix énergie électrique", "elektrik enerjisi fiyatı", "prezzo energia elettrica")
MAKE_TRANSLATION(energyPricePV, "energyfeedpv", "feed in PV", "PV Einspeisevergütung", "PV teruglevertarief", "PV Energi", "zasilanie energią PV", "strømpris PV", "alimentation PV", "giren güneş enerjisi", "energia fotovoltaico")
MAKE_TRANSLATION(hybridDHW, "hybriddhw", "hybrid DHW", "Hybrid Warmwasser", "Hybride ww", "Hybridläge varmvatten", "hybrydowa c.w.u.", "hybridmodus varmtvann", "ecs hybride", "hibrit SKS", "ACS ibrida")
MAKE_TRANSLATION(airPurgeMode, "airpurgemode", "air purge mode", "Luftspülung", "Luchtzuivering", "Luftreningsläge", "tryb oczyszczania powietrza", "luftsrensningsmodus", "mode purge air", "hava temizleme modu", "modalita spurgo aria")
MAKE_TRANSLATION(heatPumpOutput, "heatpumpoutput", "heatpump output", "WP Leistung", "WP output", "Värmepumpseffekt", "moc wyjściowa pompy ciepła", "varmepumpeeffekt", "sortie pompe à chaleur", "ısı pompası çıkışı", "prestazione pompa calore")
MAKE_TRANSLATION(coolingCircuit, "coolingcircuit", "cooling circuit", "Kühlkreislauf", "Koelcircuit", "Kylkrets", "obwód chłodzący", "kjølekrets", "circuit refroidissement", "soğutma devresi", "circuito raffreddante")
MAKE_TRANSLATION(compStartMod, "compstartmod", "compressor start modulation", "Kompressor Startleistung", "Beginvermogen compressor", "Kompressor startmodulering", "początkowa modulacja sprężarki", "kompressor startmodulering", "modulation démarrage compresseur", "kazan başlangıç modülasyonu", "avvio modulazione compressore")
MAKE_TRANSLATION(heatDrainPan, "heatdrainpan", "heat drain pan", "Wärmeausgleichsgefäß", "Vereffeningsvat", "Uppvärm. dränering", "zbiornik wyrównawczy ciepła", "oppvarming drenering", "bac récupération chaleur", "ısı tahliye tablası", "serbatoio scarico condensa")
MAKE_TRANSLATION(heatCable, "heatcable", "heating cable", "Heizband", "heating cable", "värmekabel", "przewód grzejny", "varmekabel", "câble chauffant", "ısıtma kablosu", "cavo riscaldante")
// alternative heatsource AM200
MAKE_TRANSLATION(aCylTopTemp, "cyltoptemp", "cylinder top temperature", "Speichertemperatur Oben", "Buffer temperatuur boven", "Cylindertemperatur Toppen", "temperatura na górze cylindra", "beredertemperatur topp", "température haut cylindre", "silindir üst yüzey sıcaklığı", "temperatura superiore accumulo")
@@ -500,10 +500,15 @@ MAKE_TRANSLATION(blockTerm, "blockterm", "config of block terminal", "Konfig. Sp
MAKE_TRANSLATION(blockHyst, "blockhyst", "hyst. for boiler block", "Hysterese Sperrmodus", "Hysterese blokeerterminal", "Hysteres Blockeringsmodul", "tryb blokowania histerezy", "hystrese blokkeringsmodus", "hyst. Blocage chaudière", "kazan blok geçikmesi", "modalità blocco isteresi")
MAKE_TRANSLATION(releaseWait, "releasewait", "boiler release wait time", "Wartezeit Kessel-Freigabe", "Wachttijd ketel vrijgave", "Väntetid Frisläppning", "czas oczekiwania na zwolnienie kotła", "kjele frigjøringsventetid", "temps attente libération chaudière", "kazan tahliyesi bekleme süresi", "tempo di attesa sblocco caldaia")
// energy
MAKE_TRANSLATION(nrgHeat, "nrgheat", "energy heating", "Energie Heizen", "", "", "", "", "", "ısıtma enerjisi", "") // TODO translate
MAKE_TRANSLATION(nrgWw, "nrgww", "energy dhw", "Energie Warmwasser", "", "", "", "", "", "sıcak kullanım suyu enerjisi", "") // TODO translate
MAKE_TRANSLATION(nomPower, "nompower", "nominal Power", "Brennerleistung", "", "", "", "", "", "nominal güç", "") // TODO translate
// HIU
MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "", "", "", "", "temperatura di mandata della rete di riscaldamento")
MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water ", "", "", "", "", "", "portata acqua fredda")
MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature", "Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "", "", "", "mantenere la temperatura calda")
MAKE_TRANSLATION(netFlowTemp, "netflowtemp", "heat network flow temp", "System Vorlauftemperatur", "Netto aanvoertemperatuur", "", "", "", "", "ısıtma şebekesi akış derecesi", "temperatura di mandata della rete di riscaldamento") // TODO translate
MAKE_TRANSLATION(cwFlowRate, "cwflowrate", "cold water flow rate", "Kaltwasser Durchfluss", "Stroomsnelheid koud water ", "", "", "", "", "soğuk su akış hızı", "portata acqua fredda") // TODO translate
MAKE_TRANSLATION(keepWarmTemp, "keepwarmtemp", "keep warm temperature","Warmhaltetemperatur", "Warmhoudtemperatuur", "", "", "", "", "sıcaklığı koruma derecesi", "mantenere la temperatura calda") // TODO translate
// the following are dhw for the boiler and automatically tagged with 'dhw'
MAKE_TRANSLATION(wwSelTemp, "wwseltemp", "selected temperature", "gewählte Temperatur", "Geselecteerd temperatuur", "Vald Temperatur", "temperatura wyższa/komfort", "valgt temperatur", "température sélectionnée", "seçili sıcaklık", "temperatura selezionata")
@@ -550,20 +555,20 @@ MAKE_TRANSLATION(wwOneTimeKey, "wwonetimekey", "one time key function", "Einmall
MAKE_TRANSLATION(wwSolarTemp, "wwsolartemp", "solar boiler temperature", "Solarboiler Temperatur", "Zonneboiler temperatuur", "Solpanel Temp", "temperatura zasobnika solarnego", "solpaneltemp", "température chaudière solaire", "güneş enerjisi kazan sıcaklığı", "temperatura pannello solare")
// mqtt values / commands
MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "", "ora commutazione programmata") // TODO translate
MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programm 1 Schaltzeit", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "", "ora commutazione programma 1") // TODO translate
MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programm 2 Schaltzeit", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "", "ora commutazione programma 2") // TODO translate
MAKE_TRANSLATION(wwswitchtime, "wwswitchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "", "Tempo di commutazione del programma") // TODO translate
MAKE_TRANSLATION(wwcircswitchtime, "wwcircswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "", "ora commutazione programma circolazione") // TODO translate
MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programm Schaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "program değiştirme süresi", "ora commutazione programmata")
MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programm 1 Schaltzeit", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "program1 değiştirme süresi", "ora commutazione programma 1")
MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programm 2 Schaltzeit", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "program1 değiştirme süresi", "ora commutazione programma 2")
MAKE_TRANSLATION(wwswitchtime, "wwswitchtime", "program switchtime", "Programm Schaltzeit", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "sıcak kullanıom suyu program değiştirme süresi", "Tempo di commutazione del programma")
MAKE_TRANSLATION(wwcircswitchtime, "wwcircswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "sirkülasyon program değiştirme süresi", "ora commutazione programma circolazione")
MAKE_TRANSLATION(dateTime, "datetime", "date/time", "Datum/Zeit", "Datum/Tijd", "Datum/Tid", "data i godzina", "dato/tid", "date/heure", "zaman/saat", "Data/Ora")
MAKE_TRANSLATION(errorCode, "errorcode", "error code", "Fehlernummer", "Foutmeldingscode", "Felkod", "kod błędu", "feikode", "code erreur", "hata kodu", "codice errore")
MAKE_TRANSLATION(ibaMainDisplay, "display", "display", "Anzeige", "Display", "Display", "wyświetlacz", "skjerm", "affichage", "ekran", "Display")
MAKE_TRANSLATION(ibaLanguage, "language", "language", "Sprache", "Taal", "Sprak", "język", "språk", "langue", "dil", "Lingua")
MAKE_TRANSLATION(ibaClockOffset, "clockoffset", "clock offset", "Uhrkorrektur", "Klokcorrectie", "Tidskorrigering", "korekta zegara", "tidskorrigering", "offset horloge", "saat farkı", "correzione orario")
MAKE_TRANSLATION(ibaBuildingType, "building", "building type", "Gebäudetyp", "Type gebouw", "Byggnadstyp", "typ budynku", "bygningstype", "type bâtiment", "bina tipi", "tipo di edificio") // TODO translate
MAKE_TRANSLATION(heatingPID, "heatingpid", "heating PID", "Heizungs-PID", "PID verwarming", "Uppvärmning PID", "PID ogrzewania", "oppvarmings PID", "PID chauffage", "PID ısınıyor", "PID-riscaldamento") // TODO translate
MAKE_TRANSLATION(ibaCalIntTemperature, "intoffset", "internal temperature offset", "Korrektur interner Temperatur", "Offset interne temperatuur", "Korrigering interntemperatur", "korekta temperatury w pomieszczeniu", "Korrigering interntemperatur", "offset température interne", "iç sıcaklık artışı", "scostamento della temperatura interna") // TODO translate
MAKE_TRANSLATION(ibaMinExtTemperature, "minexttemp", "minimal external temperature", "min. Aussentemperatur", "Min. buitentemperatuur", "Min Extern Temperatur", "minimalna miejscowa temperatura zewnętrzna", "minimal eksterntemperatur", "température extérieure minimale", "en düşük sış sıcaklık", "temperatura esterna minima") // TODO translate
MAKE_TRANSLATION(ibaBuildingType, "building", "building type", "Gebäudetyp", "Type gebouw", "Byggnadstyp", "typ budynku", "bygningstype", "type bâtiment", "bina tipi", "tipo di edificio")
MAKE_TRANSLATION(heatingPID, "heatingpid", "heating PID", "Heizungs-PID", "PID verwarming", "Uppvärmning PID", "PID ogrzewania", "oppvarmings PID", "PID chauffage", "PID ısınıyor", "PID-riscaldamento")
MAKE_TRANSLATION(ibaCalIntTemperature, "intoffset", "internal temperature offset", "Korrektur interner Temperatur", "Offset interne temperatuur", "Korrigering interntemperatur", "korekta temperatury w pomieszczeniu", "Korrigering interntemperatur", "offset température interne", "iç sıcaklık artışı", "scostamento della temperatura interna")
MAKE_TRANSLATION(ibaMinExtTemperature, "minexttemp", "minimal external temperature", "min. Aussentemperatur", "Min. buitentemperatuur", "Min Extern Temperatur", "minimalna miejscowa temperatura zewnętrzna", "minimal eksterntemperatur", "température extérieure minimale", "en düşük sış sıcaklık", "temperatura esterna minima")
MAKE_TRANSLATION(backlight, "backlight", "key backlight", "Gegenlicht", "Toetsverlichting", "Bakgrundsbelysning", "podświetlenie klawiatury", "bakgrunnsbelysning", "rétroéclairage touches", "tuş takımı aydınlatması", "retroilluminazione dei tasti")
MAKE_TRANSLATION(damping, "damping", "damping outdoor temperature", "Dämpfung der Außentemperatur", "Demping buitentemperatuur", "Utomhustemperatur dämpning", "tłumienie temperatury zewnętrznej", "demping av utetemperatur", "température extérieure minimale", "dış sıcaklığın sönümlenmesi", "smorzamento della temperatura esterna")
MAKE_TRANSLATION(tempsensor1, "inttemp1", "temperature sensor 1", "Temperatursensor 1", "Temperatuursensor 1", "Temperatursensor 1", "czujnik temperatury 1", "temperatursensor 1", "sonde température 1", "sıcaklık sensörü 1", "sensore temperatura 1")
@@ -576,13 +581,13 @@ MAKE_TRANSLATION(autodst, "autodst", "automatic change daylight saving time", "a
MAKE_TRANSLATION(preheating, "preheating", "preheating in the clock program", "Vorheizen im Zeitprogramm", "Voorverwarming in het klokprogramma", "Förvärmning i tidsprogram", "podgrzewanie w programie czasowym", "forvarming i tidsprogram", "préchauffage dans programme horloge", "saat programında ön ısıtma", "preriscaldamento nel programma orologio")
MAKE_TRANSLATION(offtemp, "offtemp", "temperature when mode is off", "Temperatur bei AUS", "Temperatuur bij UIT", "Temperatur Avslagen", "temperatura w trybie \"wył.\"", "temperatur avslått", "température lorsque mode désactivé", "mod kapalı iken sıcaklık", "temperatura quando la modalità è disattivata")
MAKE_TRANSLATION(mixingvalves, "mixingvalves", "mixing valves", "Mischventile", "Mengkleppen", "Blandningsventiler", "zawory mieszające", "blandeventiler", "vannes mélange", "karışım vanaları", "valvole miscela")
MAKE_TRANSLATION(pvEnableWw, "pvenableww", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "", "abilitare aumento ACS") // TODO translate
MAKE_TRANSLATION(pvRaiseHeat, "pvraiseheat", "raise heating with PV", "Anhebung Heizen mit PV", "Verwarmen met PV activeren", "", "podwyższenie grzania z PV", "heve varmen med solpanel", "", "", "Aumentare il riscaldamento con il solare") // TODO translate
MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabsenkung mit PV", "Verlagen koeling met PV activeren", "", "obniżenie chłodzenia z PV", "nedre kjøling solpanel", "", "", "Riduzione del raffreddamento con il solare") // TODO translate
MAKE_TRANSLATION(pvEnableWw, "pvenableww", "enable raise dhw", "aktiviere Anhebung WW", "Verhoging WW activeren", "", "podwyższenie c.w.u. z PV", "aktivere hevet temperatur bereder", "", "sıcak kullanım suyu yükseltmeyi etkinleştir", "abilitare aumento ACS") // TODO translate
MAKE_TRANSLATION(pvRaiseHeat, "pvraiseheat", "raise heating with PV", "Anhebung Heizen mit PV", "Verwarmen met PV activeren", "", "podwyższenie grzania z PV", "heve varmen med solpanel", "", "ısıtmayı G.E. İle yükselt", "Aumentare il riscaldamento con il solare") // TODO translate
MAKE_TRANSLATION(pvLowerCool, "pvlowercool", "lower cooling with PV", "Kühlabsenkung mit PV", "Verlagen koeling met PV activeren", "", "obniżenie chłodzenia z PV", "nedre kjøling solpanel", "", "soğutmayı G.E. İle düşür", "Riduzione del raffreddamento con il solare") // TODO translate
// thermostat ww
MAKE_TRANSLATION(wwMode, "wwmode", "mode", "Modus", "Modus", "Läge", "tryb pracy", "modus", "mode", "mod", "modalità")
MAKE_TRANSLATION(wwSetTempLow, "wwsettemplow", "set low temperature", "untere Solltemperatur", "Onderste streeftemperatuur", "Nedre Börvärde", "zadana temperatura obniżona", "nedre settverdi", "réglage température basse", "hedef düşük sıcaklık", "imposta bassa temperatura")
MAKE_TRANSLATION(wwWhenModeOff, "wwwhenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "", "quando termostato modalita OFF")
MAKE_TRANSLATION(wwWhenModeOff, "wwwhenmodeoff", "when thermostat mode off", "bei Thermostatmodus AUS", "Als Thermostaat op UIT", "när Termostatläge är AV", "gdy wyłączono na termostacie", "når modus er av", "lorsque mode thermostat off", "termostat modu kapalı olduğunda", "quando termostato modalita OFF")
MAKE_TRANSLATION(wwExtra1, "wwextra1", "circuit 1 extra", "Kreis 1 Extra", "Circuit 1 extra", "Krets 1 Extra", "obieg dodatkowy 1", "ekstra krets 1", "circuit 1 extra", "devre 1 ekstra", "Circuito 1 extra")
MAKE_TRANSLATION(wwExtra2, "wwextra2", "circuit 2 extra", "Kreis 2 Extra", "Circuit 2 extra", "Kets 2 Extra", "obieg dodatkowy 2", "ekstra krets 2", "circuit 2 extra", "devre 2 ekstra", "Circuito 2 extra")
MAKE_TRANSLATION(wwCharge, "wwcharge", "charge", "Laden", "Laden", "Ladda", "grzanie", "lade", "charge", "doldurma", "carica")
@@ -609,14 +614,14 @@ MAKE_TRANSLATION(nighttemp, "nighttemp", "night temperature", "Nachttemperatur",
MAKE_TRANSLATION(nighttemp2, "nighttemp", "night temperature T1", "Nachttemperatur T1", "Nachttemperatuur T1", "Nattemperatur T1", "temperatura w nocy T1", "nattemperatur T1", "température nuit T1", "gece sıcaklığı T1", "temperatura notturna T1")
MAKE_TRANSLATION(ecotemp, "ecotemp", "eco temperature", "eco Temperatur", "Temperatuur eco", "Eko-temperatur", "temperatura w trybie eko", "øko temperatur", "température éco", "eko sıcaklık", "Temperatura eco")
MAKE_TRANSLATION(manualtemp, "manualtemp", "manual temperature", "manuelle Temperatur", "Temperatuur handmatig", "Temperatur Manuell", "temperatura ustawiona ręcznie", "manuell temperatur", "température manuelle", "manuel sıcaklık", "temperatura manuale")
MAKE_TRANSLATION(tempautotemp, "tempautotemp", "temporary set temperature automode", "temporäre Solltemperatur", "Streeftemperatuur automodus tijdelijk", "Temporär Aktivering av Auto-läge", "zadana temperatura w pomieszczenia w trybie \"auto\" (tymczasowa)", "temporær valgt temp i automodus", "température temporaire mode automatique", "", "impostare temporaneamente temperatura automatica")
MAKE_TRANSLATION(remoteseltemp, "remoteseltemp", "temporary set temperature from remote", "temporäre Solltemperatur Remote", "Temperatuur van afstandsbedieding", "Temperatur från fjärruppkoppling", "zadana zdalnie temperatura a pomieszczeniu (tymczasowa)", "temporær valgt temp fra fjernbetjening", "température temporaire depuis télécommande", "", "Temperatura temporanea da remoto")
MAKE_TRANSLATION(tempautotemp, "tempautotemp", "temporary set temperature automode", "temporäre Solltemperatur", "Streeftemperatuur automodus tijdelijk", "Temporär Aktivering av Auto-läge", "zadana temperatura w pomieszczenia w trybie \"auto\" (tymczasowa)", "temporær valgt temp i automodus", "température temporaire mode automatique", "geçici ayarlı sıcaklık otomatik mod", "impostare temporaneamente temperatura automatica")
MAKE_TRANSLATION(remoteseltemp, "remoteseltemp", "temporary set temperature from remote", "temporäre Solltemperatur Remote", "Temperatuur van afstandsbedieding", "Temperatur från fjärruppkoppling", "zadana zdalnie temperatura a pomieszczeniu (tymczasowa)", "temporær valgt temp fra fjernbetjening", "température temporaire depuis télécommande", "geçici ayarlı sıcaklık uzaktan", "Temperatura temporanea da remoto")
MAKE_TRANSLATION(comforttemp, "comforttemp", "comfort temperature", "Komforttemperatur", "Comforttemperatuur", "Komforttemperatur", "temperatura w trybie komfort", "komforttemperatur", "température confort", "konfor sıcaklığı", "temperatura comfort")
MAKE_TRANSLATION(summertemp, "summertemp", "summer temperature", "Sommertemperatur", "Zomertemperatuur", "Sommartemperatur", "temperatura przełączania lato/zima", "Sommertemperatur", "température été", "yaz sıcaklığı", "temperatura estiva")
MAKE_TRANSLATION(designtemp, "designtemp", "design temperature", "Auslegungstemperatur", "Ontwerptemperatuur", "Design-temperatur", "temperatura projektowa", "designtemperatur", "température conception", "", "temperatura predefinita")
MAKE_TRANSLATION(designtemp, "designtemp", "design temperature", "Auslegungstemperatur", "Ontwerptemperatuur", "Design-temperatur", "temperatura projektowa", "designtemperatur", "température conception", "özel sıcaklık", "temperatura predefinita")
MAKE_TRANSLATION(offsettemp, "offsettemp", "offset temperature", "Temperaturanhebung", "Temperatuur offset", "Temperaturkorrigering", "korekta temperatury", "temperaturkorrigering", "température offset", "artış sıcaklığı", "aumento della temperatura")
MAKE_TRANSLATION(minflowtemp, "minflowtemp", "min flow temperature", "min Vorlauftemperatur", "Minimale aanvoertemperatuur", "Min Flödestemperatur", "minimalna temperatura zasilania", "min turtemperatur", "température min flux", "minimun akış sıcaklığı", "temperatura minima di mandata") // TODO translate
MAKE_TRANSLATION(maxflowtemp, "maxflowtemp", "max flow temperature", "max Vorlauftemperatur", "Maximale aanvoertemperatuur", "Max Flödestemperatur", "maksymalna temperatura zasilania", "maks turtemperatur", "température max flux", "maksimum akış sıcaklığı", "temperatura massima di mandata") // TODO translate
MAKE_TRANSLATION(minflowtemp, "minflowtemp", "min flow temperature", "min Vorlauftemperatur", "Minimale aanvoertemperatuur", "Min Flödestemperatur", "minimalna temperatura zasilania", "min turtemperatur", "température min flux", "minimun akış sıcaklığı", "temperatura minima di mandata")
MAKE_TRANSLATION(maxflowtemp, "maxflowtemp", "max flow temperature", "max Vorlauftemperatur", "Maximale aanvoertemperatuur", "Max Flödestemperatur", "maksymalna temperatura zasilania", "maks turtemperatur", "température max flux", "maksimum akış sıcaklığı", "temperatura massima di mandata")
MAKE_TRANSLATION(roominfluence, "roominfluence", "room influence", "Raumeinfluss", "Ruimteinvloed", "Rumspåverkan", "wpływ pomieszczenia", "rominnflytelse", "influence pièce", "oda etkisi", "influenza della camera")
MAKE_TRANSLATION(roominfl_factor, "roominflfactor", "room influence factor", "Raumeinflussfaktor", "Factor ruimteinvloed", "Rumspåverkansfaktor", "współczynnik wpływu pomieszczenia", "rominnflytelsesfaktor", "facteur d'influence pièce", "oda etkisi faktörü", "fattore influenza camera")
MAKE_TRANSLATION(curroominfl, "curroominfl", "current room influence", "aktueller Raumeinfluss", "Huidige ruimteinvloed", "Aktuell Rumspåverkan", "aktualny wpływ pomieszczenia", "gjeldende rominnflytelse", "influence actuelle pièce", "güncel oda etkisi", "fattore corrente influenza camera")
@@ -635,28 +640,29 @@ MAKE_TRANSLATION(party, "party", "party time", "Partyzeit", "Partytijd", "Partyt
MAKE_TRANSLATION(holidaytemp, "holidaytemp", "holiday temperature", "Urlaubstemperatur", "Vakantietemperatuur", "Helgtemperatur", "temperatura w trybie urlopowym", "ferietemperatur", "température vacances", "tatil sıcaklığı", "temperatura festiva")
MAKE_TRANSLATION(summermode, "summermode", "summer mode", "Sommerbetrieb", "Zomerbedrijf", "Sommarläge", "aktualny tryb lato/zima", "sommermodus", "mode été", "yaz modu", "funzionamento estivo")
MAKE_TRANSLATION(holidaymode, "holidaymode", "holiday mode", "Urlaubsbetrieb", "Vakantiebedrijf", "Helgläge", "tryb urlopowy", "feriemodus", "mode vacances", "tatil modu", "modalita vacanze")
MAKE_TRANSLATION(flowtempoffset, "flowtempoffset", "flow temperature offset for mixer", "Vorlauftemperaturanhebung", "Mixer aanvoertemperatuur offset", "Temperaturkorrigering Flödestemp. Blandningsventil", "korekta temperatury przepływu dla miksera", "temperaturkorrigering av blandingsventil", "décalage température de bascule pour mélangeur", "", "aumento della temperatura di ritorno")
MAKE_TRANSLATION(reducemode, "reducemode", "reduce mode", "Absenkmodus", "Gereduceerde modus", "Reducerat Läge", "tryb zredukowany/obniżony", "redusert modus", "mode réduction", "", "modalità assente")
MAKE_TRANSLATION(noreducetemp, "noreducetemp", "no reduce below temperature", "Durchheizen unter", "Reduceermodus onderbreken onder", "Inaktivera reducering under", "bez redukcji poniżej temperatury", "inaktiver redusert nedre temp", "pas de réduction en dessous température", "", "non ridurre temperatura sotto")
MAKE_TRANSLATION(reducetemp, "reducetemp", "off/reduce switch temperature", "Absenkmodus unter", "Onderste afschakeltemperatuur", "Avslag/Reducera under", "tryb zredukowany poniżej temperatury", "nedre avstengningstemperatur", "arrêt/réduction température bascule", "", "interruttore riduzione temperatura")
MAKE_TRANSLATION(vacreducetemp, "vacreducetemp", "vacations off/reduce switch temperature", "Urlaub Absenkmodus unter", "Vakantiemodus onderste afschakeltemperatuur", "Helg Avslag/Reducering under", "tryb urlopowy poniżej temperatury", "feriemodus nedre utkoblingstemperatur", "vacances arrêt/réduction température bascule", "", "interruttore riduzione temperatura vacanze")
MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlaub Absenkmodus", "Vakantie afschakelmodus", "Helg reduceringsläge", "redukcja w trakcie urlopu", "ferieavstengningsmodus", "mode réduction vacances", "", "modalita riduzione vacanze")
MAKE_TRANSLATION(flowtempoffset, "flowtempoffset", "flow temperature offset for mixer", "Vorlauftemperaturanhebung", "Mixer aanvoertemperatuur offset", "Temperaturkorrigering Flödestemp. Blandningsventil", "korekta temperatury przepływu dla miksera", "temperaturkorrigering av blandingsventil", "décalage température de bascule pour mélangeur", "karıştırıcı için akış sıcaklığı farkı", "aumento della temperatura di ritorno")
MAKE_TRANSLATION(reducemode, "reducemode", "reduce mode", "Absenkmodus", "Gereduceerde modus", "Reducerat Läge", "tryb zredukowany/obniżony", "redusert modus", "mode réduction", "düşürme modu", "modalità assente")
MAKE_TRANSLATION(noreducetemp, "noreducetemp", "no reduce below temperature", "Durchheizen unter", "Reduceermodus onderbreken onder", "Inaktivera reducering under", "bez redukcji poniżej temperatury", "inaktiver redusert nedre temp", "pas de réduction en dessous température", "bu sıcaklığın altına düşürme", "non ridurre temperatura sotto")
MAKE_TRANSLATION(reducetemp, "reducetemp", "off/reduce switch temperature", "Absenkmodus unter", "Onderste afschakeltemperatuur", "Avslag/Reducera under", "tryb zredukowany poniżej temperatury", "nedre avstengningstemperatur", "arrêt/réduction température bascule", "sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura")
MAKE_TRANSLATION(vacreducetemp, "vacreducetemp", "vacations off/reduce switch temperature", "Urlaub Absenkmodus unter", "Vakantiemodus onderste afschakeltemperatuur", "Helg Avslag/Reducering under", "tryb urlopowy poniżej temperatury", "feriemodus nedre utkoblingstemperatur", "vacances arrêt/réduction température bascule", "tatil sıcaklık kapama/düşürme modu", "interruttore riduzione temperatura vacanze")
MAKE_TRANSLATION(vacreducemode, "vacreducemode", "vacations reduce mode", "Urlaub Absenkmodus", "Vakantie afschakelmodus", "Helg reduceringsläge", "redukcja w trakcie urlopu", "ferieavstengningsmodus", "mode réduction vacances", "tail düşürme modu", "modalita riduzione vacanze")
MAKE_TRANSLATION(nofrostmode, "nofrostmode", "nofrost mode", "Frostschutz Modus", "Vorstbeveiligingsmodus", "Frostskyddsläge", "temperatura wiodąca dla ochrony przed zamarzaniem", "frostbeskyttelsesmodus", "mode protection gel", "donma koruması modu", "Modalità protezione antigelo")
MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "", "temperatura ambiente da remoto")
MAKE_TRANSLATION(remotetemp, "remotetemp", "room temperature from remote", "Raumtemperatur Remote", "Ruimtetemperatuur van afstandsbediening", "Rumstemperatur från fjärr", "temperatura w pomieszczeniu (z termostatu)", "romstemperatur fra fjernbetjening", "température pièce depuis télécommande", "uzaktan oda sıcaklığı", "temperatura ambiente da remoto")
MAKE_TRANSLATION(remotehum, "remotehum", "room humidity from remote", "Raumfeuchte Remote", "", "", "", "", "", "uzaktan kumandadan oda nemi", "") // TODO translate
MAKE_TRANSLATION(wwHolidays, "wwholidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdagar", "dni świąteczne", "feriedager varmtvann", "dates vacances", "tatil günleri", "feste pubbliche")
MAKE_TRANSLATION(wwVacations, "wwvacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum Varmvatten", "dni urlopowe", "ferie dato varmtvann", "dates vacances", "izin günleri", "date vacanze")
MAKE_TRANSLATION(holidays, "holidays", "holiday dates", "Feiertage", "Feestdagen", "Helgdatum", "święta", "helligdager", "dates vacances", "tatil günleri", "date feste pubbliche")
MAKE_TRANSLATION(vacations, "vacations", "vacation dates", "Urlaubstage", "Vakantiedagen", "Semesterdatum", "urlop", "feriedager", "dates vacances", "izin günleri", "date vacanze")
MAKE_TRANSLATION(wwprio, "wwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "", "priorita acqua calda ")
MAKE_TRANSLATION(wwprio, "wwprio", "dhw priority", "WW-Vorrang", "Prioriteit warm water", "Prioritera Varmvatten", "priorytet dla c.w.u.", "prioroter varmtvann", "priorité ecs", "sıcak kullanım suyu önceliği", "priorita acqua calda ")
MAKE_TRANSLATION(nofrostmode1, "nofrostmode1", "nofrost mode", "Frostschutz", "Vorstbeveiligingsmodus", "Frostskyddsläge", "ochrona przed zamarzaniem", "frostbeskyttelse", "mode protection gel", "donma koruması modu 1", "modalita protezione antigelo")
MAKE_TRANSLATION(reducehours, "reducehours", "duration for nighttemp", "Dauer Nachttemp.", "Duur nachtverlaging", "Timmar Nattsänkning", "czas trwania trybu nocnego", "timer nattsenkning", "durée température nuit", "gece sıcaklığı süresi", "durata temperatura notturna")
MAKE_TRANSLATION(reduceminutes, "reduceminutes", "remaining time for nightmode", "Restzeit Nachttemp.", "Resterende tijd nachtverlaging", "Återstående Tid Nattläge", "czas do końca trybu nocnego", "gjenværende tid i nattstilling", "temps restant mode nuit", "gece modu için kalan süre", "temperatura notturna residua")
MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "", "ottimizzazione all'accensione")
MAKE_TRANSLATION(switchonoptimization, "switchonoptimization", "switch-on optimization", "Einschaltoptimierung", "Inschakeloptimalisering", "Växlingsoptimering", "optymalizacja załączania", "slå på optimalisering", "optimisation mise en marche", "optimizasyonu aç", "ottimizzazione all'accensione")
MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "", "", "", "", "Modalità Termopompa")
MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "", "", "", "", "differenza del punto di rugiada")
MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "", "", "", "", "differenza temperatura ambiente")
MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "", "", "", "", "temperatura minima di mandata")
MAKE_TRANSLATION(hpmode, "hpmode", "HP Mode", "WP Modus", "Modus warmtepomp", "", "", "", "", "yüksek güç modu", "Modalità Termopompa") // TODO translate
MAKE_TRANSLATION(dewoffset, "dewoffset", "dew point offset", "Taupunkt Differenz", "Offset dauwpunt", "", "", "", "", "çiğ noktası göreli", "differenza del punto di rugiada") // TODO translate
MAKE_TRANSLATION(roomtempdiff, "roomtempdiff", "room temp difference", "Raumtemperatur Differenz", "Verschiltemperatuur kamertemp", "", "", "", "", "oda sıcaklığı farkı", "differenza temperatura ambiente") // TODO translate
MAKE_TRANSLATION(hpminflowtemp, "hpminflowtemp", "HP min. flow temp.", "WP minimale Vorlauftemperatur", "Minimale aanvoertemperatuur WP", "", "", "", "", "yüksek güç minimum akış sıcaklığı", "temperatura minima di mandata") // TODO translate
MAKE_TRANSLATION(hpcooling, "cooling", "cooling", "Kühlen", "Koelen", "Kyler", "chłodzenie", "kjøling", "refroidissement", "soğuma", "raffreddamento")
// heatpump
@@ -682,22 +688,22 @@ MAKE_TRANSLATION(poolShunt, "poolshunt", "pool shunt open/close (0% = pool / 100
MAKE_TRANSLATION(hydrTemp, "hydrTemp", "hydraulic header temperature", "Verteilertemperatur", "Temperatuur open verdeler", "Fördelartemperatur", "temperatura kolektora hydraulicznego", "Fordelertemperatur", "température collecteur hydraulique", "hidrolik başlık sıcaklığı ", "temperatura del collettore")
// solar
MAKE_TRANSLATION(cylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte (TS3)", "Zonneboilertemperatuur midden (TS3)", "Cylindertemperatur Mitten (TS3)", "temperatura w środku zasobnika (TS3)", "beredertemperatur i midten (TS3)", "température moyenne cylindre (TS3)", "", "temperatura di conservazione media accumulo (TS3)")
MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "", "temperatura ritorno scambiatore (TS4)")
MAKE_TRANSLATION(m1Valve, "heatassistvalve", "heat assistance valve (M1)", "Ventil Heizungsunterstützung (M1)", "Klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil (M1)", "zawór wspomagania grzania (M1)", "varmehjelpsventil (M1)", "vanne assistance thermique (M1)", "", "valvola scambiatore (M1)")
MAKE_TRANSLATION(m1Power, "heatassistpower", "heat assistance valve power (M1)", "Ventilleistung Heizungsunterstützung (M1)", "Vermogen klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil Effekt (M1)", "moc zaworu wspomagania grzania (M1)", "varmehjelpsventileffekt (M1)", "puissance vanne assistance thermique (M1)", "", "potenza valvola scambiatore (M1)")
MAKE_TRANSLATION(cylMiddleTemp, "cylmiddletemp", "cylinder middle temperature (TS3)", "Speichertemperatur Mitte (TS3)", "Zonneboilertemperatuur midden (TS3)", "Cylindertemperatur Mitten (TS3)", "temperatura w środku zasobnika (TS3)", "beredertemperatur i midten (TS3)", "température moyenne cylindre (TS3)", "orta depolama sıcaklığı (TS3)", "temperatura di conservazione media accumulo (TS3)")
MAKE_TRANSLATION(retHeatAssist, "retheatassist", "return temperature heat assistance (TS4)", "Rücklaufanhebungs-Temp. (TS4)", "Retourtemperatuur verwarmingsassistentie (TS4)", "Returtemperatur värmestöd (TS4)", "temperatura powrotu wspomagania grzania (TS4)", "returtemperatur varmestøtte (TS4)", "température retour de assistance thermique (TS4)", "geri dönüş sıcaklığı artışı", "temperatura ritorno scambiatore (TS4)")
MAKE_TRANSLATION(m1Valve, "heatassistvalve", "heat assistance valve (M1)", "Ventil Heizungsunterstützung (M1)", "Klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil (M1)", "zawór wspomagania grzania (M1)", "varmehjelpsventil (M1)", "vanne assistance thermique (M1)", "ısıtma yardım vanası (M1)", "valvola scambiatore (M1)")
MAKE_TRANSLATION(m1Power, "heatassistpower", "heat assistance valve power (M1)", "Ventilleistung Heizungsunterstützung (M1)", "Vermogen klep verwarmingsassistentie (M1)", "Uppvärmningsstöd Ventil Effekt (M1)", "moc zaworu wspomagania grzania (M1)", "varmehjelpsventileffekt (M1)", "puissance vanne assistance thermique (M1)", "ısıtma yardım vanası gücü (M1)", "potenza valvola scambiatore (M1)")
MAKE_TRANSLATION(pumpMinMod, "pumpminmod", "minimum pump modulation", "minimale Pumpenmodulation", "Minimale pompmodulatie", "Min Pumpmodulering", "minimalna modulacja pompy", "minimum pumpmodulering", "modulation minimale pompe", "minimum pompa modülasyonu", "modulazione minima pompa")
MAKE_TRANSLATION(maxFlow, "maxflow", "maximum solar flow", "maximaler Durchfluss", "Maximale doorstroom solar", "Max Flöde Solpanel", "maksymalny przepływ solarów", "maks strømming solpanel ", "débit solaire maximum", "minimum güneş akışı", "portata massima solare")
MAKE_TRANSLATION(solarPower, "solarpower", "actual solar power", "aktuelle Solarleistung", "Huidig solar vermogen", "Aktuellt Sol-effekt", "aktualna moc solarów", "aktuell soleffekt", "puissance solaire réelle", "gerçek güneş gücü", "potenza attuale solare")
MAKE_TRANSLATION(solarPumpTurnonDiff, "turnondiff", "pump turn on difference", "Einschalthysterese Pumpe", "Inschakelhysterese pomp", "Aktiveringshysteres Pump", "histereza załączenia pompy", "slå på hysteresepumpe", "différence activation pompe", "", "isteresi di accensione pompa")
MAKE_TRANSLATION(solarPumpTurnoffDiff, "turnoffdiff", "pump turn off difference", "Ausschalthysterese Pumpe", "Uitschakelhysterese pomp", "Avslagshysteres Pump", "histereza włączenia pompy", "slå av hysteresepumpe", "différence arrêt pompe", "", "isteresi di spegnimento pompa")
MAKE_TRANSLATION(maxFlow, "maxflow", "maximum solar flow", "maximaler Durchfluss", "Maximale doorstroom solar", "Max Flöde Solpanel", "maksymalny przepływ solarów", "maks strømming solpanel ", "débit solaire maximum", "minimum G.E. akışı", "portata massima solare")
MAKE_TRANSLATION(solarPower, "solarpower", "actual solar power", "aktuelle Solarleistung", "Huidig solar vermogen", "Aktuellt Sol-effekt", "aktualna moc solarów", "aktuell soleffekt", "puissance solaire réelle", "gerçek G.E. gücü", "potenza attuale solare")
MAKE_TRANSLATION(solarPumpTurnonDiff, "turnondiff", "pump turn on difference", "Einschalthysterese Pumpe", "Inschakelhysterese pomp", "Aktiveringshysteres Pump", "histereza załączenia pompy", "slå på hysteresepumpe", "différence activation pompe", "pompa devreye alma farkı", "isteresi di accensione pompa")
MAKE_TRANSLATION(solarPumpTurnoffDiff, "turnoffdiff", "pump turn off difference", "Ausschalthysterese Pumpe", "Uitschakelhysterese pomp", "Avslagshysteres Pump", "histereza włączenia pompy", "slå av hysteresepumpe", "différence arrêt pompe", "pompa kapama farkı", "isteresi di spegnimento pompa")
MAKE_TRANSLATION(pump2MinMod, "pump2minmod", "minimum pump 2 modulation", "minimale Modulation Pumpe 2", "Minimale modulatie pomp 2", "Min Modulering Pump 2", "minimalna modulacja pompy 2", "minimum pumpmodulering 2", "modulation minimale pompe 2", "minimum pompa 2 modülasyonu", "modulazione minima pompa 2")
MAKE_TRANSLATION(solarPump2TurnonDiff, "turnondiff2", "pump 2 turn on difference", "Einschalthysterese Pumpe 2", "Inschakelhysterese pomp 2", "Aktiveringshysteres Pump 2", "histereza załączenia pompy 2", "slå på hysteresepumpe 2", "différence activation pompe 2", "", "isteresi di accensione pompa 2")
MAKE_TRANSLATION(solarPump2TurnoffDiff, "turnoffdiff2", "pump 2 turn off difference", "Ausschalthysterese Pumpe 2", "Uitschakelhysterese pomp 2", "Avslagshysteres Pump 2", "histereza wyłączenia pompy 2", "slå av hysteresepumpe 2", "différence arrêt pompe 2", "", "isteresi di spegnimento pompa")
MAKE_TRANSLATION(solarPump2TurnonDiff, "turnondiff2", "pump 2 turn on difference", "Einschalthysterese Pumpe 2", "Inschakelhysterese pomp 2", "Aktiveringshysteres Pump 2", "histereza załączenia pompy 2", "slå på hysteresepumpe 2", "différence activation pompe 2", "pompa 2 devreye alma farkı", "isteresi di accensione pompa 2")
MAKE_TRANSLATION(solarPump2TurnoffDiff, "turnoffdiff2", "pump 2 turn off difference", "Ausschalthysterese Pumpe 2", "Uitschakelhysterese pomp 2", "Avslagshysteres Pump 2", "histereza wyłączenia pompy 2", "slå av hysteresepumpe 2", "différence arrêt pompe 2", "pompa 2 kapama farkı", "isteresi di spegnimento pompa")
MAKE_TRANSLATION(collectorTemp, "collectortemp", "collector temperature (TS1)", "Kollektortemperatur (TS1)", "Collectortemperatuur (TS1)", "Kollektor Temperatur (TS1)", "temperatura kolektora (TS1)", "kollektor temperatur (TS1)", "température collecteur (TS1)", "kollektör sıcaklığı (TS1)", "temperatura collettore (TS1)")
MAKE_TRANSLATION(collector2Temp, "collector2temp", "collector 2 temperature (TS7)", "Kollector 2 Temperatur (TS7)", "Collector 2 temperatuur (TS7)", "Kollektor 2 Temperatur (TS7)", "temperatura kolektora 2 (TS7)", "kollektor 2 temperatur (TS7)", "température collecteur 2 (TS7)", "kollektör 2 sıcaklığı (TS2)", "temperatura collettore 2 (TS7)")
MAKE_TRANSLATION(cylBottomTemp, "cylbottomtemp", "cylinder bottom temperature (TS2)", "Speicher Bodentemperatur (TS2)", "Bodemtemperatuur zonneboiler (TS2)", "Cylindertemperatur Botten (TS2)", "temperatura na spodzie zasobnika (TS2)", "beredertemp i bunn (TS2)", "température fond de cylindre (TS2)", "", "temperatura inferiore accumulo (TS2)")
MAKE_TRANSLATION(cyl2BottomTemp, "cyl2bottomtemp", "second cylinder bottom temperature (TS5)", "2. Speicher Bodentemperatur (TS5)", "Bodemtemperatuur 2e boiler", "Sekundär Cylindertemperatur Botten (TS5)", "temperatura na spodzie drugiego zasobnika (TS5)", "skundær beredertemp i bunn (TS5)", "température fond de cylindre (TS5)", "", "temperatura inferiore 2° accumulo (TS5)")
MAKE_TRANSLATION(cylBottomTemp, "cylbottomtemp", "cylinder bottom temperature (TS2)", "Speicher Bodentemperatur (TS2)", "Bodemtemperatuur zonneboiler (TS2)", "Cylindertemperatur Botten (TS2)", "temperatura na spodzie zasobnika (TS2)", "beredertemp i bunn (TS2)", "température fond de cylindre (TS2)", "alt depolama sıcaklığıc(TS2)", "temperatura inferiore accumulo (TS2)")
MAKE_TRANSLATION(cyl2BottomTemp, "cyl2bottomtemp", "second cylinder bottom temperature (TS5)", "2. Speicher Bodentemperatur (TS5)", "Bodemtemperatuur 2e boiler", "Sekundär Cylindertemperatur Botten (TS5)", "temperatura na spodzie drugiego zasobnika (TS5)", "skundær beredertemp i bunn (TS5)", "température fond de cylindre (TS5)", "ikinci alt depolama sıcaklığıc(TS5)", "temperatura inferiore 2° accumulo (TS5)")
MAKE_TRANSLATION(heatExchangerTemp, "heatexchangertemp", "heat exchanger temperature (TS6)", "wärmetauscher Temperatur (TS6)", "Temperatuur warmtewisselaar (TS6)", "Värmeväxlare Temperatur (TS6)", "temperatura wymiennika ciepła (TS6)", "Varmeveksler temperatur (TS6)", "température échangeur de chaleur (TS6)", "eşanjör sıcaklığı (TS6)", "temperatura scambiatore calore (TS6)")
MAKE_TRANSLATION(collectorMaxTemp, "collectormaxtemp", "maximum collector temperature", "maximale Kollektortemperatur", "Maximale collectortemperatuur", "Max Kollektortemperatur", "maksymalna temperatura kolektora", "maks kollektortemperatur", "température max. collecteur", "maksimum kollektör sıcaklığı", " temperatura massima scambiatore calore")
MAKE_TRANSLATION(collectorMinTemp, "collectormintemp", "minimum collector temperature", "minimale Kollektortemperatur", "Minimale collectortemperatuur", "Min Kollektortemperatur", "minimalna temperatura kolektora", "min kollektortemperatur", "température min. collecteur", "minimum kollektör sıcaklığı", "temperatura minima scambiatore calore")
@@ -709,11 +715,11 @@ MAKE_TRANSLATION(solarPump2, "solarpump2", "pump 2 (PS4)", "Pumpe 2 (PS4)", "Pom
MAKE_TRANSLATION(solarPump2Mod, "solarpump2mod", "pump 2 modulation (PS4)", "Pumpe 2 Modulation (PS4)", "Modulatie pomp 2 (PS4)", "Pump 2 Modulering (PS4)", "modulacja pompy solarnej 2 (PS4)", "solpumpe2modulering (PS4)", "modulation pompe solaire 2 (PS4)", "pompa2 modülasyonu(PS1)", "pompa modulazione 2 (PS4)")
MAKE_TRANSLATION(valveStatus, "valvestatus", "valve status", "Ventilstatus", "Klepstatus", "Ventilstatus", "stan zaworu", "ventilstatus", "statut valve", "vana durumu", "stato valvola")
MAKE_TRANSLATION(vs1Status, "vs1status", "valve status VS1", "Ventilstatus VS1", "Klepstatus VS1", "Ventilstatus VS1", "stan zaworu VS1", "ventilstatus VS1", "statut valve VS1", "vana durumu VS1", "stato valvola VS1")
MAKE_TRANSLATION(cylHeated, "cylheated", "cyl heated", "Speichertemperatur erreicht", "Boilertemperatuur behaald", "Värmepanna Uppvärmd", "zasobnik został nagrzany", "bereder oppvarmt", "cylindre chauffé", "", "temperatura richiesta vaso accumulo raggiunta")
MAKE_TRANSLATION(cylHeated, "cylheated", "cyl heated", "Speichertemperatur erreicht", "Boilertemperatuur behaald", "Värmepanna Uppvärmd", "zasobnik został nagrzany", "bereder oppvarmt", "cylindre chauffé", "depolama sıcakllığına ulaşıldı", "temperatura richiesta vaso accumulo raggiunta")
MAKE_TRANSLATION(collectorShutdown, "collectorshutdown", "collector shutdown", "Kollektorabschaltung", "Collector afschakeling", "Kollektor Avstängning", "wyłączenie kolektora", "kollektor stengt", "arrêt collecteur", "kollektör kapalı", "spegnimento del collettore")
MAKE_TRANSLATION(pumpWorkTime, "pumpworktime", "pump working time", "Pumpenlaufzeit", "Pomplooptijd", "Pump Drifttid", "czas pracy pompy", "driftstid pumpe", "durée fonctionnement pompe", "pompa çalışma süresi", "tempo funzionamento pompa")
MAKE_TRANSLATION(pump2WorkTime, "pump2worktime", "pump 2 working time", "Pumpe 2 Laufzeit", "Looptijd pomp 2", "Pump 2 Drifttid", "czas pracy pompy 2", "driftstid pumpe2", "durée fonctionnement pompe 2", "pompa 2 çalışma süresi", "tempo funzionamento pompa 2")
MAKE_TRANSLATION(m1WorkTime, "m1worktime", "differential control working time", "Differenzregelung Arbeitszeit", "Verschilregeling arbeidstijd", "Differentialreglering Drifttid", "czas pracy regulacji różnicowej", "differentialreguleringssrifttid", "durée fonctionnement contrôle différentiel", "", "controllo differenziale durata funzionamento")
MAKE_TRANSLATION(m1WorkTime, "m1worktime", "differential control working time", "Differenzregelung Arbeitszeit", "Verschilregeling arbeidstijd", "Differentialreglering Drifttid", "czas pracy regulacji różnicowej", "differentialreguleringssrifttid", "durée fonctionnement contrôle différentiel", "çalışma saatlerinin farklı düzenlenmesi", "controllo differenziale durata funzionamento")
MAKE_TRANSLATION(energyLastHour, "energylasthour", "energy last hour", "Energie letzte Std", "Energie laatste uur", "Energi Senaste Timmen", "energia w ciągu ostatniej godziny", "energi siste time", "énergie dernière heure", "son saat enerji", "Eenergia ultima ora")
MAKE_TRANSLATION(energyTotal, "energytotal", "total energy", "Gesamtenergie", "Totale energie", "Total Energi", "energia całkowita", "total energi", "énergie totale", "toplam enerji", "energia totale")
MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heute", "Energie vandaag", "Total Energi Idag", "energia całkowita dzisiaj", "total energi i dag", "énergie totale aujourd'hui", "bugün toplam enerji", "totale energia giornaliera")

View File

@@ -594,12 +594,20 @@ bool Mqtt::queue_message(const uint8_t operation, const std::string & topic, con
}
// check free mem
#ifndef EMSESP_STANDALONE
if (ESP.getFreeHeap() < 60 * 1204) {
if (ESP.getFreeHeap() < 60 * 1204 || ESP.getMaxAllocHeap() < 40 * 1024) {
if (operation == Operation::PUBLISH) {
mqtt_message_id_++;
mqtt_publish_fails_++;
}
LOG_DEBUG("%s failed: low memory", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe");
LOG_WARNING("%s failed: low memory", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe");
return false; // quit
}
if (queuecount_ >= MQTT_QUEUE_MAX_SIZE) {
if (operation == Operation::PUBLISH) {
mqtt_message_id_++;
mqtt_publish_fails_++;
}
LOG_WARNING("%s failed: queue full", operation == Operation::PUBLISH ? "Publish" : operation == Operation::SUBSCRIBE ? "Subscribe" : "Unsubscribe");
return false; // quit
}
#endif
@@ -737,7 +745,7 @@ bool Mqtt::publish_ha_sensor_config(DeviceValue & dv, const char * model, const
// calculate the min and max
int16_t dv_set_min;
uint16_t dv_set_max;
uint32_t 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
@@ -788,7 +796,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
const char * const ** options,
uint8_t options_size,
const int16_t dv_set_min,
const int16_t dv_set_max,
const uint32_t dv_set_max,
const int8_t num_op,
const JsonObject & dev_json) {
// ignore if name (fullname) is empty
@@ -847,7 +855,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
case DeviceValueType::UINT:
case DeviceValueType::SHORT:
case DeviceValueType::USHORT:
case DeviceValueType::ULONG:
// case DeviceValueType::ULONG:
if (discovery_type() == discoveryType::HOMEASSISTANT) {
// Home Assistant
// number - https://www.home-assistant.io/integrations/number.mqtt
@@ -866,6 +874,10 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
// select - https://www.home-assistant.io/integrations/select.mqtt
snprintf(topic, sizeof(topic), "select/%s", config_topic);
break;
case DeviceValueType::ULONG:
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
set_ha_classes = true;
break;
default:
// plain old sensor
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
@@ -1127,7 +1139,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
return queue_ha(topic, doc.as<JsonObject>());
}
bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint16_t max) {
bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) {
uint8_t hc_num = tag - DeviceValueTAG::TAG_HC1 + 1;
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];

View File

@@ -55,7 +55,8 @@ class Mqtt {
enum Operation : uint8_t { PUBLISH, SUBSCRIBE, UNSUBSCRIBE };
enum NestedFormat : uint8_t { NESTED = 1, SINGLE };
static constexpr uint8_t MQTT_TOPIC_MAX_SIZE = 128; // fixed, not a user setting anymore
static constexpr uint8_t MQTT_TOPIC_MAX_SIZE = 128; // fixed, not a user setting anymore
static constexpr uint16_t MQTT_QUEUE_MAX_SIZE = 300;
static void on_connect();
static void on_disconnect(espMqttClientTypes::DisconnectReason reason);
@@ -87,12 +88,12 @@ class Mqtt {
const char * const ** options,
uint8_t options_size,
const int16_t dv_set_min,
const int16_t dv_set_max,
const uint32_t dv_set_max,
const int8_t num_op,
const JsonObject & dev_json);
static bool publish_system_ha_sensor_config(uint8_t type, const char * name, const char * entity, const uint8_t uom);
static bool publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint16_t max = 30);
static bool publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove = false, const int16_t min = 5, const uint32_t max = 30);
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
static void show_mqtt(uuid::console::Shell & shell);

View File

@@ -231,9 +231,15 @@ bool System::command_watch(const char * value, const int8_t id) {
return false;
}
void System::store_nvs_values() {
Command::call(EMSdevice::DeviceType::BOILER, "nompower", "-1"); // trigger a write
EMSESP::analogsensor_.store_counters();
}
// restart EMS-ESP
void System::system_restart() {
LOG_INFO("Restarting EMS-ESP...");
store_nvs_values();
Shell::loop_all();
delay(1000); // wait a second
#ifndef EMSESP_STANDALONE

View File

@@ -66,6 +66,7 @@ class System {
std::string reset_reason(uint8_t cpu) const;
void store_nvs_values();
void system_restart();
void format(uuid::console::Shell & shell);
void upload_status(bool in_progress);

View File

@@ -360,10 +360,10 @@ bool TemperatureSensor::command_commands(const char * value, const int8_t id, Js
}
// creates JSON doc from values
// returns false if there are no sensors
// returns true if there are no sensors
bool TemperatureSensor::command_info(const char * value, const int8_t id, JsonObject & output) {
if (sensors_.empty()) {
return false;
return true;
}
for (const auto & sensor : sensors_) {
@@ -389,7 +389,7 @@ bool TemperatureSensor::command_info(const char * value, const int8_t id, JsonOb
// called from emsesp.cpp, similar to the emsdevice->get_value_info
bool TemperatureSensor::get_value_info(JsonObject & output, const char * cmd, const int8_t id) {
if (sensors_.empty()) {
return false;
return true;
}
// make a copy of the string command for parsing
char command_s[30];
@@ -576,7 +576,7 @@ TemperatureSensor::Sensor::Sensor(const uint8_t addr[])
(unsigned int)(internal_id_ >> 48) & 0xFF,
(unsigned int)(internal_id_ >> 32) & 0xFFFF,
(unsigned int)(internal_id_ >> 16) & 0xFFFF,
(unsigned int)(internal_id_) & 0xFFFF);
(unsigned int)(internal_id_)&0xFFFF);
id_ = std::string(id_s);
name_ = std::string{}; // name (alias) is empty
offset_ = 0; // 0 degrees offset

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.6.2-dev.1"
#define EMSESP_APP_VERSION "3.6.2-dev.2"

View File

@@ -127,11 +127,6 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject & input) {
}
emsesp::EMSESP::logger().err(error);
api_fails_++;
} else {
// if there was no json output from the call, default to the output message 'OK'.
if (!output.size()) {
output["message"] = "OK";
}
}
// if we're returning single values, just sent as plain text

View File

@@ -239,24 +239,20 @@ void WebCustomEntityService::render_value(JsonObject & output, CustomEntityItem
// process json output for info/commands and value_info
bool WebCustomEntityService::get_value_info(JsonObject & output, const char * cmd) {
EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; });
// if no entries, return a message instead of an error
// https://github.com/emsesp/EMS-ESP32/issues/1297
if (customEntityItems->size() == 0) {
output["message"] = "no entries";
return true;
}
if (Helpers::toLower(cmd) == "commands") {
output["info"] = "list all values";
output["commands"] = "list all commands";
if (Helpers::toLower(cmd) == F_(commands)) {
output[F_(info)] = Helpers::translated_word(FL_(info_cmd));
output[F_(commands)] = Helpers::translated_word(FL_(commands_cmd));
for (const auto & entity : *customEntityItems) {
output[entity.name] = "custom entitiy";
}
return true;
}
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == "values" || Helpers::toLower(cmd) == "info") {
// if no entries, return empty json
// https://github.com/emsesp/EMS-ESP32/issues/1297
if (customEntityItems->size() == 0) {
return true;
}
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == F_(values) || Helpers::toLower(cmd) == F_(info)) {
// list all names
for (const CustomEntityItem & entity : *customEntityItems) {
render_value(output, entity);
@@ -298,11 +294,13 @@ bool WebCustomEntityService::get_value_info(JsonObject & output, const char * cm
JsonVariant data = output[attribute_s];
output.clear();
output["api_data"] = data;
return true;
} else {
char error[100];
snprintf(error, sizeof(error), "cannot find attribute %s in entity %s", attribute_s, command_s);
output.clear();
output["message"] = error;
return false;
}
}
}

View File

@@ -251,7 +251,7 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar
return_code = Command::call(device_type, cmd, data.as<const char *>(), true, id, output);
} else if (data.is<int>()) {
char s[10];
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int16_t>(), 0), true, id, output);
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int>(), 0), true, id, output);
} else if (data.is<float>()) {
char s[10];
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<float>(), 1), true, id, output);
@@ -288,7 +288,7 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar
return_code = Command::call(device_type, cmd, data.as<const char *>(), true, id, output);
} else if (data.is<int>()) {
char s[10];
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int16_t>(), 0), true, id, output);
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<int>(), 0), true, id, output);
} else if (data.is<float>()) {
char s[10];
return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as<float>(), 1), true, id, output);

View File

@@ -133,12 +133,9 @@ bool WebSchedulerService::command_setvalue(const char * value, const std::string
// process json output for info/commands and value_info
bool WebSchedulerService::get_value_info(JsonObject & output, const char * cmd) {
EMSESP::webSchedulerService.read([&](WebScheduler & webScheduler) { scheduleItems = &webScheduler.scheduleItems; });
if (scheduleItems->size() == 0) {
return false;
}
if (Helpers::toLower(cmd) == "commands") {
output["info"] = "lists all values";
output["commands"] = "lists all commands";
if (Helpers::toLower(cmd) == F_(commands)) {
output[F_(info)] = Helpers::translated_word(FL_(info_cmd));
output[F_(commands)] = Helpers::translated_word(FL_(commands_cmd));
for (const ScheduleItem & scheduleItem : *scheduleItems) {
if (!scheduleItem.name.empty()) {
output[scheduleItem.name] = "activate schedule";
@@ -146,7 +143,10 @@ bool WebSchedulerService::get_value_info(JsonObject & output, const char * cmd)
}
return true;
}
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == "values" || Helpers::toLower(cmd) == "info") {
if (scheduleItems->size() == 0) {
return true;
}
if (strlen(cmd) == 0 || Helpers::toLower(cmd) == F_(values) || Helpers::toLower(cmd) == F_(info)) {
// list all names
for (const ScheduleItem & scheduleItem : *scheduleItems) {
if (!scheduleItem.name.empty()) {