mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-05-10 07:55:53 +00:00
Compare commits
35 Commits
d6d3a034ad
...
latest
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
017a7de639 | ||
|
|
7b61429a02 | ||
|
|
fed15f0f96 | ||
|
|
ad5d13168b | ||
|
|
ae5beccb9d | ||
|
|
764c660b14 | ||
|
|
ca0f32b087 | ||
|
|
8ad91de54a | ||
|
|
58da157272 | ||
|
|
b5014bf9ac | ||
|
|
14351436a7 | ||
|
|
469d412951 | ||
|
|
6edbac86e2 | ||
|
|
db2be70d66 | ||
|
|
c36f231990 | ||
|
|
26102121e1 | ||
|
|
8e64c6303e | ||
|
|
74c76eb90b | ||
|
|
daffdcf58e | ||
|
|
4bc4fa903f | ||
|
|
29380f0303 | ||
|
|
6b2370b79d | ||
|
|
dbc636c9bf | ||
|
|
0c0660c04b | ||
|
|
c9fd076394 | ||
|
|
35550553be | ||
|
|
06ff219385 | ||
|
|
e705a5629f | ||
|
|
cb3c9653ce | ||
|
|
0b5a83f6ae | ||
|
|
a079169005 | ||
|
|
845c51d5f9 | ||
|
|
854f4d559a | ||
|
|
d9b6de0652 | ||
|
|
c54da18822 |
@@ -14,11 +14,14 @@ For more details go to [emsesp.org](https://emsesp.org/).
|
|||||||
- heatpump reset [#2933](https://github.com/emsesp/EMS-ESP32/issues/2933)
|
- heatpump reset [#2933](https://github.com/emsesp/EMS-ESP32/issues/2933)
|
||||||
- 2.nd freshwater module (dhw4, dhw5) [#2991](https://github.com/emsesp/EMS-ESP32/issues/2991)
|
- 2.nd freshwater module (dhw4, dhw5) [#2991](https://github.com/emsesp/EMS-ESP32/issues/2991)
|
||||||
- full system backup and restore
|
- full system backup and restore
|
||||||
|
- auto-logic to set ht3/ems+ tx-mode
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- SRC climate creation [#2936](https://github.com/emsesp/EMS-ESP32/issues/2936) and [#2960](https://github.com/emsesp/EMS-ESP32/issues/2960)
|
- SRC climate creation [#2936](https://github.com/emsesp/EMS-ESP32/issues/2936) and [#2960](https://github.com/emsesp/EMS-ESP32/issues/2960)
|
||||||
- missing translations [#3015](https://github.com/emsesp/EMS-ESP32/issues/3015)
|
- missing translations [#3015](https://github.com/emsesp/EMS-ESP32/issues/3015)
|
||||||
|
- custom entities check fetch length
|
||||||
|
- modbus initialization [#3064](https://github.com/emsesp/EMS-ESP32/issues/3064)
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
@@ -33,3 +36,5 @@ For more details go to [emsesp.org](https://emsesp.org/).
|
|||||||
- fetch telegrams: set length to fetch [#3017](https://github.com/emsesp/EMS-ESP32/issues/3017)
|
- fetch telegrams: set length to fetch [#3017](https://github.com/emsesp/EMS-ESP32/issues/3017)
|
||||||
- move http client from stack to heap
|
- move http client from stack to heap
|
||||||
- heap optimizations [#3021](https://github.com/emsesp/EMS-ESP32/discussions/3021)
|
- heap optimizations [#3021](https://github.com/emsesp/EMS-ESP32/discussions/3021)
|
||||||
|
- check and read 0x470 as summer2_typeids[0] only if received [#2686](https://github.com/emsesp/EMS-ESP32/issues/2686), [#3055](https://github.com/emsesp/EMS-ESP32/issues/3055)
|
||||||
|
- default bus-id: gateway1(0x49), tx-mode: auto
|
||||||
|
|||||||
@@ -112,10 +112,10 @@ telegram_type_id,name,is_fetched
|
|||||||
0x02A0,RC300Curves,
|
0x02A0,RC300Curves,
|
||||||
0x02A1,RC300Curves,
|
0x02A1,RC300Curves,
|
||||||
0x02A2,RC300Curves,
|
0x02A2,RC300Curves,
|
||||||
0x02A5,RC300Monitor,fetched
|
0x02A5,RC300Monitor,
|
||||||
0x02A6,CRFMonitor,
|
0x02A6,RC300Monitor,
|
||||||
0x02A7,RC300Monitor,
|
0x02A7,RC300Monitor,
|
||||||
0x02A8,CRFMonitor,
|
0x02A8,RC300Monitor,
|
||||||
0x02A9,RC300Monitor,
|
0x02A9,RC300Monitor,
|
||||||
0x02AA,RC300Monitor,
|
0x02AA,RC300Monitor,
|
||||||
0x02AB,RC300Monitor,
|
0x02AB,RC300Monitor,
|
||||||
@@ -171,6 +171,7 @@ telegram_type_id,name,is_fetched
|
|||||||
0x0468,HPSet,
|
0x0468,HPSet,
|
||||||
0x0469,HPSet,
|
0x0469,HPSet,
|
||||||
0x046A,HPSet,
|
0x046A,HPSet,
|
||||||
|
0x0470,RC300Summer2,fetched
|
||||||
0x0471,RC300Summer2,
|
0x0471,RC300Summer2,
|
||||||
0x0472,RC300Summer2,
|
0x0472,RC300Summer2,
|
||||||
0x0473,RC300Summer2,
|
0x0473,RC300Summer2,
|
||||||
|
|||||||
|
@@ -26,8 +26,8 @@
|
|||||||
"@alova/adapter-xhr": "2.3.1",
|
"@alova/adapter-xhr": "2.3.1",
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.1",
|
"@emotion/styled": "^11.14.1",
|
||||||
"@mui/icons-material": "^9.0.0",
|
"@mui/icons-material": "^9.0.1",
|
||||||
"@mui/material": "^9.0.0",
|
"@mui/material": "^9.0.1",
|
||||||
"@preact/compat": "^18.3.2",
|
"@preact/compat": "^18.3.2",
|
||||||
"@table-library/react-table-library": "4.1.15",
|
"@table-library/react-table-library": "4.1.15",
|
||||||
"alova": "3.5.1",
|
"alova": "3.5.1",
|
||||||
@@ -38,11 +38,11 @@
|
|||||||
"magic-string": "^0.30.21",
|
"magic-string": "^0.30.21",
|
||||||
"mime-types": "^3.0.2",
|
"mime-types": "^3.0.2",
|
||||||
"preact": "^10.29.1",
|
"preact": "^10.29.1",
|
||||||
"react": "^19.2.5",
|
"react": "^19.2.6",
|
||||||
"react-dom": "^19.2.5",
|
"react-dom": "^19.2.6",
|
||||||
"react-icons": "^5.6.0",
|
"react-icons": "^5.6.0",
|
||||||
"react-router": "^7.14.1",
|
"react-router": "^7.15.0",
|
||||||
"react-toastify": "^11.0.5",
|
"react-toastify": "^11.1.0",
|
||||||
"typesafe-i18n": "^5.27.1",
|
"typesafe-i18n": "^5.27.1",
|
||||||
"typescript": "^6.0.3"
|
"typescript": "^6.0.3"
|
||||||
},
|
},
|
||||||
@@ -55,17 +55,17 @@
|
|||||||
"@types/node": "^25.6.0",
|
"@types/node": "^25.6.0",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"axe-core": "^4.11.3",
|
"axe-core": "^4.11.4",
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
"eslint": "^10.2.1",
|
"eslint": "^10.3.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"prettier": "^3.8.3",
|
"prettier": "^3.8.3",
|
||||||
"rollup-plugin-visualizer": "^7.0.1",
|
"rollup-plugin-visualizer": "^7.0.1",
|
||||||
"terser": "^5.46.1",
|
"terser": "^5.47.0",
|
||||||
"typescript-eslint": "^8.58.2",
|
"typescript-eslint": "^8.59.2",
|
||||||
"vite": "^8.0.8",
|
"vite": "^8.0.11",
|
||||||
"vite-plugin-imagemin": "^0.6.1",
|
"vite-plugin-imagemin": "^0.6.1",
|
||||||
"vite-tsconfig-paths": "^6.1.1"
|
"vite-tsconfig-paths": "^6.1.1"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
|
"packageManager": "pnpm@10.33.4"
|
||||||
}
|
}
|
||||||
|
|||||||
754
interface/pnpm-lock.yaml
generated
754
interface/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ import { PROJECT_NAME } from 'env';
|
|||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { SignInRequest } from 'types';
|
import type { SignInRequest } from 'types';
|
||||||
import { onEnterCallback, updateValue } from 'utils';
|
import { onEnterCallback, updateValue } from 'utils';
|
||||||
import { SIGN_IN_REQUEST_VALIDATOR, validate } from 'validators';
|
import { SIGN_IN_REQUEST_VALIDATOR, ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
const SignIn = memo(() => {
|
const SignIn = memo(() => {
|
||||||
const authenticationContext = useContext(AuthenticationContext);
|
const authenticationContext = useContext(AuthenticationContext);
|
||||||
@@ -74,7 +74,7 @@ const SignIn = memo(() => {
|
|||||||
await validate(SIGN_IN_REQUEST_VALIDATOR, signInRequest);
|
await validate(SIGN_IN_REQUEST_VALIDATOR, signInRequest);
|
||||||
await signIn();
|
await signIn();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
setProcessing(false);
|
setProcessing(false);
|
||||||
}
|
}
|
||||||
}, [signInRequest, signIn, LL]);
|
}, [signInRequest, signIn, LL]);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
|||||||
import { BlockFormControlLabel, ValidatedTextField } from 'components';
|
import { BlockFormControlLabel, ValidatedTextField } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { numberValue, updateValue } from 'utils';
|
import { numberValue, updateValue } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
import { DeviceValueType, DeviceValueTypeNames, DeviceValueUOM_s } from './types';
|
import { DeviceValueType, DeviceValueTypeNames, DeviceValueUOM_s } from './types';
|
||||||
import type { EntityItem } from './types';
|
import type { EntityItem } from './types';
|
||||||
@@ -136,7 +136,7 @@ const CustomEntitiesDialog = ({
|
|||||||
}
|
}
|
||||||
onSave(processedItem);
|
onSave(processedItem);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [validator, editItem, onSave]);
|
}, [validator, editItem, onSave]);
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ const CustomEntitiesDialog = ({
|
|||||||
name="value"
|
name="value"
|
||||||
label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)}
|
label={LL.DEFAULT(0) + ' ' + LL.VALUE(0)}
|
||||||
type="string"
|
type="string"
|
||||||
value={editItem.value as string}
|
value={editItem.value}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
fullWidth
|
fullWidth
|
||||||
@@ -260,7 +260,7 @@ const CustomEntitiesDialog = ({
|
|||||||
margin="normal"
|
margin="normal"
|
||||||
sx={{ width: '11ch' }}
|
sx={{ width: '11ch' }}
|
||||||
type="string"
|
type="string"
|
||||||
value={editItem.device_id as string}
|
value={editItem.device_id}
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
input: {
|
input: {
|
||||||
@@ -280,7 +280,7 @@ const CustomEntitiesDialog = ({
|
|||||||
margin="normal"
|
margin="normal"
|
||||||
sx={{ width: '11ch' }}
|
sx={{ width: '11ch' }}
|
||||||
type="string"
|
type="string"
|
||||||
value={editItem.type_id as string}
|
value={editItem.type_id}
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
input: {
|
input: {
|
||||||
@@ -381,7 +381,7 @@ const CustomEntitiesDialog = ({
|
|||||||
fieldErrors={fieldErrors || {}}
|
fieldErrors={fieldErrors || {}}
|
||||||
name="factor"
|
name="factor"
|
||||||
label={LL.BITMASK()}
|
label={LL.BITMASK()}
|
||||||
value={editItem.factor as string}
|
value={editItem.factor}
|
||||||
sx={{ width: '11ch' }}
|
sx={{ width: '11ch' }}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onChange={updateFormValue}
|
onChange={updateFormValue}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
|||||||
import { ValidatedTextField } from 'components';
|
import { ValidatedTextField } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { numberValue, updateValue } from 'utils';
|
import { numberValue, updateValue } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
import { DeviceValueUOM, DeviceValueUOM_s } from './types';
|
import { DeviceValueUOM, DeviceValueUOM_s } from './types';
|
||||||
import type { DeviceValue } from './types';
|
import type { DeviceValue } from './types';
|
||||||
@@ -67,7 +67,7 @@ const DevicesDialog = ({
|
|||||||
await validate(validator, editItem);
|
await validate(validator, editItem);
|
||||||
onSave(editItem);
|
onSave(editItem);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [validator, editItem, onSave]);
|
}, [validator, editItem, onSave]);
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
|||||||
import { BlockFormControlLabel, ValidatedTextField } from 'components';
|
import { BlockFormControlLabel, ValidatedTextField } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { updateValue } from 'utils';
|
import { updateValue } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
import { ScheduleFlag } from './types';
|
import { ScheduleFlag } from './types';
|
||||||
import type { ScheduleItem } from './types';
|
import type { ScheduleItem } from './types';
|
||||||
@@ -120,7 +120,7 @@ const SchedulerDialog = ({
|
|||||||
await validate(validator, itemToSave);
|
await validate(validator, itemToSave);
|
||||||
onSave(itemToSave);
|
onSave(itemToSave);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[validator, onSave]
|
[validator, onSave]
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
|||||||
import { ValidatedTextField } from 'components';
|
import { ValidatedTextField } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { numberValue, updateValue } from 'utils';
|
import { numberValue, updateValue } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
import { AnalogType, AnalogTypeNames, DeviceValueUOM_s } from './types';
|
import { AnalogType, AnalogTypeNames, DeviceValueUOM_s } from './types';
|
||||||
import type { AnalogSensor } from './types';
|
import type { AnalogSensor } from './types';
|
||||||
@@ -172,7 +172,7 @@ const SensorsAnalogDialog = ({
|
|||||||
await validate(validator, editItem);
|
await validate(validator, editItem);
|
||||||
onSave(editItem);
|
onSave(editItem);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [validator, editItem, onSave]);
|
}, [validator, editItem, onSave]);
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import type { ValidateFieldsError } from 'async-validator';
|
|||||||
import { ValidatedTextField } from 'components';
|
import { ValidatedTextField } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { numberValue, updateValue } from 'utils';
|
import { numberValue, updateValue } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
import type { TemperatureSensor } from './types';
|
import type { TemperatureSensor } from './types';
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ const SensorsTemperatureDialog = ({
|
|||||||
await validate(validator, editItem);
|
await validate(validator, editItem);
|
||||||
onSave(editItem);
|
onSave(editItem);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [validator, editItem, onSave]);
|
}, [validator, editItem, onSave]);
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { useI18nContext } from 'i18n/i18n-react';
|
|||||||
import type { APSettingsType } from 'types';
|
import type { APSettingsType } from 'types';
|
||||||
import { APProvisionMode } from 'types';
|
import { APProvisionMode } from 'types';
|
||||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||||
import { createAPSettingsValidator, validate } from 'validators';
|
import { ValidationError, createAPSettingsValidator, validate } from 'validators';
|
||||||
|
|
||||||
export const isAPEnabled = ({ provision_mode }: APSettingsType) =>
|
export const isAPEnabled = ({ provision_mode }: APSettingsType) =>
|
||||||
provision_mode === APProvisionMode.AP_MODE_ALWAYS ||
|
provision_mode === APProvisionMode.AP_MODE_ALWAYS ||
|
||||||
@@ -86,7 +86,7 @@ const APSettings = () => {
|
|||||||
await validate(createAPSettingsValidator(data), data);
|
await validate(createAPSettingsValidator(data), data);
|
||||||
await saveData();
|
await saveData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [data, saveData]);
|
}, [data, saveData]);
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import {
|
|||||||
} from 'components';
|
} from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
import { API, getBoardProfile, readSettings, writeSettings } from '../../api/app';
|
import { API, getBoardProfile, readSettings, writeSettings } from '../../api/app';
|
||||||
import { BOARD_PROFILES } from '../main/types';
|
import { BOARD_PROFILES } from '../main/types';
|
||||||
@@ -153,7 +153,7 @@ const ApplicationSettings = () => {
|
|||||||
setFieldErrors(undefined);
|
setFieldErrors(undefined);
|
||||||
await validate(createSettingsValidator(data), data);
|
await validate(createSettingsValidator(data), data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
} finally {
|
} finally {
|
||||||
await saveData();
|
await saveData();
|
||||||
}
|
}
|
||||||
@@ -677,6 +677,7 @@ const ApplicationSettings = () => {
|
|||||||
<MenuItem value={2}>EMS+</MenuItem>
|
<MenuItem value={2}>EMS+</MenuItem>
|
||||||
<MenuItem value={3}>HT3</MenuItem>
|
<MenuItem value={3}>HT3</MenuItem>
|
||||||
<MenuItem value={4}>{LL.HARDWARE()}</MenuItem>
|
<MenuItem value={4}>{LL.HARDWARE()}</MenuItem>
|
||||||
|
<MenuItem value={5}>Auto</MenuItem>
|
||||||
</TextField>
|
</TextField>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { MqttSettingsType } from 'types';
|
import type { MqttSettingsType } from 'types';
|
||||||
import { numberValue, updateValueDirty, useRest } from 'utils';
|
import { numberValue, updateValueDirty, useRest } from 'utils';
|
||||||
import { createMqttSettingsValidator, validate } from 'validators';
|
import { ValidationError, createMqttSettingsValidator, validate } from 'validators';
|
||||||
|
|
||||||
import { callAction } from '../../api/app';
|
import { callAction } from '../../api/app';
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ const MqttSettings = () => {
|
|||||||
await validate(createMqttSettingsValidator(data), data);
|
await validate(createMqttSettingsValidator(data), data);
|
||||||
await saveData();
|
await saveData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [data, saveData]);
|
}, [data, saveData]);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import {
|
|||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { NTPSettingsType, Time } from 'types';
|
import type { NTPSettingsType, Time } from 'types';
|
||||||
import { formatLocalDateTime, updateValueDirty, useRest } from 'utils';
|
import { formatLocalDateTime, updateValueDirty, useRest } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
|
import { NTP_SETTINGS_VALIDATOR } from 'validators/ntp';
|
||||||
|
|
||||||
import { TIME_ZONES, selectedTimeZone, useTimeZoneSelectItems } from './TZ';
|
import { TIME_ZONES, selectedTimeZone, useTimeZoneSelectItems } from './TZ';
|
||||||
@@ -133,7 +133,7 @@ const NTPSettings = () => {
|
|||||||
await validate(NTP_SETTINGS_VALIDATOR, data);
|
await validate(NTP_SETTINGS_VALIDATOR, data);
|
||||||
await saveData();
|
await saveData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [data, saveData]);
|
}, [data, saveData]);
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import {
|
|||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { NetworkSettingsType } from 'types';
|
import type { NetworkSettingsType } from 'types';
|
||||||
import { updateValueDirty, useRest } from 'utils';
|
import { updateValueDirty, useRest } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
import { createNetworkSettingsValidator } from 'validators/network';
|
import { createNetworkSettingsValidator } from 'validators/network';
|
||||||
|
|
||||||
import SystemMonitor from '../../status/SystemMonitor';
|
import SystemMonitor from '../../status/SystemMonitor';
|
||||||
@@ -116,7 +116,7 @@ const NetworkSettings = () => {
|
|||||||
await validate(createNetworkSettingsValidator(data), data);
|
await validate(createNetworkSettingsValidator(data), data);
|
||||||
await saveData();
|
await saveData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
deselectNetwork();
|
deselectNetwork();
|
||||||
}, [data, saveData, deselectNetwork]);
|
}, [data, saveData, deselectNetwork]);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { AuthenticatedContext } from 'contexts/authentication';
|
|||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { SecuritySettingsType } from 'types';
|
import type { SecuritySettingsType } from 'types';
|
||||||
import { updateValueDirty, useRest } from 'utils';
|
import { updateValueDirty, useRest } from 'utils';
|
||||||
import { SECURITY_SETTINGS_VALIDATOR, validate } from 'validators';
|
import { SECURITY_SETTINGS_VALIDATOR, ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
const SecuritySettings = () => {
|
const SecuritySettings = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
@@ -58,7 +58,7 @@ const SecuritySettings = () => {
|
|||||||
await saveData();
|
await saveData();
|
||||||
await authenticatedContext.refresh();
|
await authenticatedContext.refresh();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}, [data, saveData, authenticatedContext]);
|
}, [data, saveData, authenticatedContext]);
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import {
|
|||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { UserType } from 'types';
|
import type { UserType } from 'types';
|
||||||
import { updateValue } from 'utils';
|
import { updateValue } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { ValidationError, validate } from 'validators';
|
||||||
|
|
||||||
interface UserFormProps {
|
interface UserFormProps {
|
||||||
creating: boolean;
|
creating: boolean;
|
||||||
@@ -69,7 +69,7 @@ const User: FC<UserFormProps> = ({
|
|||||||
await validate(validator, user);
|
await validate(validator, user);
|
||||||
onDoneEditing();
|
onDoneEditing();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFieldErrors(error as ValidateFieldsError);
|
setFieldErrors((error as ValidationError).fieldErrors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [user, validator, onDoneEditing]);
|
}, [user, validator, onDoneEditing]);
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ const de: Translation = {
|
|||||||
COMPACT: 'Kompakte Darstellung',
|
COMPACT: 'Kompakte Darstellung',
|
||||||
DOWNLOAD_SETTINGS_TEXT: 'Erstellen Sie eine Sicherung Ihrer Konfigurationen und Einstellungen',
|
DOWNLOAD_SETTINGS_TEXT: 'Erstellen Sie eine Sicherung Ihrer Konfigurationen und Einstellungen',
|
||||||
DOWNLOAD_SETTINGS_TEXT2: 'Exportiere alle Werte',
|
DOWNLOAD_SETTINGS_TEXT2: 'Exportiere alle Werte',
|
||||||
DOWNLOAD_SYSTEM_BACKUP: 'System Sicherung',
|
DOWNLOAD_SYSTEM_BACKUP: 'Systemsicherung',
|
||||||
UPLOAD_TEXT: 'Laden Sie eine neue Firmware-Datei (.bin) oder eine Sicherungsdatei (.json) hoch',
|
UPLOAD_TEXT: 'Laden Sie eine neue Firmware-Datei (.bin) oder eine Sicherungsdatei (.json) hoch',
|
||||||
UPLOAD_DROP_TEXT: 'Legen Sie eine Firmware-Datei (.bin) ab oder klicken Sie hier',
|
UPLOAD_DROP_TEXT: 'Legen Sie eine Firmware-Datei (.bin) ab oder klicken Sie hier',
|
||||||
ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut.',
|
ERROR: 'Unerwarteter Fehler, bitte versuchen Sie es erneut.',
|
||||||
@@ -362,9 +362,9 @@ const de: Translation = {
|
|||||||
STORED_VERSIONS: 'Gespeicherte Versionen',
|
STORED_VERSIONS: 'Gespeicherte Versionen',
|
||||||
ONLINE_HELP: 'Online-Hilfe',
|
ONLINE_HELP: 'Online-Hilfe',
|
||||||
UPGRADE_IMPORTANT_MESSAGES: 'Wichtige Nachrichten aktualisieren',
|
UPGRADE_IMPORTANT_MESSAGES: 'Wichtige Nachrichten aktualisieren',
|
||||||
UPGRADE_IMPORTANT_MESSAGES_1: 'Diese Aktualisierung erfordert eine Werkseinstellung. Stellen Sie sicher, dass Sie zuerst eine Systemsicherung herunterladen, bevor Sie fortfahren, und laden Sie diese Datei dann nach der Installation der neuen Version hoch.',
|
UPGRADE_IMPORTANT_MESSAGES_1: 'Für diese Aktualisierung ist ein Werksreset erforderlich. Stellen Sie sicher, dass Sie zuerst eine Systemsicherung herunterladen, bevor Sie fortfahren, und laden Sie diese Datei dann nach der Installation der neuen Version hoch.',
|
||||||
UPGRADE_IMPORTANT_MESSAGES_2: 'Sie aktualisieren auf eine neue Hauptversion. Stellen Sie sicher, dass Sie den ChangeLog für alle wichtigen Änderungen gelesen haben.',
|
UPGRADE_IMPORTANT_MESSAGES_2: 'Sie aktualisieren auf eine neue Hauptversion. Stellen Sie sicher, dass Sie den ChangeLog für alle wichtigen Änderungen gelesen haben.',
|
||||||
WARNING_SYSTEM_BACKUP: 'Dies wird eine Sicherung Ihrer vollständigen Systemkonfiguration und -einstellungen erstellen. Alle Passwörter werden im Sicherungsdatei lesbar sein. Seien Sie vorsichtig beim Teilen! Möchten Sie fortfahren?'
|
WARNING_SYSTEM_BACKUP: 'Dies wird eine Sicherung Ihrer vollständigen Systemkonfiguration und Einstellungen erstellen. Alle Passwörter werden in dieser Sicherungsdatei lesbar sein. Seien Sie vorsichtig beim Teilen! Möchten Sie fortfahren?'
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,20 @@
|
|||||||
import type { InternalRuleItem, ValidateOption } from 'async-validator';
|
import type {
|
||||||
|
InternalRuleItem,
|
||||||
|
ValidateFieldsError,
|
||||||
|
ValidateOption
|
||||||
|
} from 'async-validator';
|
||||||
import type Schema from 'async-validator';
|
import type Schema from 'async-validator';
|
||||||
|
|
||||||
|
export class ValidationError extends Error {
|
||||||
|
readonly fieldErrors: ValidateFieldsError;
|
||||||
|
|
||||||
|
constructor(fieldErrors: ValidateFieldsError) {
|
||||||
|
super('Validation failed');
|
||||||
|
this.name = 'ValidationError';
|
||||||
|
this.fieldErrors = fieldErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const validate = <T extends object>(
|
export const validate = <T extends object>(
|
||||||
validator: Schema,
|
validator: Schema,
|
||||||
source: Partial<T>,
|
source: Partial<T>,
|
||||||
@@ -8,7 +22,7 @@ export const validate = <T extends object>(
|
|||||||
): Promise<T> =>
|
): Promise<T> =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
void validator.validate(source, options ?? {}, (errors, fieldErrors) => {
|
void validator.validate(source, options ?? {}, (errors, fieldErrors) => {
|
||||||
errors ? reject(fieldErrors as Error) : resolve(source as T);
|
errors ? reject(new ValidationError(fieldErrors)) : resolve(source as T);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,11 @@
|
|||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
#define EMS_TXMODE_OFF 0
|
#define EMS_TXMODE_OFF 0
|
||||||
#define EMS_TXMODE_DEFAULT 1
|
#define EMS_TXMODE_EMS 1
|
||||||
#define EMS_TXMODE_EMSPLUS 2
|
#define EMS_TXMODE_EMSPLUS 2
|
||||||
#define EMS_TXMODE_HT3 3
|
#define EMS_TXMODE_HT3 3
|
||||||
#define EMS_TXMODE_HW 4
|
#define EMS_TXMODE_HW 4
|
||||||
|
#define EMS_TXMODE_AUTO 5
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
@@ -15,5 +15,5 @@
|
|||||||
"itty-router": "^5.0.23",
|
"itty-router": "^5.0.23",
|
||||||
"prettier": "^3.8.3"
|
"prettier": "^3.8.3"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
|
"packageManager": "pnpm@10.33.1+sha512.05ba3c1d5d1c18f68df06470d74055e62d41fc110a0c660db1b2dfb2785327f04cf0f68345d4609bc52089e7fa0343c31593b2f9594e2c5d5da426230acc9820"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ framework = arduino
|
|||||||
board_build.partitions = partitions/esp32_partition_16M.csv
|
board_build.partitions = partitions/esp32_partition_16M.csv
|
||||||
board_upload.flash_size = 16MB
|
board_upload.flash_size = 16MB
|
||||||
board_build.app_partition_name = app0
|
board_build.app_partition_name = app0
|
||||||
platform = espressif32@6.13.0 ; Arduino Core 2.0.17 / IDF 4.4.7
|
platform = espressif32@7.0.0 ; Arduino Core 2.0.17 / IDF 4.4.7
|
||||||
|
|
||||||
; 32MB Flash variants
|
; 32MB Flash variants
|
||||||
[espressif32_base_32M]
|
[espressif32_base_32M]
|
||||||
@@ -67,7 +67,7 @@ framework = arduino
|
|||||||
board_build.partitions = partitions/esp32_partition_32M.csv
|
board_build.partitions = partitions/esp32_partition_32M.csv
|
||||||
board_upload.flash_size = 32MB
|
board_upload.flash_size = 32MB
|
||||||
board_build.app_partition_name = app0
|
board_build.app_partition_name = app0
|
||||||
platform = espressif32@6.13.0 ; Arduino Core 2.0.17 / IDF 4.4.7
|
platform = espressif32@7.0.0 ; Arduino Core 2.0.17 / IDF 4.4.7
|
||||||
|
|
||||||
; use Tasmota's library for 4MB Flash variants.
|
; use Tasmota's library for 4MB Flash variants.
|
||||||
; Removes libs (like mbedtsl, so no WiFi_secure.h) to increase available heap
|
; Removes libs (like mbedtsl, so no WiFi_secure.h) to increase available heap
|
||||||
@@ -105,7 +105,7 @@ board_build.filesystem = littlefs
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson @ 7.4.3
|
bblanchon/ArduinoJson @ 7.4.3
|
||||||
ESP32Async/AsyncTCP @ 3.4.10
|
ESP32Async/AsyncTCP @ 3.4.10
|
||||||
ESP32Async/ESPAsyncWebServer @ 3.10.3
|
ESP32Async/ESPAsyncWebServer @ 3.11.0
|
||||||
; https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8
|
; https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8
|
||||||
|
|
||||||
; builds the web interface only, not the firmware
|
; builds the web interface only, not the firmware
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ def buildWeb():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def build-webUI(*args, **kwargs):
|
def build_webUI(*args, **kwargs):
|
||||||
success = buildWeb()
|
success = buildWeb()
|
||||||
if not success:
|
if not success:
|
||||||
print("Web interface build failed!")
|
print("Web interface build failed!")
|
||||||
@@ -114,7 +114,7 @@ def build-webUI(*args, **kwargs):
|
|||||||
env.AddCustomTarget(
|
env.AddCustomTarget(
|
||||||
name="build",
|
name="build",
|
||||||
dependencies=None,
|
dependencies=None,
|
||||||
actions=[build-webUI],
|
actions=[build_webUI],
|
||||||
title="build web interface",
|
title="build web interface",
|
||||||
description="installs pnpm packages, updates libraries and builds web UI",
|
description="installs pnpm packages, updates libraries and builds web UI",
|
||||||
always_build=True
|
always_build=True
|
||||||
|
|||||||
@@ -70,16 +70,12 @@ void ArduinoJsonJWT::parseJWT(String jwt, JsonDocument & jsonDocument) {
|
|||||||
*/
|
*/
|
||||||
String ArduinoJsonJWT::sign(String & payload) {
|
String ArduinoJsonJWT::sign(String & payload) {
|
||||||
std::array<unsigned char, 32> hmacResult{};
|
std::array<unsigned char, 32> hmacResult{};
|
||||||
{
|
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
|
||||||
mbedtls_md_context_t ctx;
|
reinterpret_cast<const unsigned char *>(_secret.c_str()),
|
||||||
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
|
_secret.length(),
|
||||||
mbedtls_md_init(&ctx);
|
reinterpret_cast<const unsigned char *>(payload.c_str()),
|
||||||
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1);
|
payload.length(),
|
||||||
mbedtls_md_hmac_starts(&ctx, reinterpret_cast<const unsigned char *>(_secret.c_str()), _secret.length());
|
hmacResult.data());
|
||||||
mbedtls_md_hmac_update(&ctx, reinterpret_cast<const unsigned char *>(payload.c_str()), payload.length());
|
|
||||||
mbedtls_md_hmac_finish(&ctx, hmacResult.data());
|
|
||||||
mbedtls_md_free(&ctx);
|
|
||||||
}
|
|
||||||
return encode(reinterpret_cast<const char *>(hmacResult.data()), hmacResult.size());
|
return encode(reinterpret_cast<const char *>(hmacResult.data()), hmacResult.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,10 +185,14 @@ bool MqttSettingsService::configureMqtt() {
|
|||||||
#ifndef TASMOTA_SDK
|
#ifndef TASMOTA_SDK
|
||||||
if (_state.enableTLS) {
|
if (_state.enableTLS) {
|
||||||
if (_state.rootCA == "insecure") {
|
if (_state.rootCA == "insecure") {
|
||||||
|
#if defined(EMSESP_DEBUG)
|
||||||
emsesp::EMSESP::logger().debug("Start insecure MQTT");
|
emsesp::EMSESP::logger().debug("Start insecure MQTT");
|
||||||
|
#endif
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setInsecure();
|
static_cast<espMqttClientSecure *>(_mqttClient)->setInsecure();
|
||||||
} else {
|
} else {
|
||||||
|
#if defined(EMSESP_DEBUG)
|
||||||
emsesp::EMSESP::logger().debug("Start secure MQTT with rootCA");
|
emsesp::EMSESP::logger().debug("Start secure MQTT with rootCA");
|
||||||
|
#endif
|
||||||
String certificate = "-----BEGIN CERTIFICATE-----\n" + _state.rootCA + "\n-----END CERTIFICATE-----\n";
|
String certificate = "-----BEGIN CERTIFICATE-----\n" + _state.rootCA + "\n-----END CERTIFICATE-----\n";
|
||||||
static_cast<espMqttClientSecure *>(_mqttClient)->setCACert(certificate.c_str());
|
static_cast<espMqttClientSecure *>(_mqttClient)->setCACert(certificate.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,9 @@ class EMSESP_Version {
|
|||||||
return a.major_ < b.major_;
|
return a.major_ < b.major_;
|
||||||
if (a.minor_ != b.minor_)
|
if (a.minor_ != b.minor_)
|
||||||
return a.minor_ < b.minor_;
|
return a.minor_ < b.minor_;
|
||||||
return a.patch_ < b.patch_;
|
if (a.patch_ != b.patch_)
|
||||||
|
return a.patch_ < b.patch_;
|
||||||
|
return a.prerelease_ < b.prerelease_;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator>(const EMSESP_Version & a, const EMSESP_Version & b) {
|
friend bool operator>(const EMSESP_Version & a, const EMSESP_Version & b) {
|
||||||
@@ -77,7 +79,7 @@ class EMSESP_Version {
|
|||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator==(const EMSESP_Version & a, const EMSESP_Version & b) {
|
friend bool operator==(const EMSESP_Version & a, const EMSESP_Version & b) {
|
||||||
return a.major_ == b.major_ && a.minor_ == b.minor_ && a.patch_ == b.patch_;
|
return a.major_ == b.major_ && a.minor_ == b.minor_ && a.patch_ == b.patch_ && a.prerelease_ == b.prerelease_;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const EMSESP_Version & a, const EMSESP_Version & b) {
|
friend bool operator!=(const EMSESP_Version & a, const EMSESP_Version & b) {
|
||||||
|
|||||||
@@ -26,11 +26,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EMSESP_DEFAULT_TX_MODE
|
#ifndef EMSESP_DEFAULT_TX_MODE
|
||||||
#define EMSESP_DEFAULT_TX_MODE 1 // EMS1.0
|
#define EMSESP_DEFAULT_TX_MODE 5 // Auto
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EMSESP_DEFAULT_EMS_BUS_ID
|
#ifndef EMSESP_DEFAULT_EMS_BUS_ID
|
||||||
#define EMSESP_DEFAULT_EMS_BUS_ID 0x0B // service key
|
#define EMSESP_DEFAULT_EMS_BUS_ID 0x49 // gateway 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EMSESP_DEFAULT_SYSLOG_ENABLED
|
#ifndef EMSESP_DEFAULT_SYSLOG_ENABLED
|
||||||
|
|||||||
@@ -387,10 +387,10 @@ void EMSdevice::toggle_fetch(uint16_t telegram_id, bool toggle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get status of automatic fetch for a telegramID
|
// get status of automatic fetch for a telegramID
|
||||||
bool EMSdevice::is_fetch(uint16_t telegram_id) const {
|
bool EMSdevice::is_fetch(uint16_t telegram_id, uint8_t len) const {
|
||||||
for (const auto & tf : telegram_functions_) {
|
for (const auto & tf : telegram_functions_) {
|
||||||
if (tf.telegram_type_id_ == telegram_id) {
|
if (tf.telegram_type_id_ == telegram_id) {
|
||||||
return tf.fetch_;
|
return tf.fetch_ && tf.length_ >= len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ class EMSdevice {
|
|||||||
const char * telegram_type_name(std::shared_ptr<const Telegram> telegram);
|
const char * telegram_type_name(std::shared_ptr<const Telegram> telegram);
|
||||||
void fetch_values();
|
void fetch_values();
|
||||||
void toggle_fetch(uint16_t telegram_id, bool toggle);
|
void toggle_fetch(uint16_t telegram_id, bool toggle);
|
||||||
bool is_fetch(uint16_t telegram_id) const;
|
bool is_fetch(uint16_t telegram_id, uint8_t len = 0) const;
|
||||||
bool is_received(uint16_t telegram_id) const;
|
bool is_received(uint16_t telegram_id) const;
|
||||||
bool has_telegram_id(uint16_t id) const;
|
bool has_telegram_id(uint16_t id) const;
|
||||||
void ha_config_clear();
|
void ha_config_clear();
|
||||||
@@ -448,6 +448,14 @@ class EMSdevice {
|
|||||||
static constexpr uint8_t EMS_DEVICE_ID_DHW2 = 0x29; // MM100 module as water station
|
static constexpr uint8_t EMS_DEVICE_ID_DHW2 = 0x29; // MM100 module as water station
|
||||||
static constexpr uint8_t EMS_DEVICE_ID_DHW8 = 0x2F; // last DHW module id?
|
static constexpr uint8_t EMS_DEVICE_ID_DHW8 = 0x2F; // last DHW module id?
|
||||||
static constexpr uint8_t EMS_DEVICE_ID_IPM_DHW = 0x41; // IPM module as water station
|
static constexpr uint8_t EMS_DEVICE_ID_IPM_DHW = 0x41; // IPM module as water station
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY1 = 0x48; // KM200, MX300, MX400
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY2 = 0x49;
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY3 = 0x4A;
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY4 = 0x4B;
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY5 = 0x4C;
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY6 = 0x4D;
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY7 = 0x4E;
|
||||||
|
static constexpr uint8_t EMS_DEVICE_ID_GATEWAY8 = 0x4F;
|
||||||
|
|
||||||
// generic type IDs
|
// generic type IDs
|
||||||
static constexpr uint16_t EMS_TYPE_NAME = 0x01; // device config for ems devices, name ascii on offset 27ff for ems+
|
static constexpr uint16_t EMS_TYPE_NAME = 0x01; // device config for ems devices, name ascii on offset 27ff for ems+
|
||||||
|
|||||||
@@ -526,6 +526,29 @@ void System::syslog_init() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start or reconfigure modbus
|
||||||
|
void System::modbus_init() {
|
||||||
|
EMSESP::webSettingsService.read([&](WebSettings & settings) {
|
||||||
|
if (settings.modbus_enabled) {
|
||||||
|
if (EMSESP::modbus_ == nullptr) {
|
||||||
|
EMSESP::modbus_ = new Modbus;
|
||||||
|
EMSESP::modbus_->start(1, settings.modbus_port, settings.modbus_max_clients, settings.modbus_timeout * 1000);
|
||||||
|
} else if (settings.modbus_port != modbus_port_ || settings.modbus_max_clients != modbus_max_clients_ || settings.modbus_timeout != modbus_timeout_) {
|
||||||
|
EMSESP::modbus_->stop();
|
||||||
|
EMSESP::modbus_->start(1, settings.modbus_port, settings.modbus_max_clients, settings.modbus_timeout * 1000);
|
||||||
|
}
|
||||||
|
} else if (EMSESP::modbus_ != nullptr) {
|
||||||
|
EMSESP::modbus_->stop();
|
||||||
|
delete EMSESP::modbus_;
|
||||||
|
EMSESP::modbus_ = nullptr;
|
||||||
|
}
|
||||||
|
modbus_enabled_ = settings.modbus_enabled;
|
||||||
|
modbus_port_ = settings.modbus_port;
|
||||||
|
modbus_max_clients_ = settings.modbus_max_clients;
|
||||||
|
modbus_timeout_ = settings.modbus_timeout;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// read specific major system settings to store locally for faster access
|
// read specific major system settings to store locally for faster access
|
||||||
void System::store_settings(WebSettings & settings) {
|
void System::store_settings(WebSettings & settings) {
|
||||||
version_ = settings.version;
|
version_ = settings.version;
|
||||||
@@ -563,25 +586,6 @@ void System::store_settings(WebSettings & settings) {
|
|||||||
|
|
||||||
locale_ = settings.locale;
|
locale_ = settings.locale;
|
||||||
developer_mode_ = settings.developer_mode;
|
developer_mode_ = settings.developer_mode;
|
||||||
|
|
||||||
// start services
|
|
||||||
if (settings.modbus_enabled) {
|
|
||||||
if (EMSESP::modbus_ == nullptr) {
|
|
||||||
EMSESP::modbus_ = new Modbus;
|
|
||||||
EMSESP::modbus_->start(1, settings.modbus_port, settings.modbus_max_clients, settings.modbus_timeout * 1000);
|
|
||||||
} else if (settings.modbus_port != modbus_port_ || settings.modbus_max_clients != modbus_max_clients_ || settings.modbus_timeout != modbus_timeout_) {
|
|
||||||
EMSESP::modbus_->stop();
|
|
||||||
EMSESP::modbus_->start(1, settings.modbus_port, settings.modbus_max_clients, settings.modbus_timeout * 1000);
|
|
||||||
}
|
|
||||||
} else if (EMSESP::modbus_ != nullptr) {
|
|
||||||
EMSESP::modbus_->stop();
|
|
||||||
delete EMSESP::modbus_;
|
|
||||||
EMSESP::modbus_ = nullptr;
|
|
||||||
}
|
|
||||||
modbus_enabled_ = settings.modbus_enabled;
|
|
||||||
modbus_port_ = settings.modbus_port;
|
|
||||||
modbus_max_clients_ = settings.modbus_max_clients;
|
|
||||||
modbus_timeout_ = settings.modbus_timeout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts up core services
|
// Starts up core services
|
||||||
@@ -631,6 +635,7 @@ void System::start() {
|
|||||||
network_init(); // network
|
network_init(); // network
|
||||||
uart_init(); // start UART
|
uart_init(); // start UART
|
||||||
syslog_init(); // start syslog
|
syslog_init(); // start syslog
|
||||||
|
modbus_init(); // start modbus
|
||||||
}
|
}
|
||||||
|
|
||||||
// button single click
|
// button single click
|
||||||
@@ -1713,7 +1718,7 @@ void System::exportSystemBackup(JsonObject output) {
|
|||||||
output["version"] = EMSESP_APP_VERSION; // add the version to the output
|
output["version"] = EMSESP_APP_VERSION; // add the version to the output
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
// add date/time if NTP enabled and active
|
// add date/time if NTP enabled and active
|
||||||
if ((esp_sntp_enabled()) && (EMSESP::system_.ntp_connected())) {
|
if ((esp_sntp_enabled()) && (EMSESP::system_.ntp_connected())) {
|
||||||
time_t now = time(nullptr);
|
time_t now = time(nullptr);
|
||||||
if (now > 1500000000L) {
|
if (now > 1500000000L) {
|
||||||
@@ -1767,7 +1772,7 @@ void System::exportSystemBackup(JsonObject output) {
|
|||||||
node = nodes.add<JsonObject>();
|
node = nodes.add<JsonObject>();
|
||||||
node["type"] = "nvs";
|
node["type"] = "nvs";
|
||||||
|
|
||||||
const char * nvs_part = "nvs";
|
const char * nvs_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, "nvs1") ? "nvs1" : "nvs"; // nvs1 is on 16MBs
|
||||||
nvs_iterator_t it = nullptr;
|
nvs_iterator_t it = nullptr;
|
||||||
#if ESP_IDF_VERSION_MAJOR < 5
|
#if ESP_IDF_VERSION_MAJOR < 5
|
||||||
it = nvs_entry_find(nvs_part, "ems-esp", NVS_TYPE_ANY);
|
it = nvs_entry_find(nvs_part, "ems-esp", NVS_TYPE_ANY);
|
||||||
@@ -3266,7 +3271,7 @@ void System::set_valid_system_gpios() {
|
|||||||
valid_system_gpios_ = string_range_to_vector("0-21", "2, 8, 12-17, 18-19");
|
valid_system_gpios_ = string_range_to_vector("0-21", "2, 8, 12-17, 18-19");
|
||||||
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-reference/peripherals/gpio.html
|
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-reference/peripherals/gpio.html
|
||||||
// excluded:
|
// excluded:
|
||||||
// GPIO26 - GPIO32 = SPI flash and PSRAM
|
// GPIO26 - GPIO32 = SPI flash and PSRAM
|
||||||
// GPIO45 - GPIO46 = strapping pins
|
// GPIO45 - GPIO46 = strapping pins
|
||||||
@@ -3279,7 +3284,7 @@ void System::set_valid_system_gpios() {
|
|||||||
valid_system_gpios_ = string_range_to_vector("0-46", "19, 20, 26-32, 45-46, 39-42, 22-25");
|
valid_system_gpios_ = string_range_to_vector("0-46", "19, 20, 26-32, 45-46, 39-42, 22-25");
|
||||||
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-reference/peripherals/gpio.html
|
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-reference/peripherals/gpio.html
|
||||||
// excluded:
|
// excluded:
|
||||||
// GPIO3, GPIO45 - GPIO46 = strapping pins
|
// GPIO3, GPIO45 - GPIO46 = strapping pins
|
||||||
// GPIO26 - GPIO32 = SPI flash and PSRAM and not recommended
|
// GPIO26 - GPIO32 = SPI flash and PSRAM and not recommended
|
||||||
@@ -3298,7 +3303,7 @@ void System::set_valid_system_gpios() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/gpio.html
|
// https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/gpio.html
|
||||||
// excluded:
|
// excluded:
|
||||||
// GPIO6 - GPIO11, GPIO16 - GPIO17 = used for SPI flash and PSRAM (dio mode only GPIO06-GPIO08, GPIO11)
|
// GPIO6 - GPIO11, GPIO16 - GPIO17 = used for SPI flash and PSRAM (dio mode only GPIO06-GPIO08, GPIO11)
|
||||||
// GPIO20, GPIO24, GPIO28 - GPIO31 = don't exist
|
// GPIO20, GPIO24, GPIO28 - GPIO31 = don't exist
|
||||||
@@ -3378,6 +3383,24 @@ void System::remove_gpio(uint8_t pin, bool also_system) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove a gpio that has 0 for disable
|
||||||
|
void System::remove_optional_gpio(uint8_t pin) {
|
||||||
|
if (pin) {
|
||||||
|
remove_gpio(pin, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set unused gpios to default state input high-Z
|
||||||
|
void System::reset_unused_gpios() {
|
||||||
|
for (const auto & pin : valid_system_gpios_) {
|
||||||
|
auto it = std::find_if(used_gpios_.begin(), used_gpios_.end(), [pin](const GpioUsage & usage) { return usage.pin == pin; });
|
||||||
|
if (it == used_gpios_.end()) {
|
||||||
|
LOG_DEBUG("reset pin %d", pin);
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// return a list of GPIO's available for use
|
// return a list of GPIO's available for use
|
||||||
std::vector<uint8_t> System::available_gpios() {
|
std::vector<uint8_t> System::available_gpios() {
|
||||||
std::vector<uint8_t> gpios;
|
std::vector<uint8_t> gpios;
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ class System {
|
|||||||
void show_mem(const char * note);
|
void show_mem(const char * note);
|
||||||
void store_settings(class WebSettings & settings);
|
void store_settings(class WebSettings & settings);
|
||||||
void syslog_init();
|
void syslog_init();
|
||||||
|
void modbus_init();
|
||||||
bool check_upgrade();
|
bool check_upgrade();
|
||||||
bool check_restore();
|
bool check_restore();
|
||||||
void heartbeat_json(JsonObject output);
|
void heartbeat_json(JsonObject output);
|
||||||
@@ -376,6 +377,8 @@ class System {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void remove_gpio(uint8_t pin, bool also_system = false); // remove a gpio from both valid (optional) and used lists
|
static void remove_gpio(uint8_t pin, bool also_system = false); // remove a gpio from both valid (optional) and used lists
|
||||||
|
static void remove_optional_gpio(uint8_t pin);
|
||||||
|
static void reset_unused_gpios();
|
||||||
|
|
||||||
// Partition info map: partition name -> {version, size, install_date}
|
// Partition info map: partition name -> {version, size, install_date}
|
||||||
std::map<std::string, PartitionInfo, std::less<>, AllocatorPSRAM<std::pair<const std::string, PartitionInfo>>> partition_info_;
|
std::map<std::string, PartitionInfo, std::less<>, AllocatorPSRAM<std::pair<const std::string, PartitionInfo>>> partition_info_;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ uint8_t EMSbus::ems_mask_ = EMS_MASK_UNSET; // unset so its triggered
|
|||||||
uint8_t EMSbus::ems_bus_id_ = EMSESP_DEFAULT_EMS_BUS_ID;
|
uint8_t EMSbus::ems_bus_id_ = EMSESP_DEFAULT_EMS_BUS_ID;
|
||||||
uint8_t EMSbus::tx_mode_ = EMSESP_DEFAULT_TX_MODE;
|
uint8_t EMSbus::tx_mode_ = EMSESP_DEFAULT_TX_MODE;
|
||||||
uint8_t EMSbus::tx_state_ = Telegram::Operation::NONE;
|
uint8_t EMSbus::tx_state_ = Telegram::Operation::NONE;
|
||||||
|
bool EMSbus::isEMS2_ = false;
|
||||||
|
|
||||||
uuid::log::Logger EMSbus::logger_{F_(telegram), uuid::log::Facility::CONSOLE};
|
uuid::log::Logger EMSbus::logger_{F_(telegram), uuid::log::Facility::CONSOLE};
|
||||||
|
|
||||||
@@ -206,7 +207,9 @@ void RxService::add(uint8_t * data, uint8_t length) {
|
|||||||
message_data = data + 6;
|
message_data = data + 6;
|
||||||
message_length = length - 7;
|
message_length = length - 7;
|
||||||
}
|
}
|
||||||
|
if (type_id > 0x0FF && message_length > 1) { // used for auto tx_mode
|
||||||
|
set_ems2();
|
||||||
|
}
|
||||||
// if we're watching and "raw" print out actual telegram as bytes to the console
|
// if we're watching and "raw" print out actual telegram as bytes to the console
|
||||||
// including the CRC at the end
|
// including the CRC at the end
|
||||||
if (EMSESP::watch() == EMSESP::Watch::WATCH_RAW) {
|
if (EMSESP::watch() == EMSESP::Watch::WATCH_RAW) {
|
||||||
|
|||||||
@@ -168,6 +168,14 @@ class EMSbus {
|
|||||||
return (ems_mask_ == EMS_MASK_HT3);
|
return (ems_mask_ == EMS_MASK_HT3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_ems2() {
|
||||||
|
return isEMS2_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_ems2() {
|
||||||
|
isEMS2_ = true;;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t ems_mask() {
|
static uint8_t ems_mask() {
|
||||||
return ems_mask_;
|
return ems_mask_;
|
||||||
}
|
}
|
||||||
@@ -242,6 +250,7 @@ class EMSbus {
|
|||||||
static uint8_t ems_bus_id_; // the bus id, which configurable and stored in settings
|
static uint8_t ems_bus_id_; // the bus id, which configurable and stored in settings
|
||||||
static uint8_t tx_mode_; // local copy of the tx mode
|
static uint8_t tx_mode_; // local copy of the tx mode
|
||||||
static uint8_t tx_state_; // state of the Tx line (NONE or waiting on a TX_READ or TX_WRITE)
|
static uint8_t tx_state_; // state of the Tx line (NONE or waiting on a TX_READ or TX_WRITE)
|
||||||
|
static bool isEMS2_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RxService : public EMSbus {
|
class RxService : public EMSbus {
|
||||||
|
|||||||
@@ -21,12 +21,6 @@
|
|||||||
#include "temperaturesensor.h"
|
#include "temperaturesensor.h"
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
#define YIELD
|
|
||||||
#else
|
|
||||||
#define YIELD yield()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
uuid::log::Logger TemperatureSensor::logger_{F_(temperaturesensor), uuid::log::Facility::DAEMON};
|
uuid::log::Logger TemperatureSensor::logger_{F_(temperaturesensor), uuid::log::Facility::DAEMON};
|
||||||
@@ -81,7 +75,6 @@ void TemperatureSensor::loop() {
|
|||||||
LOG_DEBUG("Read sensor temperature");
|
LOG_DEBUG("Read sensor temperature");
|
||||||
#endif
|
#endif
|
||||||
if (bus_.reset() || parasite_) {
|
if (bus_.reset() || parasite_) {
|
||||||
YIELD;
|
|
||||||
bus_.skip();
|
bus_.skip();
|
||||||
bus_.write(CMD_CONVERT_TEMP, parasite_ ? 1 : 0);
|
bus_.write(CMD_CONVERT_TEMP, parasite_ ? 1 : 0);
|
||||||
state_ = State::READING;
|
state_ = State::READING;
|
||||||
@@ -260,19 +253,16 @@ int16_t TemperatureSensor::get_temperature_c(const uint8_t addr[]) {
|
|||||||
LOG_ERROR("Bus reset failed before reading scratchpad from %s", Sensor(addr).id());
|
LOG_ERROR("Bus reset failed before reading scratchpad from %s", Sensor(addr).id());
|
||||||
return EMS_VALUE_INT16_NOTSET;
|
return EMS_VALUE_INT16_NOTSET;
|
||||||
}
|
}
|
||||||
YIELD;
|
|
||||||
|
|
||||||
uint8_t scratchpad[SCRATCHPAD_LEN] = {0};
|
uint8_t scratchpad[SCRATCHPAD_LEN] = {0};
|
||||||
bus_.select(addr);
|
bus_.select(addr);
|
||||||
bus_.write(CMD_READ_SCRATCHPAD);
|
bus_.write(CMD_READ_SCRATCHPAD);
|
||||||
bus_.read_bytes(scratchpad, SCRATCHPAD_LEN);
|
bus_.read_bytes(scratchpad, SCRATCHPAD_LEN);
|
||||||
YIELD;
|
|
||||||
|
|
||||||
if (!bus_.reset()) {
|
if (!bus_.reset()) {
|
||||||
LOG_ERROR("Bus reset failed after reading scratchpad from %s", Sensor(addr).id());
|
LOG_ERROR("Bus reset failed after reading scratchpad from %s", Sensor(addr).id());
|
||||||
return EMS_VALUE_INT16_NOTSET;
|
return EMS_VALUE_INT16_NOTSET;
|
||||||
}
|
}
|
||||||
YIELD;
|
|
||||||
|
|
||||||
if (bus_.crc8(scratchpad, SCRATCHPAD_LEN - 1) != scratchpad[SCRATCHPAD_LEN - 1]) {
|
if (bus_.crc8(scratchpad, SCRATCHPAD_LEN - 1) != scratchpad[SCRATCHPAD_LEN - 1]) {
|
||||||
LOG_WARNING("Invalid scratchpad CRC: %02X%02X%02X%02X%02X%02X%02X%02X%02X from sensor %s",
|
LOG_WARNING("Invalid scratchpad CRC: %02X%02X%02X%02X%02X%02X%02X%02X%02X from sensor %s",
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
for (uint8_t i = 0; i < monitor_size; i++) {
|
for (uint8_t i = 0; i < monitor_size; i++) {
|
||||||
register_telegram_type(monitor_typeids[i], "RC300Monitor", false, MAKE_PF_CB(process_RC300Monitor), 33);
|
register_telegram_type(monitor_typeids[i], "RC300Monitor", false, MAKE_PF_CB(process_RC300Monitor), 33);
|
||||||
register_telegram_type(set_typeids[i], "RC300Set", false, MAKE_PF_CB(process_RC300Set), 29);
|
register_telegram_type(set_typeids[i], "RC300Set", false, MAKE_PF_CB(process_RC300Set), 29);
|
||||||
register_telegram_type(summer_typeids[i], "RC300Summer", false, MAKE_PF_CB(process_RC300Summer), 13);
|
register_telegram_type(summer_typeids[i], "RC300Summer", false, MAKE_PF_CB(process_RC300Summer), 14);
|
||||||
register_telegram_type(curve_typeids[i], "RC300Curves", false, MAKE_PF_CB(process_RC300Curve), 9);
|
register_telegram_type(curve_typeids[i], "RC300Curves", false, MAKE_PF_CB(process_RC300Curve), 9);
|
||||||
register_telegram_type(summer2_typeids[i], "RC300Summer2", false, MAKE_PF_CB(process_RC300Summer2), 8);
|
register_telegram_type(summer2_typeids[i], "RC300Summer2", false, MAKE_PF_CB(process_RC300Summer2), 8);
|
||||||
}
|
}
|
||||||
@@ -202,11 +202,12 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
if (model == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
if (model == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
||||||
register_telegram_type(0x43F, "CRHolidays", true, MAKE_PF_CB(process_RC300Holiday), 6);
|
register_telegram_type(0x43F, "CRHolidays", true, MAKE_PF_CB(process_RC300Holiday), 6);
|
||||||
} else {
|
} else {
|
||||||
register_telegram_type(0x269, "RC300Holiday", true, MAKE_PF_CB(process_RC300Holiday), 6);
|
register_telegram_type(0x269, "RC300Holiday", true, MAKE_PF_CB(process_RC300Holiday), 18);
|
||||||
}
|
}
|
||||||
register_telegram_type(0x16E, "Absent", true, MAKE_PF_CB(process_Absent), 1);
|
register_telegram_type(0x16E, "Absent", true, MAKE_PF_CB(process_Absent), 1);
|
||||||
register_telegram_type(0xBF, "ErrorMessage", false, MAKE_PF_CB(process_ErrorMessageBF));
|
register_telegram_type(0xBF, "ErrorMessage", false, MAKE_PF_CB(process_ErrorMessageBF));
|
||||||
register_telegram_type(0xC0, "RCErrorMessage", false, MAKE_PF_CB(process_RCErrorMessage2));
|
register_telegram_type(0xC0, "RCErrorMessage", false, MAKE_PF_CB(process_RCErrorMessage2));
|
||||||
|
register_telegram_type(0x470, "RC300Summer2", true, MAKE_PF_CB(process_RC300Summer2), 8);
|
||||||
EMSESP::send_read_request(0xC0, device_id, 0, 20); // read last errorcode on start (only published on errors)
|
EMSESP::send_read_request(0xC0, device_id, 0, 20); // read last errorcode on start (only published on errors)
|
||||||
|
|
||||||
// JUNKERS/HT3
|
// JUNKERS/HT3
|
||||||
@@ -1268,7 +1269,13 @@ void Thermostat::process_RC300Summer(std::shared_ptr<const Telegram> telegram) {
|
|||||||
void Thermostat::process_RC300Summer2(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RC300Summer2(std::shared_ptr<const Telegram> telegram) {
|
||||||
auto hc = heating_circuit(telegram);
|
auto hc = heating_circuit(telegram);
|
||||||
if (hc == nullptr) {
|
if (hc == nullptr) {
|
||||||
return;
|
// telegram 0x470 see https://github.com/emsesp/EMS-ESP32/issues/2686
|
||||||
|
if (telegram->type_id == 0x470 && telegram->message_length > 2) {
|
||||||
|
hc = heating_circuit(1);
|
||||||
|
summer2_typeids[0] = 0x470;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hc->statusbyte & 1) {
|
if (hc->statusbyte & 1) {
|
||||||
has_update(telegram, hc->summersetmode, 0);
|
has_update(telegram, hc->summersetmode, 0);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define EMSESP_APP_VERSION "3.8.2-dev.16"
|
#define EMSESP_APP_VERSION "3.8.2-dev.22"
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
|||||||
uart_telegram({0x08, 0x98, 0x33, 0x00, 0x23, 0x24});
|
uart_telegram({0x08, 0x98, 0x33, 0x00, 0x23, 0x24});
|
||||||
|
|
||||||
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
// Thermostat RCPLUSStatusMessage_HC1(0x01A5)
|
// Thermostat RCPLUSStatusMessage_HC1(0x01A5)
|
||||||
uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24,
|
uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24,
|
||||||
@@ -89,7 +89,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
|||||||
|
|
||||||
add_device(0x08, 219); // Greenstar HIU/Logamax kompakt WS170
|
add_device(0x08, 219); // Greenstar HIU/Logamax kompakt WS170
|
||||||
|
|
||||||
// [emsesp] boiler(0x08) -W-> Me(0x0B), UBAMonitorFastPlus(0xE4), data: 00 01 35 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00 (offset 6)
|
// [emsesp] boiler(0x08) -W-> Me(0x49), UBAMonitorFastPlus(0xE4), data: 00 01 35 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 00 (offset 6)
|
||||||
uart_telegram({0x08, 0x00, 0xE4, 0x00, //
|
uart_telegram({0x08, 0x00, 0xE4, 0x00, //
|
||||||
00, 01, 0x35, 00, 00, 00, 00, 00, 00, 00, 00, 0x80, 00, 00, 00, 00, 00, 00, 00, 0x80, 00});
|
00, 01, 0x35, 00, 00, 00, 00, 00, 00, 00, 00, 0x80, 00, 00, 00, 00, 00, 00, 00, 0x80, 00});
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
|||||||
uart_telegram({0x08, 0x90, 0x33, 0x00, 0x23, 0x24});
|
uart_telegram({0x08, 0x90, 0x33, 0x00, 0x23, 0x24});
|
||||||
|
|
||||||
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
// Thermostat 0x2A5 for HC1
|
// Thermostat 0x2A5 for HC1
|
||||||
uart_telegram({0x10, 00, 0xFF, 00, 01, 0xA5, 0x80, 00, 01, 0x30, 0x28, 00, 0x30, 0x28, 01, 0x54,
|
uart_telegram({0x10, 00, 0xFF, 00, 01, 0xA5, 0x80, 00, 01, 0x30, 0x28, 00, 0x30, 0x28, 01, 0x54,
|
||||||
@@ -144,7 +144,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
|||||||
uart_telegram({0x08, 0x90, 0x33, 0x00, 0x23, 0x24});
|
uart_telegram({0x08, 0x90, 0x33, 0x00, 0x23, 0x24});
|
||||||
|
|
||||||
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
// Thermostat 0x2A5 for HC1
|
// Thermostat 0x2A5 for HC1
|
||||||
uart_telegram({0x10, 00, 0xFF, 00, 01, 0xA5, 0x80, 00, 01, 0x30, 0x28, 00, 0x30, 0x28, 01, 0x54,
|
uart_telegram({0x10, 00, 0xFF, 00, 01, 0xA5, 0x80, 00, 01, 0x30, 0x28, 00, 0x30, 0x28, 01, 0x54,
|
||||||
@@ -160,7 +160,7 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
|||||||
EMSESP::logger().notice("Adding a Gateway...");
|
EMSESP::logger().notice("Adding a Gateway...");
|
||||||
|
|
||||||
// add 0x48 KM200, via a version command
|
// add 0x48 KM200, via a version command
|
||||||
rx_telegram({0x48, 0x0B, 0x02, 0x00, 0xBD, 0x04, 0x06, 00, 00, 00, 00, 00, 00, 00});
|
rx_telegram({0x48, 0x49, 0x02, 0x00, 0xBD, 0x04, 0x06, 00, 00, 00, 00, 00, 00, 00});
|
||||||
|
|
||||||
// Boiler(0x08) -> All(0x00), UBADevices(0x07), data: 09 01 00 00 00 00 00 00 01 00 00 00 00
|
// Boiler(0x08) -> All(0x00), UBADevices(0x07), data: 09 01 00 00 00 00 00 00 01 00 00 00 00
|
||||||
// check: make sure 0x48 is not detected again !
|
// check: make sure 0x48 is not detected again !
|
||||||
@@ -203,14 +203,14 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
|||||||
add_device(0x08, 123); // Nefit Trendline
|
add_device(0x08, 123); // Nefit Trendline
|
||||||
|
|
||||||
// UBAuptime
|
// UBAuptime
|
||||||
uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70});
|
uart_telegram({0x08, 0x49, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70});
|
||||||
|
|
||||||
// Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25)
|
// Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25)
|
||||||
uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A,
|
uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A,
|
||||||
0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00});
|
0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00});
|
||||||
|
|
||||||
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -234,10 +234,10 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
|
|||||||
add_device(0x30, 163); // SM100
|
add_device(0x30, 163); // SM100
|
||||||
|
|
||||||
// SM100Monitor - type 0x0362 EMS+ - for SM100 and SM200
|
// SM100Monitor - type 0x0362 EMS+ - for SM100 and SM200
|
||||||
uart_telegram({0xB0, 0x0B, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00,
|
uart_telegram({0xB0, 0x49, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00,
|
||||||
0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80});
|
0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80});
|
||||||
|
|
||||||
uart_telegram({0xB0, 0x0B, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00,
|
uart_telegram({0xB0, 0x49, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00,
|
||||||
0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33});
|
0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33});
|
||||||
|
|
||||||
uart_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8});
|
uart_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8});
|
||||||
@@ -580,7 +580,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
add_device(0x09, 206); // Nefit Excellent HR30 Controller
|
add_device(0x09, 206); // Nefit Excellent HR30 Controller
|
||||||
|
|
||||||
// UBAuptime
|
// UBAuptime
|
||||||
uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70});
|
uart_telegram({0x08, 0x49, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70});
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,10 +588,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
EMSESP::logger().notice("Testing 620...");
|
EMSESP::logger().notice("Testing 620...");
|
||||||
|
|
||||||
// Version Controller
|
// Version Controller
|
||||||
uart_telegram({0x09, 0x0B, 0x02, 0x00, 0x5F, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
uart_telegram({0x09, 0x49, 0x02, 0x00, 0x5F, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||||
|
|
||||||
// Version Boiler
|
// Version Boiler
|
||||||
uart_telegram({0x08, 0x0B, 0x02, 0x00, 0x5F, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
uart_telegram({0x08, 0x49, 0x02, 0x00, 0x5F, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,7 +607,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
|
|
||||||
// simulate getting version information back from an unknown device
|
// simulate getting version information back from an unknown device
|
||||||
// note there is no brand (byte 9)
|
// note there is no brand (byte 9)
|
||||||
rx_telegram({0x09, 0x0B, 0x02, 0x00, 0x59, 0x09, 0x0a});
|
rx_telegram({0x09, 0x49, 0x02, 0x00, 0x59, 0x09, 0x0a});
|
||||||
|
|
||||||
shell.invoke_command("show devices");
|
shell.invoke_command("show devices");
|
||||||
shell.invoke_command("call system report");
|
shell.invoke_command("call system report");
|
||||||
@@ -618,7 +618,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
shell.printfln("Testing unknown2...");
|
shell.printfln("Testing unknown2...");
|
||||||
|
|
||||||
// simulate getting version information back from an unknown device
|
// simulate getting version information back from an unknown device
|
||||||
rx_telegram({0x09, 0x0B, 0x02, 0x00, 0x5A, 0x01, 0x02}); // productID is 90 which doesn't exist
|
rx_telegram({0x09, 0x49, 0x02, 0x00, 0x5A, 0x01, 0x02}); // productID is 90 which doesn't exist
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -815,9 +815,9 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
// test("thermostat");
|
// test("thermostat");
|
||||||
|
|
||||||
// 0xC2
|
// 0xC2
|
||||||
// [emsesp] Boiler(0x08) -> Me(0x0B), UBAErrorMessage3(0xC2), data: 08 AC 00 10 31 48 30 31 15 80 95 0B 0E 10 38 00 7F FF FF FF 08 AC 00 10 09 41 30
|
// [emsesp] Boiler(0x08) -> Me(0x49), UBAErrorMessage3(0xC2), data: 08 AC 00 10 31 48 30 31 15 80 95 0B 0E 10 38 00 7F FF FF FF 08 AC 00 10 09 41 30
|
||||||
uart_telegram(
|
uart_telegram(
|
||||||
{0x08, 0x0B, 0xC2, 0, 0x08, 0xAC, 00, 0x10, 0x31, 0x48, 0x30, 0x31, 0x15, 0x80, 0x95, 0x0B, 0x0E, 0x10, 0x38, 00, 0x7F, 0xFF, 0xFF, 0xFF});
|
{0x08, 0x49, 0xC2, 0, 0x08, 0xAC, 00, 0x10, 0x31, 0x48, 0x30, 0x31, 0x15, 0x80, 0x95, 0x0B, 0x0E, 0x10, 0x38, 00, 0x7F, 0xFF, 0xFF, 0xFF});
|
||||||
|
|
||||||
// shell.invoke_command("show values");
|
// shell.invoke_command("show values");
|
||||||
|
|
||||||
@@ -1042,7 +1042,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
// Boiler -> Me, UBAParameterWW(0x33)
|
// Boiler -> Me, UBAParameterWW(0x33)
|
||||||
// wwseltemp = goes from 52 degrees (0x34) to void (0xFF)
|
// wwseltemp = goes from 52 degrees (0x34) to void (0xFF)
|
||||||
// it should delete the HA config topic homeassistant/sensor/ems-esp/boiler_wwseltemp/config
|
// it should delete the HA config topic homeassistant/sensor/ems-esp/boiler_wwseltemp/config
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0xFF, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0xFF, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
shell.invoke_command("call boiler wwseltemp");
|
shell.invoke_command("call boiler wwseltemp");
|
||||||
shell.invoke_command("call system publish");
|
shell.invoke_command("call system publish");
|
||||||
@@ -1795,7 +1795,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
add_device(0x18, 202); // Bosch TC100 - https://github.com/emsesp/EMS-ESP/issues/474
|
add_device(0x18, 202); // Bosch TC100 - https://github.com/emsesp/EMS-ESP/issues/474
|
||||||
|
|
||||||
// 0x0A
|
// 0x0A
|
||||||
uart_telegram({0x98, 0x0B, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
uart_telegram({0x98, 0x49, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
@@ -1829,10 +1829,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
|
|
||||||
// SM100Monitor - type 0x0362 EMS+ - for SM100 and SM200
|
// SM100Monitor - type 0x0362 EMS+ - for SM100 and SM200
|
||||||
// B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80
|
// B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80
|
||||||
rx_telegram({0xB0, 0x0B, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00,
|
rx_telegram({0xB0, 0x49, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00,
|
||||||
0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80});
|
0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80});
|
||||||
|
|
||||||
rx_telegram({0xB0, 0x0B, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00,
|
rx_telegram({0xB0, 0x49, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00,
|
||||||
0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33});
|
0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33});
|
||||||
|
|
||||||
rx_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8});
|
rx_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8});
|
||||||
@@ -1936,7 +1936,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
if (command == "rx2") {
|
if (command == "rx2") {
|
||||||
shell.printfln("Testing Rx2...");
|
shell.printfln("Testing Rx2...");
|
||||||
for (uint8_t i = 0; i < 30; i++) {
|
for (uint8_t i = 0; i < 30; i++) {
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1953,23 +1953,23 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
uart_telegram({0x08, 0x97, 0x33, 0x00, 0x23, 0x24});
|
uart_telegram({0x08, 0x97, 0x33, 0x00, 0x23, 0x24});
|
||||||
|
|
||||||
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
// Thermostat -> Me, RC20StatusMessage(0x91), telegram: 17 0B 91 05 44 45 46 47 (#data=4)
|
// Thermostat -> Me, RC20StatusMessage(0x91), telegram: 17 0B 91 05 44 45 46 47 (#data=4)
|
||||||
uart_telegram({0x17, 0x0B, 0x91, 0x05, 0x44, 0x45, 0x46, 0x47});
|
uart_telegram({0x17, 0x49, 0x91, 0x05, 0x44, 0x45, 0x46, 0x47});
|
||||||
|
|
||||||
// bad CRC - corrupt telegram - CRC should be 0x8E
|
// bad CRC - corrupt telegram - CRC should be 0x8E
|
||||||
uint8_t t5[] = {0x17, 0x0B, 0x91, 0x05, 0x44, 0x45, 0x46, 0x47, 0x99};
|
uint8_t t5[] = {0x17, 0x49, 0x91, 0x05, 0x44, 0x45, 0x46, 0x47, 0x99};
|
||||||
EMSESP::rxservice_.add(t5, sizeof(t5));
|
EMSESP::rxservice_.add(t5, sizeof(t5));
|
||||||
|
|
||||||
// simulating a Tx record
|
// simulating a Tx record
|
||||||
uart_telegram({0x0B, 0x88, 0x07, 0x00, 0x20});
|
uart_telegram({0x49, 0x88, 0x07, 0x00, 0x20});
|
||||||
|
|
||||||
// Version Boiler
|
// Version Boiler
|
||||||
uart_telegram({0x08, 0x0B, 0x02, 0x00, 0x7B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04});
|
uart_telegram({0x08, 0x49, 0x02, 0x00, 0x7B, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04});
|
||||||
|
|
||||||
// Version Thermostat, device_id 0x11
|
// Version Thermostat, device_id 0x11
|
||||||
uart_telegram({0x11, 0x0B, 0x02, 0x00, 0x4D, 0x03, 0x03});
|
uart_telegram({0x11, 0x49, 0x02, 0x00, 0x4D, 0x03, 0x03});
|
||||||
|
|
||||||
// Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00
|
// Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00
|
||||||
// 0x1A5 test ems+
|
// 0x1A5 test ems+
|
||||||
@@ -1987,7 +1987,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
uart_telegram({0x17, 0x08, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00});
|
uart_telegram({0x17, 0x08, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00});
|
||||||
|
|
||||||
// Thermostat -> Me, RC20Set(0xA8), telegram: 17 0B A8 00 01 00 FF F6 01 06 00 01 0D 01 00 FF FF 01 02 02 02 00 00 05 1F 05 1F 02 0E 00 FF (#data=27)
|
// Thermostat -> Me, RC20Set(0xA8), telegram: 17 0B A8 00 01 00 FF F6 01 06 00 01 0D 01 00 FF FF 01 02 02 02 00 00 05 1F 05 1F 02 0E 00 FF (#data=27)
|
||||||
uart_telegram({0x17, 0x0B, 0xA8, 0x00, 0x01, 0x00, 0xFF, 0xF6, 0x01, 0x06, 0x00, 0x01, 0x0D, 0x01, 0x00, 0xFF,
|
uart_telegram({0x17, 0x49, 0xA8, 0x00, 0x01, 0x00, 0xFF, 0xF6, 0x01, 0x06, 0x00, 0x01, 0x0D, 0x01, 0x00, 0xFF,
|
||||||
0xFF, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x05, 0x1F, 0x05, 0x1F, 0x02, 0x0E, 0x00, 0xFF});
|
0xFF, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x05, 0x1F, 0x05, 0x1F, 0x02, 0x0E, 0x00, 0xFF});
|
||||||
|
|
||||||
// Boiler(0x08) -> All(0x00), UBAMonitorWW(0x34), data: 36 01 A5 80 00 21 00 00 01 00 01 3E 8D 03 77 91 00 80 00
|
// Boiler(0x08) -> All(0x00), UBAMonitorWW(0x34), data: 36 01 A5 80 00 21 00 00 01 00 01 3E 8D 03 77 91 00 80 00
|
||||||
@@ -2021,7 +2021,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
EMSESP::send_write_request(0x91, 0x17, 0x00, t18, sizeof(t18), 0x00);
|
EMSESP::send_write_request(0x91, 0x17, 0x00, t18, sizeof(t18), 0x00);
|
||||||
|
|
||||||
// TX - send EMS+
|
// TX - send EMS+
|
||||||
const uint8_t t13[] = {0x90, 0x0B, 0xFF, 00, 01, 0xBA, 00, 0x2E, 0x2A, 0x26, 0x1E, 0x03,
|
const uint8_t t13[] = {0x90, 0x49, 0xFF, 00, 01, 0xBA, 00, 0x2E, 0x2A, 0x26, 0x1E, 0x03,
|
||||||
00, 0xFF, 0xFF, 05, 0x2A, 01, 0xE1, 0x20, 0x01, 0x0F, 05, 0x2A};
|
00, 0xFF, 0xFF, 05, 0x2A, 01, 0xE1, 0x20, 0x01, 0x0F, 05, 0x2A};
|
||||||
EMSESP::txservice_.add(Telegram::Operation::TX_RAW, t13, sizeof(t13), 0);
|
EMSESP::txservice_.add(Telegram::Operation::TX_RAW, t13, sizeof(t13), 0);
|
||||||
|
|
||||||
@@ -2145,7 +2145,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
uart_telegram({0x08, 0x98, 0x33, 0x00, 0x23, 0x24});
|
uart_telegram({0x08, 0x98, 0x33, 0x00, 0x23, 0x24});
|
||||||
|
|
||||||
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
// add a thermostat
|
// add a thermostat
|
||||||
add_device(0x18, 157); // Bosch CR100
|
add_device(0x18, 157); // Bosch CR100
|
||||||
@@ -2487,7 +2487,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
if (command == "rx3") {
|
if (command == "rx3") {
|
||||||
shell.printfln("Testing rx3...");
|
shell.printfln("Testing rx3...");
|
||||||
|
|
||||||
uart_telegram({0x21, 0x0B, 0xFF, 0x00});
|
uart_telegram({0x21, 0x49, 0xFF, 0x00});
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2495,7 +2495,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
if (command == "tx2") {
|
if (command == "tx2") {
|
||||||
shell.printfln("Testing tx2...");
|
shell.printfln("Testing tx2...");
|
||||||
|
|
||||||
uint8_t t[] = {0x0B, 0x88, 0x18, 0x00, 0x20, 0xD4}; // including CRC
|
uint8_t t[] = {0x49, 0x88, 0x18, 0x00, 0x20, 0xD4}; // including CRC
|
||||||
EMSuart::transmit(t, sizeof(t));
|
EMSuart::transmit(t, sizeof(t));
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,8 +149,10 @@ uint8_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
|
|||||||
return EMS_TX_STATUS_OK;
|
return EMS_TX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto tx_mode = tx_mode_ != EMS_TXMODE_AUTO ? tx_mode_ : EMSbus::is_ht3() ? EMS_TXMODE_HT3 : EMSbus::is_ems2() ? EMS_TXMODE_EMSPLUS : EMS_TXMODE_EMS;
|
||||||
|
|
||||||
// TXMODE is EMS+ with long delay
|
// TXMODE is EMS+ with long delay
|
||||||
if (tx_mode_ == EMS_TXMODE_EMSPLUS) {
|
if (tx_mode == EMS_TXMODE_EMSPLUS) {
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
uart_write_bytes(EMSUART_NUM, &buf[i], 1);
|
uart_write_bytes(EMSUART_NUM, &buf[i], 1);
|
||||||
delayMicroseconds(EMSUART_TX_WAIT_PLUS);
|
delayMicroseconds(EMSUART_TX_WAIT_PLUS);
|
||||||
@@ -160,7 +162,7 @@ uint8_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TXMODE is HT3 with 7 bittimes delay
|
// TXMODE is HT3 with 7 bittimes delay
|
||||||
if (tx_mode_ == EMS_TXMODE_HT3) {
|
if (tx_mode == EMS_TXMODE_HT3) {
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
uart_write_bytes(EMSUART_NUM, &buf[i], 1);
|
uart_write_bytes(EMSUART_NUM, &buf[i], 1);
|
||||||
delayMicroseconds(EMSUART_TX_WAIT_HT3);
|
delayMicroseconds(EMSUART_TX_WAIT_HT3);
|
||||||
|
|||||||
@@ -42,10 +42,11 @@
|
|||||||
|
|
||||||
#define EMS_TXMODE_INIT 0xFF
|
#define EMS_TXMODE_INIT 0xFF
|
||||||
#define EMS_TXMODE_OFF 0
|
#define EMS_TXMODE_OFF 0
|
||||||
#define EMS_TXMODE_DEFAULT 1
|
#define EMS_TXMODE_EMS 1
|
||||||
#define EMS_TXMODE_EMSPLUS 2
|
#define EMS_TXMODE_EMSPLUS 2
|
||||||
#define EMS_TXMODE_HT3 3
|
#define EMS_TXMODE_HT3 3
|
||||||
#define EMS_TXMODE_HW 4
|
#define EMS_TXMODE_HW 4
|
||||||
|
#define EMS_TXMODE_AUTO 5
|
||||||
|
|
||||||
// LEGACY
|
// LEGACY
|
||||||
#define EMSUART_TX_BIT_TIME 104 // bit time @9600 baud
|
#define EMSUART_TX_BIT_TIME 104 // bit time @9600 baud
|
||||||
|
|||||||
@@ -166,7 +166,9 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
|
|||||||
bool WebCustomEntityService::command_setvalue(const char * value, const int8_t id, const char * name) {
|
bool WebCustomEntityService::command_setvalue(const char * value, const int8_t id, const char * name) {
|
||||||
// don't write if there is no value, to prevent setting an empty value by mistake when parsing attributes
|
// don't write if there is no value, to prevent setting an empty value by mistake when parsing attributes
|
||||||
if (!strlen(value)) {
|
if (!strlen(value)) {
|
||||||
|
#if defined(EMSESP_DEBUG)
|
||||||
EMSESP::logger().debug("can't set empty value!");
|
EMSESP::logger().debug("can't set empty value!");
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,7 +688,7 @@ void WebCustomEntityService::fetch() {
|
|||||||
uint8_t stop = (entity.offset + len[entity.value_type]) % fetchblock;
|
uint8_t stop = (entity.offset + len[entity.value_type]) % fetchblock;
|
||||||
bool is_fetched = start < fetchblock && stop < fetchblock; // make sure the complete value is a a fetched block
|
bool is_fetched = start < fetchblock && stop < fetchblock; // make sure the complete value is a a fetched block
|
||||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||||
if (emsdevice->is_device_id(entity.device_id) && emsdevice->is_fetch(entity.type_id)
|
if (emsdevice->is_device_id(entity.device_id) && emsdevice->is_fetch(entity.type_id, entity.offset + len[entity.value_type])
|
||||||
&& (is_fetched || entity.value_type == DeviceValueType::STRING)) {
|
&& (is_fetched || entity.value_type == DeviceValueType::STRING)) {
|
||||||
needFetch = false;
|
needFetch = false;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -465,7 +465,9 @@ void WebSchedulerService::condition() {
|
|||||||
} else if (match.length() == 1 && match[0] == '0' && scheduleItem.retry_cnt == 1) {
|
} else if (match.length() == 1 && match[0] == '0' && scheduleItem.retry_cnt == 1) {
|
||||||
scheduleItem.retry_cnt = 0xFF;
|
scheduleItem.retry_cnt = 0xFF;
|
||||||
} else if (match.length() != 1) { // the match is not boolean
|
} else if (match.length() != 1) { // the match is not boolean
|
||||||
|
#if defined(EMSESP_DEBUG)
|
||||||
EMSESP::logger().debug("condition result: %s", match.c_str());
|
EMSESP::logger().debug("condition result: %s", match.c_str());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
uint8_t WebSettings::flags_ = 0;
|
uint16_t WebSettings::flags_ = 0;
|
||||||
|
|
||||||
WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||||
: _httpEndpoint(WebSettings::read, WebSettings::update, this, server, EMSESP_SETTINGS_SERVICE_PATH, securityManager)
|
: _httpEndpoint(WebSettings::read, WebSettings::update, this, server, EMSESP_SETTINGS_SERVICE_PATH, securityManager)
|
||||||
@@ -114,11 +114,11 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
|||||||
reset_flags();
|
reset_flags();
|
||||||
|
|
||||||
// before loading new board profile free old gpios from used list to allow remapping
|
// before loading new board profile free old gpios from used list to allow remapping
|
||||||
EMSESP::system_.remove_gpio(original_settings.led_gpio);
|
EMSESP::system_.remove_optional_gpio(original_settings.led_gpio);
|
||||||
EMSESP::system_.remove_gpio(original_settings.dallas_gpio);
|
EMSESP::system_.remove_optional_gpio(original_settings.dallas_gpio);
|
||||||
EMSESP::system_.remove_gpio(original_settings.pbutton_gpio);
|
EMSESP::system_.remove_gpio(original_settings.pbutton_gpio);
|
||||||
EMSESP::system_.remove_gpio(original_settings.rx_gpio);
|
EMSESP::system_.remove_optional_gpio(original_settings.rx_gpio);
|
||||||
EMSESP::system_.remove_gpio(original_settings.tx_gpio);
|
EMSESP::system_.remove_optional_gpio(original_settings.tx_gpio);
|
||||||
|
|
||||||
// see if the user has changed the board profile
|
// see if the user has changed the board profile
|
||||||
// this will set: led_gpio, dallas_gpio, rx_gpio, tx_gpio, pbutton_gpio, phy_type, eth_power, eth_phy_addr, eth_clock_mode, led_type
|
// this will set: led_gpio, dallas_gpio, rx_gpio, tx_gpio, pbutton_gpio, phy_type, eth_power, eth_phy_addr, eth_clock_mode, led_type
|
||||||
@@ -243,13 +243,13 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
|||||||
|
|
||||||
// Modbus settings
|
// Modbus settings
|
||||||
settings.modbus_enabled = root["modbus_enabled"] | EMSESP_DEFAULT_MODBUS_ENABLED;
|
settings.modbus_enabled = root["modbus_enabled"] | EMSESP_DEFAULT_MODBUS_ENABLED;
|
||||||
check_flag(original_settings.modbus_enabled, settings.modbus_enabled, ChangeFlags::RESTART);
|
check_flag(original_settings.modbus_enabled, settings.modbus_enabled, ChangeFlags::MODBUS);
|
||||||
settings.modbus_port = root["modbus_port"] | EMSESP_DEFAULT_MODBUS_PORT;
|
settings.modbus_port = root["modbus_port"] | EMSESP_DEFAULT_MODBUS_PORT;
|
||||||
check_flag(original_settings.modbus_port, settings.modbus_port, ChangeFlags::RESTART);
|
check_flag(original_settings.modbus_port, settings.modbus_port, ChangeFlags::MODBUS);
|
||||||
settings.modbus_max_clients = root["modbus_max_clients"] | EMSESP_DEFAULT_MODBUS_MAX_CLIENTS;
|
settings.modbus_max_clients = root["modbus_max_clients"] | EMSESP_DEFAULT_MODBUS_MAX_CLIENTS;
|
||||||
check_flag(original_settings.modbus_max_clients, settings.modbus_max_clients, ChangeFlags::RESTART);
|
check_flag(original_settings.modbus_max_clients, settings.modbus_max_clients, ChangeFlags::MODBUS);
|
||||||
settings.modbus_timeout = root["modbus_timeout"] | EMSESP_DEFAULT_MODBUS_TIMEOUT;
|
settings.modbus_timeout = root["modbus_timeout"] | EMSESP_DEFAULT_MODBUS_TIMEOUT;
|
||||||
check_flag(original_settings.modbus_timeout, settings.modbus_timeout, ChangeFlags::RESTART);
|
check_flag(original_settings.modbus_timeout, settings.modbus_timeout, ChangeFlags::MODBUS);
|
||||||
|
|
||||||
//
|
//
|
||||||
// these may need mqtt restart to rebuild HA discovery topics
|
// these may need mqtt restart to rebuild HA discovery topics
|
||||||
@@ -372,7 +372,11 @@ void WebSettingsService::onUpdate() {
|
|||||||
Mqtt::reset_mqtt(); // reload MQTT, init HA etc
|
Mqtt::reset_mqtt(); // reload MQTT, init HA etc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WebSettings::has_flags(WebSettings::ChangeFlags::MODBUS)) {
|
||||||
|
EMSESP::system_.modbus_init();
|
||||||
|
}
|
||||||
WebSettings::reset_flags();
|
WebSettings::reset_flags();
|
||||||
|
EMSESP::system_.reset_unused_gpios();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSettingsService::begin() {
|
void WebSettingsService::begin() {
|
||||||
@@ -523,7 +527,7 @@ void WebSettings::set_board_profile(WebSettings & settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns true if the value was changed
|
// returns true if the value was changed
|
||||||
bool WebSettings::check_flag(int prev_v, int new_v, uint8_t flag) {
|
bool WebSettings::check_flag(int prev_v, int new_v, uint16_t flag) {
|
||||||
if (prev_v != new_v) {
|
if (prev_v != new_v) {
|
||||||
add_flags(flag);
|
add_flags(flag);
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
@@ -534,11 +538,11 @@ bool WebSettings::check_flag(int prev_v, int new_v, uint8_t flag) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSettings::add_flags(uint8_t flags) {
|
void WebSettings::add_flags(uint16_t flags) {
|
||||||
flags_ |= flags;
|
flags_ |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebSettings::has_flags(uint8_t flags) {
|
bool WebSettings::has_flags(uint16_t flags) {
|
||||||
return (flags_ & flags) == flags;
|
return (flags_ & flags) == flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,7 +550,7 @@ void WebSettings::reset_flags() {
|
|||||||
flags_ = ChangeFlags::NONE;
|
flags_ = ChangeFlags::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WebSettings::get_flags() {
|
uint16_t WebSettings::get_flags() {
|
||||||
return flags_;
|
return flags_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class WebSettings {
|
|||||||
static void read(WebSettings & settings, JsonObject root);
|
static void read(WebSettings & settings, JsonObject root);
|
||||||
static StateUpdateResult update(JsonObject root, WebSettings & settings);
|
static StateUpdateResult update(JsonObject root, WebSettings & settings);
|
||||||
|
|
||||||
enum ChangeFlags : uint8_t {
|
enum ChangeFlags : uint16_t {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
UART = (1 << 0), // 1 - uart
|
UART = (1 << 0), // 1 - uart
|
||||||
SYSLOG = (1 << 1), // 2 - syslog
|
SYSLOG = (1 << 1), // 2 - syslog
|
||||||
@@ -98,19 +98,20 @@ class WebSettings {
|
|||||||
LED = (1 << 5), // 32 - led
|
LED = (1 << 5), // 32 - led
|
||||||
BUTTON = (1 << 6), // 64 - button
|
BUTTON = (1 << 6), // 64 - button
|
||||||
MQTT = (1 << 7), // 128 - mqtt
|
MQTT = (1 << 7), // 128 - mqtt
|
||||||
RESTART = 0xFF // 255 - restart request (all changes)
|
MODBUS = (1 << 8), // 256 - modbus
|
||||||
|
RESTART = 0xFFFF // restart request (all changes)
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool check_flag(int prev_v, int new_v, uint8_t flag);
|
static bool check_flag(int prev_v, int new_v, uint16_t flag);
|
||||||
static void add_flags(uint8_t flags);
|
static void add_flags(uint16_t flags);
|
||||||
static bool has_flags(uint8_t flags);
|
static bool has_flags(uint16_t flags);
|
||||||
static void reset_flags();
|
static void reset_flags();
|
||||||
static uint8_t get_flags();
|
static uint16_t get_flags();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void set_board_profile(WebSettings & settings);
|
static void set_board_profile(WebSettings & settings);
|
||||||
|
|
||||||
static uint8_t flags_;
|
static uint16_t flags_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebSettingsService : public StatefulService<WebSettings> {
|
class WebSettingsService : public StatefulService<WebSettings> {
|
||||||
|
|||||||
@@ -296,10 +296,6 @@ uint8_t WebStatusService::upgradeImportantMessages(std::string & version) {
|
|||||||
|
|
||||||
version::EMSESP_Version current_version(current_version_s); // get current version
|
version::EMSESP_Version current_version(current_version_s); // get current version
|
||||||
|
|
||||||
if (latest_version > current_version && current_version.minor() < latest_version.minor()) {
|
|
||||||
return 0; // if it's just a minor version upgrade return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((current_version.major() <= 3 && current_version.minor() <= 8) && (latest_version.major() == 3 && latest_version.minor() == 9)) {
|
if ((current_version.major() <= 3 && current_version.minor() <= 8) && (latest_version.major() == 3 && latest_version.minor() == 9)) {
|
||||||
return 1; // if moving from below 3.8.x to 3.9.x return 1
|
return 1; // if moving from below 3.8.x to 3.9.x return 1
|
||||||
}
|
}
|
||||||
@@ -308,6 +304,10 @@ uint8_t WebStatusService::upgradeImportantMessages(std::string & version) {
|
|||||||
return 2; // if it's a major version upgrade return 2
|
return 2; // if it's a major version upgrade return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (latest_version > current_version && current_version.minor() < latest_version.minor()) {
|
||||||
|
return 0; // if it's just a minor version upgrade return 0
|
||||||
|
}
|
||||||
|
|
||||||
return 0; // if it's not a valid version upgrade return 0
|
return 0; // if it's not a valid version upgrade return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ void uart_telegram(const char * rx_data) {
|
|||||||
|
|
||||||
// add an EMS device and register it
|
// add an EMS device and register it
|
||||||
void add_device(uint8_t device_id, uint8_t product_id) {
|
void add_device(uint8_t device_id, uint8_t product_id) {
|
||||||
uart_telegram({device_id, 0x0B, EMSdevice::EMS_TYPE_VERSION, 0, product_id, 1, 0});
|
uart_telegram({device_id, 0x49, EMSdevice::EMS_TYPE_VERSION, 0, product_id, 1, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
// add our EMS test devices
|
// add our EMS test devices
|
||||||
@@ -143,14 +143,14 @@ void add_devices() {
|
|||||||
add_device(0x08, 123); // Nefit Trendline
|
add_device(0x08, 123); // Nefit Trendline
|
||||||
|
|
||||||
// UBAuptime
|
// UBAuptime
|
||||||
uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70});
|
uart_telegram({0x08, 0x49, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70});
|
||||||
|
|
||||||
// Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25)
|
// Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25)
|
||||||
uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A,
|
uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A,
|
||||||
0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00});
|
0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00});
|
||||||
|
|
||||||
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
// Boiler -> Me, UBAParameterWW(0x33), telegram: 08 49 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13)
|
||||||
uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
uart_telegram({0x08, 0x49, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00});
|
||||||
|
|
||||||
//
|
//
|
||||||
// thermostat
|
// thermostat
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ void test_23() {
|
|||||||
"\"temperatureSensorReads\":0,\"temperatureSensorFails\":0},\"analog\":{\"enabled\":true,\"analogSensors\":5,\"analogSensorReads\":0,"
|
"\"temperatureSensorReads\":0,\"temperatureSensorFails\":0},\"analog\":{\"enabled\":true,\"analogSensors\":5,\"analogSensorReads\":0,"
|
||||||
"\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\","
|
"\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\","
|
||||||
"\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0,\"busReadsFailed\":0,\"busWritesFailed\":0,"
|
"\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0,\"busReadsFailed\":0,\"busWritesFailed\":0,"
|
||||||
"\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":\"en\",\"txMode\":1,\"emsBusID\":11,"
|
"\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":\"en\",\"txMode\":5,\"emsBusID\":73,"
|
||||||
"\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false,\"readonlyMode\":false,\"fahrenheit\":"
|
"\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false,\"readonlyMode\":false,\"fahrenheit\":"
|
||||||
"false,\"dallasParasite\":false,\"boolFormat\":1,\"boolDashboard\":1,\"enumFormat\":1,\"analogEnabled\":true,\"telnetEnabled\":true,"
|
"false,\"dallasParasite\":false,\"boolFormat\":1,\"boolDashboard\":1,\"enumFormat\":1,\"analogEnabled\":true,\"telnetEnabled\":true,"
|
||||||
"\"maxWebLogBuffer\":25,\"modbusEnabled\":false,\"forceHeatingOff\":false,\"developerMode\":false},\"devices\":[{\"type\":\"boiler\",\"name\":\"My "
|
"\"maxWebLogBuffer\":25,\"modbusEnabled\":false,\"forceHeatingOff\":false,\"developerMode\":false},\"devices\":[{\"type\":\"boiler\",\"name\":\"My "
|
||||||
@@ -259,7 +259,7 @@ void test_24() {
|
|||||||
"\"temperatureSensorReads\":0,\"temperatureSensorFails\":0},\"analog\":{\"enabled\":true,\"analogSensors\":5,\"analogSensorReads\":0,"
|
"\"temperatureSensorReads\":0,\"temperatureSensorFails\":0},\"analog\":{\"enabled\":true,\"analogSensors\":5,\"analogSensorReads\":0,"
|
||||||
"\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\","
|
"\"analogSensorFails\":0},\"api\":{\"APICalls\":0,\"APIFails\":0},\"bus\":{\"busStatus\":\"connected\",\"busProtocol\":\"Buderus\","
|
||||||
"\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0,\"busReadsFailed\":0,\"busWritesFailed\":0,"
|
"\"busTelegramsReceived\":8,\"busReads\":0,\"busWrites\":0,\"busIncompleteTelegrams\":0,\"busReadsFailed\":0,\"busWritesFailed\":0,"
|
||||||
"\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":\"en\",\"txMode\":1,\"emsBusID\":11,"
|
"\"busRxLineQuality\":100,\"busTxLineQuality\":100},\"settings\":{\"boardProfile\":\"S32\",\"locale\":\"en\",\"txMode\":5,\"emsBusID\":73,"
|
||||||
"\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false,\"readonlyMode\":false,\"fahrenheit\":"
|
"\"showerTimer\":false,\"showerMinDuration\":180,\"showerAlert\":false,\"hideLed\":false,\"noTokenApi\":false,\"readonlyMode\":false,\"fahrenheit\":"
|
||||||
"false,\"dallasParasite\":false,\"boolFormat\":1,\"boolDashboard\":1,\"enumFormat\":1,\"analogEnabled\":true,\"telnetEnabled\":true,"
|
"false,\"dallasParasite\":false,\"boolFormat\":1,\"boolDashboard\":1,\"enumFormat\":1,\"analogEnabled\":true,\"telnetEnabled\":true,"
|
||||||
"\"maxWebLogBuffer\":25,\"modbusEnabled\":false,\"forceHeatingOff\":false,\"developerMode\":false},\"devices\":[{\"type\":\"boiler\",\"name\":\"My "
|
"\"maxWebLogBuffer\":25,\"modbusEnabled\":false,\"forceHeatingOff\":false,\"developerMode\":false},\"devices\":[{\"type\":\"boiler\",\"name\":\"My "
|
||||||
@@ -330,8 +330,8 @@ void test_25() {
|
|||||||
"gauge\\nemsesp_bus_buswritesfailed 0\\n# HELP emsesp_bus_busrxlinequality busRxLineQuality\\n# TYPE emsesp_bus_busrxlinequality "
|
"gauge\\nemsesp_bus_buswritesfailed 0\\n# HELP emsesp_bus_busrxlinequality busRxLineQuality\\n# TYPE emsesp_bus_busrxlinequality "
|
||||||
"gauge\\nemsesp_bus_busrxlinequality 100\\n# HELP emsesp_bus_bustxlinequality busTxLineQuality\\n# TYPE emsesp_bus_bustxlinequality "
|
"gauge\\nemsesp_bus_busrxlinequality 100\\n# HELP emsesp_bus_bustxlinequality busTxLineQuality\\n# TYPE emsesp_bus_bustxlinequality "
|
||||||
"gauge\\nemsesp_bus_bustxlinequality 100\\n# HELP emsesp_bus_info info\\n# TYPE emsesp_bus_info gauge\\nemsesp_bus_info{busstatus=\\\"connected\\\", "
|
"gauge\\nemsesp_bus_bustxlinequality 100\\n# HELP emsesp_bus_info info\\n# TYPE emsesp_bus_info gauge\\nemsesp_bus_info{busstatus=\\\"connected\\\", "
|
||||||
"busprotocol=\\\"Buderus\\\"} 1\\n# HELP emsesp_settings_txmode txMode\\n# TYPE emsesp_settings_txmode gauge\\nemsesp_settings_txmode 1\\n# HELP "
|
"busprotocol=\\\"Buderus\\\"} 1\\n# HELP emsesp_settings_txmode txMode\\n# TYPE emsesp_settings_txmode gauge\\nemsesp_settings_txmode 5\\n# HELP "
|
||||||
"emsesp_settings_emsbusid emsBusID\\n# TYPE emsesp_settings_emsbusid gauge\\nemsesp_settings_emsbusid 11\\n# HELP emsesp_settings_showertimer "
|
"emsesp_settings_emsbusid emsBusID\\n# TYPE emsesp_settings_emsbusid gauge\\nemsesp_settings_emsbusid 73\\n# HELP emsesp_settings_showertimer "
|
||||||
"showerTimer\\n# TYPE emsesp_settings_showertimer gauge\\nemsesp_settings_showertimer 0\\n# HELP emsesp_settings_showerminduration "
|
"showerTimer\\n# TYPE emsesp_settings_showertimer gauge\\nemsesp_settings_showertimer 0\\n# HELP emsesp_settings_showerminduration "
|
||||||
"showerMinDuration\\n# TYPE emsesp_settings_showerminduration gauge\\nemsesp_settings_showerminduration 180\\n# HELP emsesp_settings_showeralert "
|
"showerMinDuration\\n# TYPE emsesp_settings_showerminduration gauge\\nemsesp_settings_showerminduration 180\\n# HELP emsesp_settings_showeralert "
|
||||||
"showerAlert\\n# TYPE emsesp_settings_showeralert gauge\\nemsesp_settings_showeralert 0\\n# HELP emsesp_settings_hideled hideLed\\n# TYPE "
|
"showerAlert\\n# TYPE emsesp_settings_showeralert gauge\\nemsesp_settings_showeralert 0\\n# HELP emsesp_settings_hideled hideLed\\n# TYPE "
|
||||||
|
|||||||
Reference in New Issue
Block a user