Merge pull request #2491 from MichaelDvP/dev

fixes and additions
This commit is contained in:
Proddy
2025-03-26 18:42:19 +01:00
committed by GitHub
20 changed files with 260 additions and 115 deletions

View File

@@ -6,11 +6,12 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
## Added
-
- analogsensor types: NTC and RGB-Led
- Flag for HMC310
## Fixed
-
- dhw/switchtime [#2490](https://github.com/emsesp/EMS-ESP32/issues/2490)
## Changed

View File

@@ -4371,7 +4371,7 @@
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
| dhw.maxtemp | maximum temperature | uint8 (>=0<=254) | C | true | DHW | 15 | 1 | 1 |
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
| dhw.switchtimeWW | program switchtime warm water | string | | true | DHW | 17 | 11 | 1 |
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 11 | 1 |
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 28 | 8 | 1 |
| dhw.holidays | holiday dates | string | | true | DHW | 36 | 13 | 1 |
| dhw.vacations | vacation dates | string | | true | DHW | 49 | 13 | 1 |
@@ -4437,7 +4437,7 @@
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
| dhw.maxtemp | maximum temperature | uint8 (>=60<=80) | C | true | DHW | 15 | 1 | 1 |
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
| dhw.switchtimeWW | program switchtime warm water | string | | true | DHW | 17 | 11 | 1 |
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 11 | 1 |
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 28 | 8 | 1 |
| dhw.holidays | holiday dates | string | | true | DHW | 36 | 13 | 1 |
| dhw.vacations | vacation dates | string | | true | DHW | 49 | 13 | 1 |
@@ -5344,7 +5344,7 @@
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
| dhw.maxtemp | maximum temperature | uint8 (>=0<=254) | C | true | DHW | 15 | 1 | 1 |
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
| dhw.switchtimeWW | program switchtime warm water | string | | true | DHW | 17 | 11 | 1 |
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 11 | 1 |
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 28 | 8 | 1 |
| dhw.holidays | holiday dates | string | | true | DHW | 36 | 13 | 1 |
| dhw.vacations | vacation dates | string | | true | DHW | 49 | 13 | 1 |
@@ -5410,7 +5410,7 @@
| dhw.disinfecthour | disinfection hour | uint8 (>=0<=23) | | true | DHW | 14 | 1 | 1 |
| dhw.maxtemp | maximum temperature | uint8 (>=60<=80) | C | true | DHW | 15 | 1 | 1 |
| dhw.onetimekey | one time key function | boolean | | true | DHW | 16 | 1 | 1 |
| dhw.switchtimeWW | program switchtime warm water | string | | true | DHW | 17 | 11 | 1 |
| dhw.switchtime | program switchtime | string | | true | DHW | 17 | 11 | 1 |
| dhw.circswitchtime | circulation program switchtime | string | | true | DHW | 28 | 8 | 1 |
| dhw.holidays | holiday dates | string | | true | DHW | 36 | 13 | 1 |
| dhw.vacations | vacation dates | string | | true | DHW | 49 | 13 | 1 |

View File

@@ -3753,7 +3753,7 @@ device name,device type,product id,shortname,fullname,type [options...] \| (min/
"RC30",thermostat,67,dhw.disinfecthour,disinfection hour,uint8 (>=0<=23), ,true,number.thermostat_dhw_disinfection_hour,number.thermostat_dhw_disinfecthour,6,9,1,14,1
"RC30",thermostat,67,dhw.maxtemp,maximum temperature,uint8 (>=0<=254),C,true,number.thermostat_dhw_maximum_temperature,number.thermostat_dhw_maxtemp,6,9,1,15,1
"RC30",thermostat,67,dhw.onetimekey,one time key function,boolean, ,true,switch.thermostat_dhw_one_time_key_function,switch.thermostat_dhw_onetimekey,6,9,1,16,1
"RC30",thermostat,67,dhw.switchtimeWW,program switchtime warm water,string, ,true,sensor.thermostat_dhw_program_switchtime_warm_water,sensor.thermostat_dhw_switchtimeWW,6,9,1,17,11
"RC30",thermostat,67,dhw.switchtime,program switchtime,string, ,true,sensor.thermostat_dhw_program_switchtime,sensor.thermostat_dhw_switchtime,6,9,1,17,11
"RC30",thermostat,67,dhw.circswitchtime,circulation program switchtime,string, ,true,sensor.thermostat_dhw_circulation_program_switchtime,sensor.thermostat_dhw_circswitchtime,6,9,1,28,8
"RC30",thermostat,67,dhw.holidays,holiday dates,string, ,true,sensor.thermostat_dhw_holiday_dates,sensor.thermostat_dhw_holidays,6,9,1,36,13
"RC30",thermostat,67,dhw.vacations,vacation dates,string, ,true,sensor.thermostat_dhw_vacation_dates,sensor.thermostat_dhw_vacations,6,9,1,49,13
Can't render this file because it is too large.

View File

@@ -47,7 +47,7 @@
"@preact/preset-vite": "^2.10.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@types/formidable": "^3",
"@types/node": "^22.13.11",
"@types/node": "^22.13.13",
"@types/react": "^19.0.12",
"@types/react-dom": "^19.0.4",
"concurrently": "^9.1.2",
@@ -57,8 +57,8 @@
"prettier": "^3.5.3",
"rollup-plugin-visualizer": "^5.14.0",
"terser": "^5.39.0",
"typescript-eslint": "8.27.0",
"vite": "^6.2.2",
"typescript-eslint": "8.28.0",
"vite": "^6.2.3",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^5.1.4"
},

View File

@@ -171,6 +171,27 @@ const SensorsAnalogDialog = ({
/>
</Grid>
)}
{editItem.t === AnalogType.NTC && (
<Grid>
<TextField
name="o"
label={LL.OFFSET()}
value={numberValue(editItem.o)}
sx={{ width: '11ch' }}
type="number"
variant="outlined"
onChange={updateFormValue}
slotProps={{
input: {
startAdornment: (
<InputAdornment position="start">°C</InputAdornment>
)
},
htmlInput: { min: '-20', max: '20', step: '0.1' }
}}
/>
</Grid>
)}
{editItem.t === AnalogType.COUNTER && (
<Grid>
<TextField
@@ -187,6 +208,19 @@ const SensorsAnalogDialog = ({
/>
</Grid>
)}
{editItem.t === AnalogType.RGB && (
<Grid>
<TextField
name="o"
label={'RGB ' + LL.VALUE(0)}
value={numberValue(editItem.o)}
type="number"
sx={{ width: '11ch' }}
variant="outlined"
onChange={updateFormValue}
/>
</Grid>
)}
{editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && (
<Grid>
<TextField

View File

@@ -232,20 +232,24 @@ export enum AnalogType {
DIGITAL_OUT = 6,
PWM_0 = 7,
PWM_1 = 8,
PWM_2 = 9
PWM_2 = 9,
NTC = 10,
RGB = 11
}
export const AnalogTypeNames = [
'(disabled)',
'Digital In',
'Counter',
'ADC',
'ADC In',
'Timer',
'Rate',
'Digital Out',
'PWM 0',
'PWM 1',
'PWM 2'
'PWM 2',
'NTC Temp.',
'RGB Led'
];
type BoardProfiles = Record<string, string>;

View File

@@ -1406,7 +1406,7 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:*, @types/node@npm:^22.13.11":
"@types/node@npm:*":
version: 22.13.11
resolution: "@types/node@npm:22.13.11"
dependencies:
@@ -1415,6 +1415,15 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^22.13.13":
version: 22.13.13
resolution: "@types/node@npm:22.13.13"
dependencies:
undici-types: "npm:~6.20.0"
checksum: 10c0/daf792ba5dcff1316abf4b33680f94b792f8d54d6ae495efc8929531e0ba1284a248d29aab117d2259f9280284d986ad5799b193b0516e2b926d713aab835f7d
languageName: node
linkType: hard
"@types/parse-json@npm:^4.0.0":
version: 4.0.2
resolution: "@types/parse-json@npm:4.0.2"
@@ -1474,15 +1483,15 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/eslint-plugin@npm:8.27.0"
"@typescript-eslint/eslint-plugin@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/eslint-plugin@npm:8.28.0"
dependencies:
"@eslint-community/regexpp": "npm:^4.10.0"
"@typescript-eslint/scope-manager": "npm:8.27.0"
"@typescript-eslint/type-utils": "npm:8.27.0"
"@typescript-eslint/utils": "npm:8.27.0"
"@typescript-eslint/visitor-keys": "npm:8.27.0"
"@typescript-eslint/scope-manager": "npm:8.28.0"
"@typescript-eslint/type-utils": "npm:8.28.0"
"@typescript-eslint/utils": "npm:8.28.0"
"@typescript-eslint/visitor-keys": "npm:8.28.0"
graphemer: "npm:^1.4.0"
ignore: "npm:^5.3.1"
natural-compare: "npm:^1.4.0"
@@ -1491,64 +1500,64 @@ __metadata:
"@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/95bbab011bfe51ca657ff346e4c6cac25652c88e5188a5e74d14372dba45c3d7aa713f4c90f80ebc885d77a8be89e131e8b77c096145c90da6c251a475b125fc
checksum: 10c0/f01b7d231b01ec2c1cc7c40599ddceb329532f2876664a39dec9d25c0aed4cfdbef3ec07f26bac357df000d798f652af6fdb6a2481b6120e43bfa38f7c7a7c48
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/parser@npm:8.27.0"
"@typescript-eslint/parser@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/parser@npm:8.28.0"
dependencies:
"@typescript-eslint/scope-manager": "npm:8.27.0"
"@typescript-eslint/types": "npm:8.27.0"
"@typescript-eslint/typescript-estree": "npm:8.27.0"
"@typescript-eslint/visitor-keys": "npm:8.27.0"
"@typescript-eslint/scope-manager": "npm:8.28.0"
"@typescript-eslint/types": "npm:8.28.0"
"@typescript-eslint/typescript-estree": "npm:8.28.0"
"@typescript-eslint/visitor-keys": "npm:8.28.0"
debug: "npm:^4.3.4"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/2ada98167ca5a474544fada7658d7c8d54ea4dfdd692e3d30d18b5531e50d7308a5b09d23dca651f9fe841f96075ccd18643431f4b61d0e4e7e7ccde888258e8
checksum: 10c0/4bde6887bbf3fe031c01e46db90f9f384a8cac2e67c2972b113a62d607db75e01db943601279aac847b9187960a038981814042cb02fd5aa27ea4613028f9313
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/scope-manager@npm:8.27.0"
"@typescript-eslint/scope-manager@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/scope-manager@npm:8.28.0"
dependencies:
"@typescript-eslint/types": "npm:8.27.0"
"@typescript-eslint/visitor-keys": "npm:8.27.0"
checksum: 10c0/d87daeffb81f4e70f168c38f01c667713bda71c4545e28fcdf0792378fb3df171894ef77854c5c1a5e5a22c784ee1ccea2dd856b5baf825840710a6a74c14ac9
"@typescript-eslint/types": "npm:8.28.0"
"@typescript-eslint/visitor-keys": "npm:8.28.0"
checksum: 10c0/f3bd76b3f54e60f1efe108b233b2d818e44ecf0dc6422cc296542f784826caf3c66d51b8acc83d8c354980bd201e1d9aa1ea01011de96e0613d320c00e40ccfd
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/type-utils@npm:8.27.0"
"@typescript-eslint/type-utils@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/type-utils@npm:8.28.0"
dependencies:
"@typescript-eslint/typescript-estree": "npm:8.27.0"
"@typescript-eslint/utils": "npm:8.27.0"
"@typescript-eslint/typescript-estree": "npm:8.28.0"
"@typescript-eslint/utils": "npm:8.28.0"
debug: "npm:^4.3.4"
ts-api-utils: "npm:^2.0.1"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/f38cdc660ebcb3b71496182b9ea52301ab08a4f062558aa7061a5f0b759ae3e8f68ae250a29e74251cb52c6c56733d7dabed7002b993544cbe0933bb75d67a57
checksum: 10c0/b8936edc2153bf794efba39bfb06393a228217830051767360f4b691fed7c82f3831c4fc6deac6d78b90a58596e61f866c17eaee9dd793c3efda3ebdcf5a71d8
languageName: node
linkType: hard
"@typescript-eslint/types@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/types@npm:8.27.0"
checksum: 10c0/9c5f2ba816a9baea5982feeadebe4d19f4df77ddb025a7b2307f9e1e6914076b63cbad81f7f915814e64b4d915052cf27bd79ce3e5a831340cb5ab244133941b
"@typescript-eslint/types@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/types@npm:8.28.0"
checksum: 10c0/1f95895e20dac1cf063dc93c99142fd1871e53be816bcbbee93f22a05e6b2a82ca83c20ce3a551f65555910aa0956443a23268edbb004369d0d5cb282d13c377
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/typescript-estree@npm:8.27.0"
"@typescript-eslint/typescript-estree@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/typescript-estree@npm:8.28.0"
dependencies:
"@typescript-eslint/types": "npm:8.27.0"
"@typescript-eslint/visitor-keys": "npm:8.27.0"
"@typescript-eslint/types": "npm:8.28.0"
"@typescript-eslint/visitor-keys": "npm:8.28.0"
debug: "npm:^4.3.4"
fast-glob: "npm:^3.3.2"
is-glob: "npm:^4.0.3"
@@ -1557,32 +1566,32 @@ __metadata:
ts-api-utils: "npm:^2.0.1"
peerDependencies:
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/c04d602825ff2a7b2a89746a68b32f7052fb4ce3d2355d1f4e6f43fd064f17c3b44fb974c98838a078fdebdc35152d2ab0af34663dfca99db7a790bd3fc5d8ac
checksum: 10c0/97a91c95b1295926098c12e2d2c2abaa68994dc879da132dcce1e75ec9d7dee8187695eaa5241d09cbc42b5e633917b6d35c624e78e3d3ee9bda42d1318080b6
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/utils@npm:8.27.0"
"@typescript-eslint/utils@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/utils@npm:8.28.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0"
"@typescript-eslint/scope-manager": "npm:8.27.0"
"@typescript-eslint/types": "npm:8.27.0"
"@typescript-eslint/typescript-estree": "npm:8.27.0"
"@typescript-eslint/scope-manager": "npm:8.28.0"
"@typescript-eslint/types": "npm:8.28.0"
"@typescript-eslint/typescript-estree": "npm:8.28.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/dcfd5f2c17f1a33061e3ec70d0946ff23a4238aabacae3d85087165beccedf84fb8506d30848f2470e3b60ab98b230aef79c6e8b4c5d39648a37ac559ac5b1e0
checksum: 10c0/d3425be7f86c1245a11f0ea39136af681027797417348d8e666d38c76646945eaed7b35eb8db66372b067dee8b02a855caf2c24c040ec9c31e59681ab223b59d
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:8.27.0":
version: 8.27.0
resolution: "@typescript-eslint/visitor-keys@npm:8.27.0"
"@typescript-eslint/visitor-keys@npm:8.28.0":
version: 8.28.0
resolution: "@typescript-eslint/visitor-keys@npm:8.28.0"
dependencies:
"@typescript-eslint/types": "npm:8.27.0"
"@typescript-eslint/types": "npm:8.28.0"
eslint-visitor-keys: "npm:^4.2.0"
checksum: 10c0/d86fd4032db07123816aab3a6b8b53f840387385ab2a4d8f96b22fc76b5438fb27ac8dc42b63caf23f3d265c33e9075dbf1ce8d31f939df12f5cd077d3b10295
checksum: 10c0/245a78ed983fe95fbd1b0f2d4cb9e9d1d964bddc0aa3e3d6ab10c19c4273855bfb27d840bb1fd55deb7ae3078b52f26592472baf6fd2c7019a5aa3b1da974f35
languageName: node
linkType: hard
@@ -1602,7 +1611,7 @@ __metadata:
"@table-library/react-table-library": "npm:4.1.12"
"@trivago/prettier-plugin-sort-imports": "npm:^5.2.2"
"@types/formidable": "npm:^3"
"@types/node": "npm:^22.13.11"
"@types/node": "npm:^22.13.13"
"@types/react": "npm:^19.0.12"
"@types/react-dom": "npm:^19.0.4"
alova: "npm:3.2.10"
@@ -1624,8 +1633,8 @@ __metadata:
terser: "npm:^5.39.0"
typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.8.2"
typescript-eslint: "npm:8.27.0"
vite: "npm:^6.2.2"
typescript-eslint: "npm:8.28.0"
vite: "npm:^6.2.3"
vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^5.1.4"
languageName: unknown
@@ -6654,17 +6663,17 @@ __metadata:
languageName: node
linkType: hard
"typescript-eslint@npm:8.27.0":
version: 8.27.0
resolution: "typescript-eslint@npm:8.27.0"
"typescript-eslint@npm:8.28.0":
version: 8.28.0
resolution: "typescript-eslint@npm:8.28.0"
dependencies:
"@typescript-eslint/eslint-plugin": "npm:8.27.0"
"@typescript-eslint/parser": "npm:8.27.0"
"@typescript-eslint/utils": "npm:8.27.0"
"@typescript-eslint/eslint-plugin": "npm:8.28.0"
"@typescript-eslint/parser": "npm:8.28.0"
"@typescript-eslint/utils": "npm:8.28.0"
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: ">=4.8.4 <5.9.0"
checksum: 10c0/f66f8311418b12bca751e8e1c68e42c638745765be40621b65f287a15dd58d4a71e3a0f80756d5c3cc9070a93bb1745887fce2260117e19e1b70f2804cefd351
checksum: 10c0/bf1c1e4b2f21a95930758d5b285c39a394a50e3b6983f373413b93b80a6cb5aabc1d741780e60c63cb42ad5d645ea9c1e6d441d98174c5a2884ab88f4ac46df6
languageName: node
linkType: hard
@@ -6867,9 +6876,9 @@ __metadata:
languageName: node
linkType: hard
"vite@npm:^6.2.2":
version: 6.2.2
resolution: "vite@npm:6.2.2"
"vite@npm:^6.2.3":
version: 6.2.3
resolution: "vite@npm:6.2.3"
dependencies:
esbuild: "npm:^0.25.0"
fsevents: "npm:~2.3.3"
@@ -6915,7 +6924,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 10c0/52f5b1c10cfe5e3b6382c6de1811ebbf76df9b5a8bab3d65169446c6b54a5f1528f775b1548009a6d8aad11def20fba046bb3e9abb10c0c2c9ccd78118623bb8
checksum: 10c0/ba6ad7e83e5a63fb0b6f62d3a3963624b8784bdc1bfa2a83e16cf268fb58c76bd9f8e69f39ed34bf8711cdb8fd7702916f878781da53c232c34ef7a85e0600cf
languageName: node
linkType: hard

View File

@@ -30,7 +30,7 @@ void AnalogSensor::start() {
return;
}
analogSetAttenuation(ADC_2_5db); // for all channels 1.5V
analogSetAttenuation(ADC_11db); // for all channels 3.3V
LOG_INFO("Starting Analog Sensor service");
@@ -110,13 +110,15 @@ void AnalogSensor::reload(bool get_nvs) {
sensors_.back().set_value(0); // reset value only for new sensors
}
}
if (sensor.type == AnalogType::COUNTER || sensor.type >= AnalogType::DIGITAL_OUT) {
if (sensor.type == AnalogType::COUNTER || (sensor.type >= AnalogType::DIGITAL_OUT && sensor.type <= AnalogType::PWM_2)
|| sensor.type == AnalogType::RGB) {
Command::add(
EMSdevice::DeviceType::ANALOGSENSOR,
sensor.name.c_str(),
[&](const char * value, const int8_t id) { return command_setvalue(value, sensor.gpio); },
sensor.type == AnalogType::COUNTER ? FL_(counter)
: sensor.type == AnalogType::DIGITAL_OUT ? FL_(digital_out)
: sensor.type == AnalogType::RGB ? FL_(RGB)
: FL_(pwm),
CommandFlag::ADMIN_ONLY);
}
@@ -157,6 +159,10 @@ void AnalogSensor::reload(bool get_nvs) {
// analogSetPinAttenuation does not work with analogReadMilliVolts
sensor.analog_ = 0; // initialize
sensor.last_reading_ = 0;
} else if (sensor.type() == AnalogType::NTC) {
LOG_DEBUG("NTC Sensor on GPIO %02d", sensor.gpio());
// analogSetPinAttenuation(sensor.gpio(), ADC_11db); //does not work with analogReadMilliVolts
sensor.set_uom(DeviceValueUOM::DEGREES);
} else if (sensor.type() == AnalogType::COUNTER) {
LOG_DEBUG("I/O Counter on GPIO %02d", sensor.gpio());
pinMode(sensor.gpio(), INPUT_PULLUP);
@@ -183,6 +189,18 @@ void AnalogSensor::reload(bool get_nvs) {
sensor.polltime_ = 0;
sensor.poll_ = digitalRead(sensor.gpio());
publish_sensor(sensor);
} else if (sensor.type() == AnalogType::RGB) {
LOG_DEBUG("RGB on GPIO %02d", sensor.gpio());
uint32_t v = sensor.value();
uint8_t r = v / 10000;
uint8_t g = (v - r * 10000) / 100;
uint8_t b = v % 100;
#if ESP_ARDUINO_VERSION_MAJOR < 3
neopixelWrite(sensor.gpio(), 2 * r, 2 * g, 2 * b);
#else
rgbLedWrite(sensor.gpio(), 2 * r, 2 * g, 2 * b);
#endif
LOG_DEBUG("RGB set to %d, %d, %d", r, g, b);
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
LOG_DEBUG("Digital Write on GPIO %02d", sensor.gpio());
pinMode(sensor.gpio(), OUTPUT);
@@ -272,6 +290,23 @@ void AnalogSensor::measure() {
changed_ = true;
publish_sensor(sensor);
}
} else if (sensor.type() == AnalogType::NTC) {
auto a = analogReadMilliVolts(sensor.gpio());
if (!sensor.analog_) { // init first time
sensor.analog_ = a;
sensor.sum_ = a * 16;
} else { // simple moving average filter
sensor.sum_ = (sensor.sum_ * 15 + a * 16) / 16;
sensor.analog_ = sensor.sum_ / 16;
}
if (sensor.analog_ > 0 && sensor.analog_ < 3300 && (sensor.last_reading_ + 1 < sensor.analog_ || sensor.last_reading_ > sensor.analog_ + 1)) {
sensor.set_value(sensor.offset() + 1 / (1 / T25 + log((double)sensor.analog_ / (3300 - sensor.analog_) * (Rt / R0)) / Beta)
- T0); // Temperature in Celsius
sensor.last_reading_ = sensor.analog_;
sensorreads_++;
changed_ = true;
publish_sensor(sensor);
}
}
}
}
@@ -350,12 +385,14 @@ bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, doubl
bool found_sensor = false;
EMSESP::webCustomizationService.update([&](WebCustomization & settings) {
for (auto & AnalogCustomization : settings.analogCustomizations) {
if (AnalogCustomization.type == AnalogType::COUNTER || AnalogCustomization.type >= AnalogType::DIGITAL_OUT) {
if (AnalogCustomization.type == AnalogType::COUNTER
|| (AnalogCustomization.type >= AnalogType::DIGITAL_OUT && AnalogCustomization.type <= AnalogType::PWM_2)
|| AnalogCustomization.type >= AnalogType::RGB) {
Command::erase_command(EMSdevice::DeviceType::ANALOGSENSOR, AnalogCustomization.name.c_str());
}
if (name.empty()) {
char n[20];
snprintf(n, sizeof(n), "%s_%02d", FL_(AnalogTypeName)[type], gpio);
snprintf(n, sizeof(n), "%s_%02d", FL_(list_sensortype)[type], gpio);
name = n;
}
if (AnalogCustomization.gpio == gpio) {
@@ -430,8 +467,13 @@ void AnalogSensor::publish_sensor(const Sensor & sensor) const {
} else {
snprintf(topic, sizeof(topic), "%s%s/%s", F_(analogsensor), "_data", sensor.name().c_str());
}
char payload[10];
Mqtt::queue_publish(topic, Helpers::render_value(payload, sensor.value(), 2)); // always publish as doubles
char result[12];
if (sensor.type() == AnalogType::DIGITAL_IN || sensor.type() == AnalogType::DIGITAL_OUT) {
Helpers::render_boolean(result, sensor.value() != 0);
} else {
Helpers::render_value(result, sensor.value(), 2); // double
}
Mqtt::queue_publish(topic, result); // always publish as doubles
}
char cmd[COMMAND_MAX_LENGTH];
snprintf(cmd, sizeof(cmd), "%s/%s", F_(analogsensor), sensor.name().c_str());
@@ -455,7 +497,9 @@ void AnalogSensor::remove_ha_topic(const int8_t type, const uint8_t gpio) const
snprintf(topic, sizeof(topic), "switch/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
} else if (type == AnalogType::DIGITAL_OUT) { // DAC
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
} else if (type >= AnalogType::PWM_0) {
} else if (type >= AnalogType::PWM_0 && type <= AnalogType::PWM_2) {
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
} else if (type >= AnalogType::RGB) {
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
} else if (type == AnalogType::DIGITAL_IN) {
snprintf(topic, sizeof(topic), "binary_sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
@@ -495,6 +539,8 @@ void AnalogSensor::publish_values(const bool force) {
case AnalogType::PWM_0:
case AnalogType::PWM_1:
case AnalogType::PWM_2:
case AnalogType::RGB:
case AnalogType::NTC:
dataSensor["value"] = serialized(Helpers::render_value(s, sensor.value(), 2)); // double
break;
case AnalogType::DIGITAL_IN:
@@ -597,6 +643,14 @@ void AnalogSensor::publish_values(const bool force) {
config["max"] = 100;
config["mode"] = "box"; // auto, slider or box
config["step"] = 0.1;
} else if (sensor.type() == AnalogType::RGB) {
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::base().c_str(), F_(analogsensor), sensor.name().c_str());
config["cmd_t"] = command_topic;
config["min"] = 0;
config["max"] = 999999;
config["mode"] = "box"; // auto, slider or box
config["step"] = 1;
} else if (sensor.type() == AnalogType::COUNTER) {
snprintf(topic, sizeof(topic), "sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), sensor.gpio());
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::base().c_str(), F_(analogsensor), sensor.name().c_str());
@@ -679,7 +733,8 @@ void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) {
output["analog"] = FL_(list_sensortype)[sensor.type()];
output["value"] = sensor.value();
output["readable"] = true;
output["writeable"] = sensor.type() == AnalogType::COUNTER || (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2);
output["writeable"] = sensor.type() == AnalogType::COUNTER || sensor.type() >= AnalogType::RGB
|| (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2);
output["visible"] = true;
if (sensor.type() == AnalogType::COUNTER) {
output["min"] = 0;
@@ -733,10 +788,10 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
double oldoffset = sensor.offset();
if (sensor.type() == AnalogType::COUNTER) {
if (val < 0 || value[0] == '+') { // sign corrects values
sensor.set_offset(sensor.value() + val);
// sensor.set_offset(sensor.value() + val);
sensor.set_value(sensor.value() + val);
} else { // positive values are set
sensor.set_offset(val);
// sensor.set_offset(val);
sensor.set_value(val);
}
if (oldoffset != sensor.offset() && sensor.offset() != EMSESP::nvs_.getDouble(sensor.name().c_str())) {
@@ -744,6 +799,19 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) {
}
} else if (sensor.type() == AnalogType::ADC) {
sensor.set_offset(val);
} else if (sensor.type() == AnalogType::RGB) {
uint32_t v = val;
sensor.set_offset(v);
sensor.set_value(v);
uint8_t r = v / 10000;
uint8_t g = (v - r * 10000) / 100;
uint8_t b = v % 100;
#if ESP_ARDUINO_VERSION_MAJOR < 3
neopixelWrite(sensor.gpio(), 2 * r, 2 * g, 2 * b);
#else
rgbLedWrite(sensor.gpio(), 2 * r, 2 * g, 2 * b);
#endif
LOG_DEBUG("RGB set to %d, %d, %d", r, g, b);
} else if (sensor.type() == AnalogType::DIGITAL_OUT) {
uint8_t v = val;
#if CONFIG_IDF_TARGET_ESP32

View File

@@ -27,8 +27,8 @@
namespace emsesp {
// names, same order as AnalogType
MAKE_ENUM_FIXED(AnalogTypeName, "disabled", "dig_in", "counter", "adc", "timer", "rate", "dig_out", "pwm0", "pwm1", "pwm2")
// names, same order as AnalogType, see list_sensortype in local_common.h
// MAKE_ENUM_FIXED(AnalogTypeName, "disabled", "dig_in", "counter", "adc", "timer", "rate", "dig_out", "pwm0", "pwm1", "pwm2")
class AnalogSensor {
public:
@@ -122,7 +122,9 @@ class AnalogSensor {
DIGITAL_OUT = 6,
PWM_0 = 7,
PWM_1 = 8,
PWM_2 = 9
PWM_2 = 9,
NTC = 10,
RGB = 11
};
void start();
@@ -166,6 +168,11 @@ class AnalogSensor {
void store_counters();
private:
static constexpr double Beta = 3380;
static constexpr double T0 = 273.15;
static constexpr double T25 = 298.15;
static constexpr double R0 = 10000;
static constexpr double Rt = 10000;
static constexpr uint8_t MAX_SENSORS = 20;
static constexpr uint32_t MEASURE_ANALOG_INTERVAL = 500;

View File

@@ -468,6 +468,7 @@ class EMSdevice {
static constexpr uint8_t EMS_DEVICE_FLAG_R3000 = 15; // Rego3000, same as RC300 with different wwmodes
static constexpr uint8_t EMS_DEVICE_FLAG_CR120 = 16; // mostly like RC300, but some changes
static constexpr uint8_t EMS_DEVICE_FLAG_CR11 = 17; // CRF200 only monitor
static constexpr uint8_t EMS_DEVICE_FLAG_HMC310 = 18;
uint8_t count_entities();
uint8_t count_entities_fav();

View File

@@ -1314,6 +1314,10 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
flags = DeviceFlags::EMS_DEVICE_FLAG_CR120;
default_name = "CR120";
}
if (product_id == 158 && strncmp(version,"73",2) == 0) {
flags = DeviceFlags::EMS_DEVICE_FLAG_HMC310;
default_name = "HMC310";
}
// empty reply to version, read a generic device from database
if (product_id == 0) {

View File

@@ -276,7 +276,8 @@ MAKE_ENUM_FIXED(list_syslog_level, "off", "emerg", "alert", "crit", "error", "wa
// sensors
MAKE_ENUM_FIXED(counter, "counter")
MAKE_ENUM_FIXED(digital_out, "digital_out")
MAKE_ENUM_FIXED(list_sensortype, "disabled", "digital in", "counter", "adc", "timer", "rate", "digital out", "pwm 0", "pwm 1", "pwm 2")
MAKE_ENUM_FIXED(RGB, "RGB")
MAKE_ENUM_FIXED(list_sensortype, "disabled", "digital in", "counter", "adc", "timer", "rate", "digital out", "pwm 0", "pwm 1", "pwm 2", "NTC Temp", "RGB Led")
// watch
MAKE_ENUM_FIXED(list_watch, "off", "on", "raw", "unknown")

View File

@@ -652,7 +652,6 @@ MAKE_TRANSLATION(wwSolarTemp, "solartemp", "solar boiler temperature", "Solarkes
MAKE_TRANSLATION(switchtime, "switchtime", "program switchtime", "Programmschaltzeit", "Programma schakeltijd", "Program Bytestid", "program czasowy", "programbyttetid", "heure commutation programme", "program değiştirme süresi", "ora commutazione programmata", "čas prepnutia programu", "čas přepnutí programu")
MAKE_TRANSLATION(switchtime1, "switchtime1", "own1 program switchtime", "Programmschaltzeit Eigen 1", "Schakeltijd programma 1", "Program 1 Bytestid", "program przełączania 1", "byttetidprogram 1", "heure de commutation programme 1", "program1 değiştirme süresi", "ora commutazione programma 1", "vlastný 1 program prepnutia", "vlastní program 1 přepnutí")
MAKE_TRANSLATION(switchtime2, "switchtime2", "own2 program switchtime", "Programmschaltzeit Eigen 2", "Schakeltijd programma 2", "Program 2 Bytestid", "program przełączania 2", "byttetid program 2", "heure de changement programme 2", "program1 değiştirme süresi", "ora commutazione programma 2", "vlastný 2 program prepnutia", "vlastní program 2 přepnutí")
MAKE_TRANSLATION(wwswitchtime, "switchtimeWW", "program switchtime warm water", "Programmschaltzeit Warmwasser", "Warm water programma schakeltijd", "Varmvattenprogram Bytestid", "program czasowy", "byttetid varmtvannsprogram", "heure commutation programme", "sıcak kullanıom suyu program değiştirme süresi", "Tempo di commutazione del programma", "čas prepnutia programu", "čas přepnutí program TUV")
MAKE_TRANSLATION(wwcircswitchtime, "circswitchtime", "circulation program switchtime", "Zirculationsprogramm Schaltzeit", "Schakeltijd circulatieprogramma", "Cirkulationsprogram Bytestid", "program cyrkulacji", "byttetid sirkulasjonsprogram", "heure commutation programme circulation", "sirkülasyon program değiştirme süresi", "ora commutazione programma circolazione", "čas prepnutia cirkulačného programu", "čas přepnutí programu cirkulace")
MAKE_TRANSLATION(dateTime, "datetime", "date/time", "Datum/Zeit", "Datum/Tijd", "Datum/Tid", "data i godzina", "dato/tid", "date/heure", "zaman/saat", "Data/Ora", "dátum/čas", "datum/čas")
MAKE_TRANSLATION(errorCode, "errorcode", "error code", "Fehlercode", "Foutmeldingscode", "Felkod", "kod błędu", "feikode", "code erreur", "hata kodu", "codice errore", "error kód", "chybový kód")

View File

@@ -393,7 +393,7 @@ const std::initializer_list<Modbus::EntityModbusInfo> Modbus::modbus_register_ma
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwDisinfectHour), 14, 1), // disinfecthour
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwMaxTemp), 15, 1), // maxtemp
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwOneTimeKey), 16, 1), // onetimekey
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwswitchtime), 17, 11), // switchtimeWW
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(switchtime), 17, 11), // switchtime
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(wwcircswitchtime), 28, 8), // circswitchtime
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(holidays), 36, 13), // holidays
REGISTER_MAPPING(dt::THERMOSTAT, TAG_TYPE_DHW, FL_(vacations), 49, 13), // vacations

View File

@@ -102,6 +102,9 @@ std::deque<Token> exprToTokens(const std::string & expr) {
} else if (strncmp(p, "hex", 3) == 0) {
p += 2;
tokens.emplace_back(Token::Type::Unary, "h", 5);
} else if (strncmp(p, "rnd", 3) == 0) {
p += 2;
tokens.emplace_back(Token::Type::Unary, "d", 5);
} else if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p == '_') || (*p & 0x80)) {
const auto * b = p;
while ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p == '_') || (*p & 0x80)) {
@@ -526,6 +529,9 @@ std::string calculate(const std::string & expr) {
case 'x':
stack.push_back(to_hex(static_cast<int>(rhd)));
break;
case 'd':
stack.push_back(to_string(rhd * esp_random() / UINT32_MAX));
break;
}
} break;
case Token::Type::Compare: {

View File

@@ -1848,10 +1848,11 @@ void Boiler::process_UBAErrorMessage(std::shared_ptr<const Telegram> telegram) {
uint32_t date = (year - 2000) * 535680UL + month * 44640UL + day * 1440UL + hour * 60 + min + duration;
// check valid https://github.com/emsesp/EMS-ESP32/issues/2189
if (day == 0 || day > 31 || month == 0 || month > 12 || !std::isprint(code[0]) || !std::isprint(code[1])) {
if (!lastCodeDate_) {
if (!lastCodeDate_ && std::isprint(code[0]) && std::isprint(code[1])) {
char newCode[sizeof(lastCode_)];
snprintf(newCode, sizeof(lastCode_), "%s(%d)", code, codeNo);
has_update(lastCode_, newCode, sizeof(lastCode_));
lastCodeDate_ = 1;
}
return;
}

View File

@@ -513,7 +513,8 @@ uint8_t Thermostat::HeatingCircuit::get_mode() const {
} else if (mode_new == 2) {
return HeatingCircuit::Mode::AUTO;
}
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_R3000) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) {
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC300 || model == EMSdevice::EMS_DEVICE_FLAG_R3000 || model == EMSdevice::EMS_DEVICE_FLAG_RC100
|| model == EMSdevice::EMS_DEVICE_FLAG_HMC310) {
if (mode == 0) {
return HeatingCircuit::Mode::MANUAL;
} else if (mode == 1) {
@@ -565,7 +566,8 @@ uint8_t Thermostat::HeatingCircuit::get_mode_type() const {
} else if (modetype == 1) {
return HeatingCircuit::Mode::ON;
}
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_R3000) || (model == EMSdevice::EMS_DEVICE_FLAG_BC400)) {
} else if (model == EMSdevice::EMS_DEVICE_FLAG_RC300 || model == EMSdevice::EMS_DEVICE_FLAG_R3000 || model == EMSdevice::EMS_DEVICE_FLAG_BC400
|| model == EMSdevice::EMS_DEVICE_FLAG_HMC310) {
if (modetype == 0) {
return HeatingCircuit::Mode::ECO;
} else if (modetype == 1) {
@@ -906,8 +908,8 @@ void Thermostat::process_IBASettings(std::shared_ptr<const Telegram> telegram) {
// Settings WW 0x37 - RC35
void Thermostat::process_RC35wwSettings(std::shared_ptr<const Telegram> telegram) {
auto dhw = dhw_circuit(0, true);
has_update(telegram, dhw->wwProgMode_, 0); // 0-like hc, 0xFF own prog
has_update(telegram, dhw->wwCircProg_, 1); // 0-like hc, 0xFF own prog
has_bitupdate(telegram, dhw->wwProgMode_, 0, 0); // 0-like hc, 0xFF own prog
has_bitupdate(telegram, dhw->wwCircProg_, 1, 0); // 0-like hc, 0xFF own prog
has_update(telegram, dhw->wwMode_, 2); // 0-off, 1-on, 2-auto
has_update(telegram, dhw->wwCircMode_, 3); // 0-off, 1-on, 2-auto
has_update(telegram, dhw->wwDisinfecting_, 4); // 0-off, 0xFF on
@@ -1265,7 +1267,7 @@ void Thermostat::process_RC300WWmode(std::shared_ptr<const Telegram> telegram) {
// circulation pump see: https://github.com/Th3M3/buderus_ems-wiki/blob/master/Einstellungen%20der%20Bedieneinheit%20RC310.md
has_update(telegram, dhw->wwCircPump_, 1); // FF=off, 0=on ?
if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) {
if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_HMC310) {
const uint8_t modes[] = {0, 5, 1, 2, 4}; // off, eco+, eco, comfort, auto
uint8_t wwmode = dhw->wwMode_ < sizeof(modes) ? modes[dhw->wwMode_] : EMS_VALUE_UINT8_NOTSET;
telegram->read_value(wwmode, 2);
@@ -2235,7 +2237,7 @@ bool Thermostat::set_wwmode(const char * value, const int8_t id) {
return false;
}
write_command(0xB0, 2, set, 0xB0);
} else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) {
} else if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_HMC310) {
if (!Helpers::value2enum(value, set, FL_(enum_wwMode4))) { // off, eco+, eco, comfort, auto
return false;
}
@@ -2946,6 +2948,7 @@ bool Thermostat::set_mode(const char * value, const int8_t id) {
case EMSdevice::EMS_DEVICE_FLAG_RC300:
case EMSdevice::EMS_DEVICE_FLAG_RC100:
case EMSdevice::EMS_DEVICE_FLAG_R3000:
case EMSdevice::EMS_DEVICE_FLAG_HMC310:
mode_list = FL_(enum_mode);
break;
case EMSdevice::EMS_DEVICE_FLAG_JUNKERS:
@@ -3071,6 +3074,7 @@ bool Thermostat::set_mode_n(const uint8_t mode, const int8_t id) {
case EMSdevice::EMS_DEVICE_FLAG_RC300:
case EMSdevice::EMS_DEVICE_FLAG_RC100:
case EMSdevice::EMS_DEVICE_FLAG_R3000:
case EMSdevice::EMS_DEVICE_FLAG_HMC310:
offset = EMS_OFFSET_RCPLUSSet_mode;
set_mode_value = set_mode_value == 2 ? 0xFF : 0;
break;
@@ -3105,7 +3109,8 @@ bool Thermostat::set_mode_n(const uint8_t mode, const int8_t id) {
hc->mode = set_mode_value >> 1;
} else if (model_ == EMSdevice::EMS_DEVICE_FLAG_BC400 || model_ == EMSdevice::EMS_DEVICE_FLAG_CR120) {
hc->mode_new = set_mode_value;
} else if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC300 || model_ == EMSdevice::EMS_DEVICE_FLAG_R3000 || model_ == EMSdevice::EMS_DEVICE_FLAG_RC100) {
} else if (model_ == EMSdevice::EMS_DEVICE_FLAG_RC300 || model_ == EMSdevice::EMS_DEVICE_FLAG_R3000 || model_ == EMSdevice::EMS_DEVICE_FLAG_HMC310
|| model_ == EMSdevice::EMS_DEVICE_FLAG_RC100) {
hc->mode = set_mode_value == 0xFF ? 1 : 0;
} else if (model_ == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
hc->mode = set_mode_value - 1;
@@ -3614,7 +3619,7 @@ bool Thermostat::set_wwCircSwitchTime(const char * value, const int8_t id) {
// sets a single switchtime in the thermostat circulation program for RC35
bool Thermostat::set_wwSwitchTime(const char * value, const int8_t id) {
auto dhw = dhw_circuit(id2dhw(id));
if (dhw != nullptr) {
if (dhw == nullptr) {
return false;
}
char out[sizeof(dhw->wwSwitchTime_)] = {'\0'};
@@ -4188,6 +4193,7 @@ void Thermostat::register_device_values() {
case EMSdevice::EMS_DEVICE_FLAG_R3000:
case EMSdevice::EMS_DEVICE_FLAG_BC400:
case EMSdevice::EMS_DEVICE_FLAG_CR120:
case EMSdevice::EMS_DEVICE_FLAG_HMC310:
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&dateTime_,
DeviceValueType::STRING,
@@ -4619,6 +4625,7 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
case EMSdevice::EMS_DEVICE_FLAG_R3000:
case EMSdevice::EMS_DEVICE_FLAG_BC400:
case EMSdevice::EMS_DEVICE_FLAG_CR120:
case EMSdevice::EMS_DEVICE_FLAG_HMC310:
if (model == EMSdevice::EMS_DEVICE_FLAG_BC400 || model == EMSdevice::EMS_DEVICE_FLAG_CR120) {
register_device_value(tag, &hc->mode_new, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode));
} else {
@@ -5058,7 +5065,8 @@ void Thermostat::register_device_values_dhw(std::shared_ptr<Thermostat::DhwCircu
case EMSdevice::EMS_DEVICE_FLAG_R3000:
case EMSdevice::EMS_DEVICE_FLAG_BC400:
case EMSdevice::EMS_DEVICE_FLAG_CR120:
if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400) {
case EMSdevice::EMS_DEVICE_FLAG_HMC310:
if (model() == EMSdevice::EMS_DEVICE_FLAG_BC400 || model() == EMSdevice::EMS_DEVICE_FLAG_HMC310) {
register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode4), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
} else if (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) {
register_device_value(tag, &dhw->wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode5), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode));
@@ -5134,7 +5142,7 @@ void Thermostat::register_device_values_dhw(std::shared_ptr<Thermostat::DhwCircu
register_device_value(tag, &dhw->wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp));
register_device_value(tag, &dhw->wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey));
register_device_value(
tag, &dhw->wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime));
tag, &dhw->wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime));
register_device_value(tag,
&dhw->wwCircSwitchTime_,
DeviceValueType::STRING,
@@ -5157,7 +5165,7 @@ void Thermostat::register_device_values_dhw(std::shared_ptr<Thermostat::DhwCircu
register_device_value(tag, &dhw->wwMaxTemp_, DeviceValueType::UINT8, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp), 60, 80);
register_device_value(tag, &dhw->wwOneTimeKey_, DeviceValueType::BOOL, FL_(wwOneTimeKey), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwOneTimeKey));
register_device_value(
tag, &dhw->wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(wwswitchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime));
tag, &dhw->wwSwitchTime_, DeviceValueType::STRING, FL_(tpl_switchtime), FL_(switchtime), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwSwitchTime));
register_device_value(tag,
&dhw->wwCircSwitchTime_,
DeviceValueType::STRING,

View File

@@ -229,8 +229,8 @@ class Thermostat : public EMSdevice {
// check to see if the thermostat is a hybrid of the R300
inline bool isRC300() const {
return ((model() == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model() == EMSdevice::EMS_DEVICE_FLAG_R3000) || (model() == EMSdevice::EMS_DEVICE_FLAG_BC400)
|| (model() == EMSdevice::EMS_DEVICE_FLAG_CR120));
return (model() == EMSdevice::EMS_DEVICE_FLAG_RC300 || model() == EMSdevice::EMS_DEVICE_FLAG_R3000 || model() == EMSdevice::EMS_DEVICE_FLAG_BC400
|| model() == EMSdevice::EMS_DEVICE_FLAG_CR120 || model() == EMSdevice::EMS_DEVICE_FLAG_HMC310);
}
inline uint8_t id2dhw(const int8_t id) const { // returns telegram offset for TAG(id)

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.3-dev.0"
#define EMSESP_APP_VERSION "3.7.3-dev.2"

View File

@@ -446,7 +446,9 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) {
dv["v"] = Helpers::transformNumFloat(sensor.value());
dv["u"] = sensor.uom();
}
if (sensor.type() == AnalogSensor::AnalogType::COUNTER || sensor.type() >= AnalogSensor::AnalogType::DIGITAL_OUT) {
if (sensor.type() == AnalogSensor::AnalogType::COUNTER
|| (sensor.type() >= AnalogSensor::AnalogType::DIGITAL_OUT && sensor.type() <= AnalogSensor::AnalogType::PWM_2)
|| sensor.type() == AnalogSensor::AnalogType::RGB) {
dv["c"] = sensor.name();
}
}