move dhw entities from mixer/solar to new water device, add pool device

This commit is contained in:
MichaelDvP
2023-11-04 15:24:43 +01:00
parent 6c17d61baf
commit 3101f5e6ae
36 changed files with 842 additions and 715 deletions

View File

@@ -4,6 +4,8 @@
## **IMPORTANT! BREAKING CHANGES**
- move dhw functions from mixer/solar to water
## Added
- humidity for ventilation devices
@@ -16,6 +18,7 @@
- heatpump high res energy counters [#1348, #1349. #1350](https://github.com/emsesp/EMS-ESP32/issues/1348)
- optional bssid in network settings
- extension module EM100 [#1315](https://github.com/emsesp/EMS-ESP32/discussions/1315)
- digital_out with new options for polarity and startup state
## Fixed

View File

@@ -54,7 +54,7 @@
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"concurrently": "^8.2.2",
"eslint": "^8.52.0",
"eslint": "^8.53.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-prettier": "^9.0.0",
@@ -65,7 +65,7 @@
"eslint-plugin-prettier": "alpha",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"preact": "^10.18.1",
"preact": "^10.18.2",
"prettier": "^3.0.3",
"rollup-plugin-visualizer": "^5.9.2",
"terser": "^5.24.0",

View File

@@ -382,6 +382,21 @@ const MqttSettingsForm: FC = () => {
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<TextField
name="publish_time_water"
label={LL.MQTT_INT_WATER()}
InputProps={{
endAdornment: <InputAdornment position="end">{LL.SECONDS()}</InputAdornment>
}}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_water)}
type="number"
onChange={updateFormValue}
margin="normal"
/>
</Grid>
<Grid item xs={12} sm={6} md={4}>
<TextField
name="publish_time_sensor"

View File

@@ -246,6 +246,7 @@ const de: Translation = {
MQTT_INT_THERMOSTATS: 'Thermostate',
MQTT_INT_SOLAR: 'Solarmodule',
MQTT_INT_MIXER: 'Mischermodule',
MQTT_INT_WATER: 'Warmwassermodule',
MQTT_QUEUE: 'MQTT Queue',
DEFAULT: 'Standard',
MQTT_ENTITY_FORMAT: 'Entitäts-ID Format',

View File

@@ -246,6 +246,7 @@ const en: Translation = {
MQTT_INT_THERMOSTATS: 'Thermostats',
MQTT_INT_SOLAR: 'Solar Modules',
MQTT_INT_MIXER: 'Mixer Modules',
MQTT_INT_WATER: 'Water Modules',
MQTT_QUEUE: 'MQTT Queue',
DEFAULT: 'Default',
MQTT_ENTITY_FORMAT: 'Entity ID format',

View File

@@ -246,6 +246,7 @@ const fr: Translation = {
MQTT_INT_THERMOSTATS: 'Thermostats',
MQTT_INT_SOLAR: 'Modules solaires',
MQTT_INT_MIXER: 'Modules mélangeurs',
MQTT_INT_WATER: 'Modules eau',
MQTT_QUEUE: 'Queue MQTT',
DEFAULT: 'Défaut',
MQTT_ENTITY_FORMAT: 'Entity ID format', // TODO translate

View File

@@ -248,6 +248,7 @@ const it: Translation = {
MQTT_INT_THERMOSTATS: 'Termostati',
MQTT_INT_SOLAR: 'Moduli solari',
MQTT_INT_MIXER: 'Moduli Mixer',
MQTT_INT_WATER: 'Moduli Acqua',
MQTT_QUEUE: 'Coda MQTT',
DEFAULT: 'Predefinito',
MQTT_ENTITY_FORMAT: 'Formato ID entità',

View File

@@ -246,6 +246,7 @@ const nl: Translation = {
MQTT_INT_THERMOSTATS: 'Thermostaten',
MQTT_INT_SOLAR: 'Solar Modules',
MQTT_INT_MIXER: 'Mixer Modules',
MQTT_INT_WATER: 'Water Modules',
MQTT_QUEUE: 'MQTT Queue',
DEFAULT: 'Default',
MQTT_ENTITY_FORMAT: 'Entity ID formaat',

View File

@@ -246,6 +246,7 @@ const no: Translation = {
MQTT_INT_THERMOSTATS: 'Termostat',
MQTT_INT_SOLAR: 'Solpaneler',
MQTT_INT_MIXER: 'Blandeventil',
MQTT_INT_WATER: 'Water Modules', // TODO translate
MQTT_QUEUE: 'MQTT Queue',
DEFAULT: 'Standard',
MQTT_ENTITY_FORMAT: 'Enhets ID format',

View File

@@ -246,6 +246,7 @@ const pl: BaseTranslation = {
MQTT_INT_THERMOSTATS: 'Termostaty',
MQTT_INT_SOLAR: 'Panele solarne',
MQTT_INT_MIXER: 'Mieszacze',
MQTT_INT_WATER: 'Water Modules', // TODO translate
MQTT_QUEUE: 'Kolejka MQTT',
DEFAULT: '{{Pozostałe|Domyślna|}}',
MQTT_ENTITY_FORMAT: 'Format "Entity ID"',

View File

@@ -246,6 +246,7 @@ const sv: Translation = {
MQTT_INT_THERMOSTATS: 'Termostater',
MQTT_INT_SOLAR: 'Solpaneler',
MQTT_INT_MIXER: 'Blandningsventiler',
MQTT_INT_WATER: 'Water Modules', // TODO translate
MQTT_QUEUE: 'MQTT-kö',
DEFAULT: 'Standard',
MQTT_ENTITY_FORMAT: 'Entitets-ID format',

View File

@@ -246,6 +246,7 @@ const tr: Translation = {
MQTT_INT_THERMOSTATS: 'Termostatlar',
MQTT_INT_SOLAR: 'Güneş Enerjisi Modülleri',
MQTT_INT_MIXER: 'Karışım Modülleri',
MQTT_INT_WATER: 'Water Modules', // TODO translate
MQTT_QUEUE: 'MQTT Sırası',
DEFAULT: 'Varsayılan',
MQTT_ENTITY_FORMAT: 'Varlık Kimlik biçimi',

View File

@@ -2,8 +2,8 @@ import { AiOutlineControl, AiOutlineGateway, AiOutlineAlert } from 'react-icons/
import { CgSmartHomeBoiler } from 'react-icons/cg';
import { FaSolarPanel } from 'react-icons/fa';
import { GiHeatHaze } from 'react-icons/gi';
import { MdThermostatAuto, MdOutlineSensors, MdOutlineExtension, MdOutlineDevices } from 'react-icons/md';
import { GiHeatHaze, GiTap } from 'react-icons/gi';
import { MdThermostatAuto, MdOutlineSensors, MdOutlineExtension, MdOutlineDevices, MdOutlinePool } from 'react-icons/md';
import { TiFlowSwitch } from 'react-icons/ti';
import { VscVmConnect } from 'react-icons/vsc';
import { DeviceType } from './types';
@@ -40,6 +40,10 @@ const DeviceIcon: FC<DeviceIconProps> = ({ type_id }) => {
return <AiOutlineAlert />;
case DeviceType.EXTENSION:
return <MdOutlineDevices />;
case DeviceType.WATER:
return <GiTap />;
case DeviceType.POOL:
return <MdOutlinePool />;
case DeviceType.CUSTOM:
return <MdOutlineExtension />;
default:

View File

@@ -355,6 +355,7 @@ export const enum DeviceType {
TEMPERATURESENSOR,
ANALOGSENSOR,
SCHEDULER,
CUSTOM,
BOILER,
THERMOSTAT,
MIXER,
@@ -368,7 +369,9 @@ export const enum DeviceType {
EXTENSION,
GENERIC,
HEATSOURCE,
CUSTOM,
VENTILATION,
WATER,
POOL,
UNKNOWN
}

View File

@@ -35,6 +35,7 @@ export interface MqttSettings {
publish_time_thermostat: number;
publish_time_solar: number;
publish_time_mixer: number;
publish_time_water: number;
publish_time_other: number;
publish_time_sensor: number;
publish_time_heartbeat: number;

View File

@@ -641,9 +641,9 @@ __metadata:
languageName: node
linkType: hard
"@eslint/eslintrc@npm:^2.1.2":
version: 2.1.2
resolution: "@eslint/eslintrc@npm:2.1.2"
"@eslint/eslintrc@npm:^2.1.3":
version: 2.1.3
resolution: "@eslint/eslintrc@npm:2.1.3"
dependencies:
ajv: "npm:^6.12.4"
debug: "npm:^4.3.2"
@@ -654,14 +654,14 @@ __metadata:
js-yaml: "npm:^4.1.0"
minimatch: "npm:^3.1.2"
strip-json-comments: "npm:^3.1.1"
checksum: fa25638f2666cac6810f98ee7d0f4b912f191806467c1b40d72bac759fffef0b3357f12a1869817286837b258e4de3517e0c7408520e156ca860fc53a1fbaed9
checksum: 77b70a89232fe702c2f765b5b92970f5e4224b55363b923238b996c66fcd991504f40d3663c0543ae17d6c5049ab9b07ab90b65d7601e6f25e8bcd4caf69ac75
languageName: node
linkType: hard
"@eslint/js@npm:8.52.0":
version: 8.52.0
resolution: "@eslint/js@npm:8.52.0"
checksum: 86beff213d0ae4ced203a922b74e2cc4d767d109e7815f985bf648946ba072198977102e32afc9fa04f7825a6de83a831874f6b6675ba0c1d0743ade2dc2d53d
"@eslint/js@npm:8.53.0":
version: 8.53.0
resolution: "@eslint/js@npm:8.53.0"
checksum: a372d55aa2bbe0d9399acc8de3c892dcfe507fd914d29fde6826ae54a13452619be626aa7eb70b1ec4d4da5302b6ed8e8ac9bf1f830003f15c0ad56c30b4f520
languageName: node
linkType: hard
@@ -1566,7 +1566,7 @@ __metadata:
alova: "npm:^2.13.1"
async-validator: "npm:^4.2.5"
concurrently: "npm:^8.2.2"
eslint: "npm:^8.52.0"
eslint: "npm:^8.53.0"
eslint-config-airbnb: "npm:^19.0.4"
eslint-config-airbnb-typescript: "npm:^17.1.0"
eslint-config-prettier: "npm:^9.0.0"
@@ -1581,7 +1581,7 @@ __metadata:
jwt-decode: "npm:^4.0.0"
lodash-es: "npm:^4.17.21"
mime-types: "npm:^2.1.35"
preact: "npm:^10.18.1"
preact: "npm:^10.18.2"
prettier: "npm:^3.0.3"
react: "npm:latest"
react-dom: "npm:latest"
@@ -3654,14 +3654,14 @@ __metadata:
languageName: node
linkType: hard
"eslint@npm:^8.52.0":
version: 8.52.0
resolution: "eslint@npm:8.52.0"
"eslint@npm:^8.53.0":
version: 8.53.0
resolution: "eslint@npm:8.53.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.2.0"
"@eslint-community/regexpp": "npm:^4.6.1"
"@eslint/eslintrc": "npm:^2.1.2"
"@eslint/js": "npm:8.52.0"
"@eslint/eslintrc": "npm:^2.1.3"
"@eslint/js": "npm:8.53.0"
"@humanwhocodes/config-array": "npm:^0.11.13"
"@humanwhocodes/module-importer": "npm:^1.0.1"
"@nodelib/fs.walk": "npm:^1.2.8"
@@ -3698,7 +3698,7 @@ __metadata:
text-table: "npm:^0.2.0"
bin:
eslint: bin/eslint.js
checksum: 01784ab15351d749bc95446039ed7acd5124f7cc84acdbf98c7199272eae06212a8f3ea4a9b47e7cc54ab17ca094c3a664bbfc3002c7de27936220e278b5028a
checksum: e305a71ce2b9a8631b293266fe53e346c76f28bc8d004af33f10e537cf133db1fb87af3599376e70ed6e0f89a78be10c4f08ddd0c1c9c0c497cd143b4a270420
languageName: node
linkType: hard
@@ -6661,10 +6661,10 @@ __metadata:
languageName: node
linkType: hard
"preact@npm:^10.18.1":
version: 10.18.1
resolution: "preact@npm:10.18.1"
checksum: 587c4634b310efc306ef9315f849b8e4ff538435087a1dca626e1394b98570af1ecdc254b7f0bb3060fc7ab87456c5f891f9b8a167d5c34dbbcfcf60b6e993f4
"preact@npm:^10.18.2":
version: 10.18.2
resolution: "preact@npm:10.18.2"
checksum: c7dcd6ea812adb0bdc215366b14aadc44724b6dd6c4e9aadd986126d94abde62f3e02e18d6157a9984873be9877f206c0afa10a09346178c4c828a103a66a0e1
languageName: node
linkType: hard

View File

@@ -234,6 +234,7 @@ void MqttSettings::read(MqttSettings & settings, JsonObject & root) {
root["publish_time_thermostat"] = settings.publish_time_thermostat;
root["publish_time_solar"] = settings.publish_time_solar;
root["publish_time_mixer"] = settings.publish_time_mixer;
root["publish_time_water"] = settings.publish_time_water;
root["publish_time_other"] = settings.publish_time_other;
root["publish_time_sensor"] = settings.publish_time_sensor;
root["publish_time_heartbeat"] = settings.publish_time_heartbeat;
@@ -271,6 +272,7 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting
newSettings.publish_time_thermostat = root["publish_time_thermostat"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.publish_time_solar = root["publish_time_solar"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.publish_time_mixer = root["publish_time_mixer"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.publish_time_water = root["publish_time_water"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.publish_time_other = root["publish_time_other"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.publish_time_sensor = root["publish_time_sensor"] | EMSESP_DEFAULT_PUBLISH_TIME;
newSettings.publish_time_heartbeat = root["publish_time_heartbeat"] | EMSESP_DEFAULT_PUBLISH_HEARTBEAT;
@@ -358,6 +360,10 @@ StateUpdateResult MqttSettings::update(JsonObject & root, MqttSettings & setting
emsesp::EMSESP::mqtt_.set_publish_time_mixer(newSettings.publish_time_mixer);
}
if (newSettings.publish_time_water != settings.publish_time_water) {
emsesp::EMSESP::mqtt_.set_publish_time_water(newSettings.publish_time_water);
}
if (newSettings.publish_time_other != settings.publish_time_other) {
emsesp::EMSESP::mqtt_.set_publish_time_other(newSettings.publish_time_other);
}

View File

@@ -82,6 +82,7 @@ class MqttSettings {
uint16_t publish_time_thermostat;
uint16_t publish_time_solar;
uint16_t publish_time_mixer;
uint16_t publish_time_water;
uint16_t publish_time_other;
uint16_t publish_time_sensor;
uint16_t publish_time_heartbeat;

View File

@@ -142,7 +142,7 @@
{160, DeviceType::MIXER, "MM100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
{161, DeviceType::MIXER, "MM200", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
{193, DeviceType::MIXER, "MZ100", DeviceFlags::EMS_DEVICE_FLAG_MMPLUS},
{204, DeviceType::MIXER, "MP100", DeviceFlags::EMS_DEVICE_FLAG_MP}, // pool
{204, DeviceType::POOL, "MP100", DeviceFlags::EMS_DEVICE_FLAG_MP}, // pool
// Heat Pumps - 0x38? This is a thermostat like RC100H
// also prod-id of wifi module and wireless base

View File

@@ -176,31 +176,76 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(boilTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&exhaustTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(exhaustTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatblock_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(heatblock),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&headertemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(headertemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas_, DeviceValueType::BOOL, FL_(burnGas), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas2_, DeviceValueType::BOOL, FL_(burnGas2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &flameCurr_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flameCurr), DeviceValueUOM::UA);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump_, DeviceValueType::BOOL, FL_(heatingPump), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fanWork_, DeviceValueType::BOOL, FL_(fanWork), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ignWork_, DeviceValueType::BOOL, FL_(ignWork), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &oilPreHeat_, DeviceValueType::BOOL, FL_(oilPreHeat), DeviceValueUOM::NONE);
if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&exhaustTemp_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(exhaustTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatblock_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(heatblock),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas_, DeviceValueType::BOOL, FL_(burnGas), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &burnGas2_, DeviceValueType::BOOL, FL_(burnGas2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&flameCurr_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(flameCurr),
DeviceValueUOM::UA);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &heatingPump_, DeviceValueType::BOOL, FL_(heatingPump), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &fanWork_, DeviceValueType::BOOL, FL_(fanWork), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &ignWork_, DeviceValueType::BOOL, FL_(ignWork), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &oilPreHeat_, DeviceValueType::BOOL, FL_(oilPreHeat), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&burnMinPower_,
DeviceValueType::UINT,
FL_(burnMinPower),
DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_min_power));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&burnMaxPower_,
DeviceValueType::UINT,
FL_(burnMaxPower),
DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_max_power),
0,
254);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on), -20, 0);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off), 0, 20);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOn_, DeviceValueType::INT, FL_(boil2HystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_on), -20, 0);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&boil2HystOff_,
DeviceValueType::INT,
FL_(boil2HystOff),
DeviceValueUOM::DEGREES_R,
MAKE_CF_CB(set_hyst2_off),
0,
20);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&burnMinPeriod_,
DeviceValueType::UINT,
FL_(burnMinPeriod),
DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_burn_period),
0,
120);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT, FL_(absBurnPow), DeviceValueUOM::PERCENT);
}
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&heatingActivated_,
DeviceValueType::BOOL,
@@ -215,33 +260,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
DeviceValueTAG::TAG_DEVICE_DATA, &pumpMode_, DeviceValueType::ENUM, FL_(enum_pumpMode), FL_(pumpMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_pumpMode));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &pumpDelay_, DeviceValueType::UINT, FL_(pumpDelay), DeviceValueUOM::MINUTES, MAKE_CF_CB(set_pump_delay), 0, 60);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&burnMinPeriod_,
DeviceValueType::UINT,
FL_(burnMinPeriod),
DeviceValueUOM::MINUTES,
MAKE_CF_CB(set_burn_period),
0,
120);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&burnMinPower_,
DeviceValueType::UINT,
FL_(burnMinPower),
DeviceValueUOM::PERCENT,
MAKE_CF_CB(set_min_power));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &burnMaxPower_, DeviceValueType::UINT, FL_(burnMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_power), 0, 254);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOn_, DeviceValueType::INT, FL_(boilHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_on), -20, 0);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boilHystOff_, DeviceValueType::INT, FL_(boilHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst_off), 0, 20);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOn_, DeviceValueType::INT, FL_(boil2HystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_on), -20, 0);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &boil2HystOff_, DeviceValueType::INT, FL_(boil2HystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_hyst2_off), 0, 20);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &absBurnPow_, DeviceValueType::UINT, FL_(absBurnPow), DeviceValueUOM::PERCENT);
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &selBurnPow_, DeviceValueType::UINT, FL_(selBurnPow), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_burn_power), 0, 254);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &curBurnPow_, DeviceValueType::UINT, FL_(curBurnPow), DeviceValueUOM::PERCENT);
@@ -924,7 +944,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
EMSESP::send_read_request(0xC2, device_id); // read last errorcode on start (only published on errors)
if (model() != EMS_DEVICE_FLAG_HEATPUMP) {
if (model() != EMS_DEVICE_FLAG_HEATPUMP && model() != EMS_DEVICE_FLAG_HIU) {
register_telegram_type(0x04, "UBAFactory", true, MAKE_PF_CB(process_UBAFactory));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &nomPower_, DeviceValueType::UINT, FL_(nomPower), DeviceValueUOM::KW, MAKE_CF_CB(set_nomPower));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
@@ -1269,7 +1289,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram
has_update(telegram, heatblock_, 23); // see #1317
has_update(telegram, headertemp_, 25); // see #1317
//has_update(telegram, temperatur_, 27); // unknown temperature
telegram->read_value(exhaustTemp1_ , 31);
telegram->read_value(exhaustTemp1_, 31);
if (Helpers::hasValue(exhaustTemp1_)) {
has_update(exhaustTemp_, exhaustTemp1_);
}

View File

@@ -26,61 +26,16 @@ uuid::log::Logger Mixer::logger_{F_(mixer), uuid::log::Facility::CONSOLE};
Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
// Pool module
if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) {
register_telegram_type(0x5BA, "HpPoolStatus", true, MAKE_PF_CB(process_HpPoolStatus));
type_ = Type::MP;
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&poolTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(poolTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT, FL_(poolShunt), DeviceValueUOM::PERCENT);
}
// EMS+
if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
if (device_id >= 0x20 && device_id <= 0x27) {
register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC));
// register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
type_ = Type::HC;
hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT);
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
} else if (device_id >= 0x28 && device_id <= 0x29) {
register_telegram_type(device_id - 0x28 + 0x0331, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
register_telegram_type(device_id - 0x28 + 0x0313, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC));
// register_telegram_type(device_id - 0x28 + 0x033B, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC));
type_ = Type::WWC;
hc_ = device_id - 0x28 + 1;
uint8_t tag = DeviceValueTAG::TAG_WWC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(wwPumpStatus), DeviceValueUOM::NONE);
register_device_value(tag, &status_, DeviceValueType::INT, FL_(wwTempStatus), DeviceValueUOM::NONE);
register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp));
register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp));
register_device_value(tag,
&wwDisinfectionTemp_,
DeviceValueType::UINT,
FL_(wwDisinfectionTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(tag, &wwReducedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwReducedTemp));
register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwCircPump_,
DeviceValueType::BOOL,
FL_(wwCircPump),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwCircPump));
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
}
register_telegram_type(device_id - 0x20 + 0x02D7, "MMPLUSStatusMessage_HC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC));
// register_telegram_type(device_id - 0x20 + 0x02E1, "MMPLUSSetMessage_HC", true, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
register_device_value(tag, &status_, DeviceValueType::UINT, FL_(mixerStatus), DeviceValueUOM::PERCENT);
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
}
// EMS 1.0
@@ -88,7 +43,6 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
register_telegram_type(0x00AA, "MMConfigMessage", true, MAKE_PF_CB(process_MMConfigMessage));
register_telegram_type(0x00AB, "MMStatusMessage", false, MAKE_PF_CB(process_MMStatusMessage));
register_telegram_type(0x00AC, "MMSetMessage", false, MAKE_PF_CB(process_MMSetMessage));
type_ = Type::HC;
hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
@@ -109,48 +63,16 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
// HT3
if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
if (device_id >= 0x40) { // special DHW pos 10
register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_IPMMonitorWW));
register_telegram_type(0x1E, "HydrTemp", false, MAKE_PF_CB(process_IPMHydrTemp));
register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_IPMParameterWW));
// register_telegram_type(0x10D, "wwNTCStatus", false, MAKE_PF_CB(process_wwNTCStatus));
type_ = Type::WWC;
hc_ = device_id - 0x40 + 1;
uint8_t tag = DeviceValueTAG::TAG_WWC9 + hc_ - 1;
register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp));
register_device_value(tag, &wwCurTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwCurTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwCurTemp2), DeviceValueUOM::DEGREES);
register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE);
register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset));
register_device_value(tag, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn));
register_device_value(tag, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff));
register_device_value(tag,
&wwDisinfectionTemp_,
DeviceValueType::UINT,
FL_(wwDisinfectionTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwCircPump_,
DeviceValueType::BOOL,
FL_(wwCircPump),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwCircPump));
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
} else {
register_telegram_type(0x010C, "IPMStatusMessage", false, MAKE_PF_CB(process_IPMStatusMessage));
register_telegram_type(0x011E, "IPMTempMessage", false, MAKE_PF_CB(process_IPMTempMessage));
// register_telegram_type(0x0123, "IPMSetMessage", false, MAKE_PF_CB(process_IPMSetMessage));
type_ = Type::HC;
hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
register_device_value(tag, &status_, DeviceValueType::INT, FL_(mixerStatus), DeviceValueUOM::PERCENT);
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES);
}
register_telegram_type(0x010C, "IPMStatusMessage", false, MAKE_PF_CB(process_IPMStatusMessage));
register_telegram_type(0x011E, "IPMTempMessage", false, MAKE_PF_CB(process_IPMTempMessage));
// register_telegram_type(0x0123, "IPMSetMessage", false, MAKE_PF_CB(process_IPMSetMessage));
hc_ = device_id - 0x20 + 1;
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempHc), DeviceValueUOM::DEGREES);
register_device_value(tag, &status_, DeviceValueType::UINT, FL_(mixerStatus), DeviceValueUOM::PERCENT);
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(flowTempVf), DeviceValueUOM::DEGREES);
}
}
@@ -164,15 +86,6 @@ void Mixer::process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> teleg
has_update(telegram, status_, 2); // valve status
}
// Mixer warm water loading/DHW - 0x0331, 0x0332
// e.g. A9 00 FF 00 02 32 02 6C 00 3C 00 3C 3C 46 02 03 03 00 3C // on 0x28
// A8 00 FF 00 02 31 02 35 00 3C 00 3C 3C 46 02 03 03 00 3C // in 0x29
void Mixer::process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, flowTempHc_, 0); // is * 10
has_bitupdate(telegram, pumpStatus_, 2, 0);
has_update(telegram, status_, 11); // temp status
}
// Mixer IPM - 0x010C
// e.g. A0 00 FF 00 00 0C 01 00 00 00 00 00 54
// A1 00 FF 00 00 0C 02 04 00 01 1D 00 82
@@ -200,15 +113,6 @@ void Mixer::process_IPMTempMessage(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, flowTempVf_, 0); // TC1, is * 10
}
// Mixer MP100 for pools - 0x5BA
void Mixer::process_HpPoolStatus(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, poolTemp_, 0);
has_update(telegram, poolShunt_, 3); // 0-100% how much is the shunt open?
telegram->read_value(poolShuntStatus__, 2);
uint8_t pss = poolShunt_ == 100 ? 3 : (poolShunt_ == 0 ? 4 : poolShuntStatus__);
has_update(poolShuntStatus_, pss);
}
// Mixer on a MM10 - 0xAB
// e.g. Mixer Module -> All, type 0xAB, telegram: 21 00 AB 00 2D 01 BE 64 04 01 00 (CRC=15) #data=7
// see also https://github.com/emsesp/EMS-ESP/issues/386
@@ -235,43 +139,6 @@ void Mixer::process_MMConfigMessage(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s
}
// Config message 0x313, has to be fetched
void Mixer::process_MMPLUSConfigMessage_WWC(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwRequiredTemp_, 4);
has_update(telegram, wwReducedTemp_, 5);
has_update(telegram, wwDiffTemp_, 7);
has_update(telegram, wwDisinfectionTemp_, 9);
has_update(telegram, wwMaxTemp_, 10);
}
// 0x34 only 8 bytes long
// Mixer(0x41) -> All(0x00), UBAMonitorWW(0x34), data: 37 02 1E 02 1E 00 00 00 00
void Mixer::process_IPMMonitorWW(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwSelTemp_, 0);
has_update(telegram, wwCurTemp_1_, 1);
has_update(telegram, wwCurTemp_2_, 3);
has_bitupdate(telegram, pumpStatus_, 5, 3);
}
// Mixer(0x41) -> Me(0x0B), UBAParameterWW(0x33), data: 08 FF 46 FB FF 28 FF 07 46 00 FF 00
void Mixer::process_IPMParameterWW(std::shared_ptr<const Telegram> telegram) {
// has_update(telegram, wwActivated_, 1); // 0xFF means on
// has_update(telegram, wwSelTemp_, 2);
has_update(telegram, wwHystOn_, 3); // Hyst on (default -5)
has_update(telegram, wwHystOff_, 4); // Hyst off (default -1)
has_update(telegram, wwFlowTempOffset_, 5); // default 40
has_update(telegram, wwCircPump_, 6); // 0xFF means on
has_update(telegram, wwCircMode_, 7); // 1=1x3min 6=6x3min 7=continuous
has_update(telegram, wwDisinfectionTemp_, 8);
// has_bitupdate(telegram, wwChargeType_, 10, 0); // 0 = charge pump, 0xff = 3-way valve
}
// 0x1E, only16 bit temperature
// Mixer(0x41) -> Boiler(0x08), HydrTemp(0x1E), data: 01 D8
void Mixer::process_IPMHydrTemp(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, HydrTemp_, 0);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
@@ -284,16 +151,6 @@ void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr<const Telegram> telegram
// pos2: pump
}
// unknown, 2 examples from older threads
// Thermostat(0x10) -> Mixer(0x28), ?(0x33B), data: 01 01 00
// Thermostat -> Mixing Module, type 0x023B, telegram: 90 28 FF 00 02 3B 00 02 00 (CRC=68)
void Mixer::process_MMPLUSSetMessage_WWC(std::shared_ptr<const Telegram> telegram) {
}
// MMPLUS telegram 0x345 unknown
// Solar Module -> Mixing Module, type 0x0245, telegram: B0 28 FF 00 02 45 64 01 01 (CRC=36)
// ?
// Mixer on a MM10 - 0xAC
// e.g. Thermostat -> Mixer Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB
void Mixer::process_MMSetMessage(std::shared_ptr<const Telegram> telegram) {
@@ -311,15 +168,6 @@ void Mixer::process_IPMSetMessage(std::shared_ptr<const Telegram> telegram) {
#pragma GCC diagnostic pop
bool Mixer::set_wwSelTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
write_command(0x35, 3, (uint8_t)temperature, 0x34);
return true;
}
bool Mixer::set_flowSetTemp(const char * value, const int8_t id) {
int v;
if (!Helpers::value2number(value, v)) {
@@ -389,113 +237,4 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) {
return false;
}
bool Mixer::set_wwMaxTemp(const char * value, const int8_t id) {
uint8_t wwc = device_id() - 0x28;
float v;
if (!Helpers::value2temperature(value, v)) {
return false;
}
write_command(0x313 + wwc, 10, (uint8_t)v, 0x313 + wwc);
return true;
}
bool Mixer::set_wwDiffTemp(const char * value, const int8_t id) {
uint8_t wwc = device_id() - 0x28;
float v;
if (!Helpers::value2temperature(value, v)) {
return false;
}
write_command(0x313 + wwc, 7, (int8_t)(v * 10), 0x313 + wwc);
return true;
}
bool Mixer::set_wwReducedTemp(const char * value, const int8_t id) {
uint8_t wwc = device_id() - 0x28;
float v;
if (!Helpers::value2temperature(value, v)) {
return false;
}
write_command(0x313 + wwc, 5, (uint8_t)v, 0x313 + wwc);
return true;
}
bool Mixer::set_wwRequiredTemp(const char * value, const int8_t id) {
uint8_t wwc = device_id() - 0x28;
float v;
if (!Helpers::value2temperature(value, v)) {
return false;
}
write_command(0x313 + wwc, 4, (uint8_t)v, 0x313 + wwc);
return true;
}
bool Mixer::set_wwDisinfectionTemp(const char * value, const int8_t id) {
float v;
if (!Helpers::value2temperature(value, v)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
write_command(0x33, 8, (uint8_t)v, 0x33);
} else {
uint8_t wwc = device_id() - 0x28;
write_command(0x313 + wwc, 9, (uint8_t)v, 0x313 + wwc);
}
return true;
}
bool Mixer::set_wwCircPump(const char * value, const int8_t id) {
bool v;
if (!Helpers::value2bool(value, v)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
write_command(0x33, 6, v ? 0xFF : 0x00, 0x33);
} else {
uint8_t wwc = device_id() - 0x28;
write_command(0x33B + wwc, 0, v ? 0x01 : 0x00, 0x33B + wwc);
}
return true;
}
bool Mixer::set_wwCircMode(const char * value, const int8_t id) {
uint8_t n;
if (!Helpers::value2enum(value, n, FL_(enum_wwCircMode))) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
write_command(0x33, 7, n, 0x33);
} else {
uint8_t wwc = device_id() - 0x28;
write_command(0x313 + wwc, 0, n, 0x313 + wwc);
}
return true;
}
bool Mixer::set_wwFlowTempOffset(const char * value, const int8_t id) {
int n;
if (!Helpers::value2number(value, n)) {
return false;
}
write_command(0x33, 5, n, 0x33);
return true;
}
bool Mixer::set_wwHystOn(const char * value, const int8_t id) {
int n;
if (!Helpers::value2number(value, n)) {
return false;
}
write_command(0x33, 3, n, 0x33);
return true;
}
bool Mixer::set_wwHystOff(const char * value, const int8_t id) {
int n;
if (!Helpers::value2number(value, n)) {
return false;
}
write_command(0x33, 4, n, 0x33);
return true;
}
} // namespace emsesp

View File

@@ -32,46 +32,18 @@ class Mixer : public EMSdevice {
void process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram);
void process_MMPLUSSetMessage_HC(std::shared_ptr<const Telegram> telegram);
void process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram);
void process_MMPLUSSetMessage_WWC(std::shared_ptr<const Telegram> telegram);
void process_MMPLUSConfigMessage_WWC(std::shared_ptr<const Telegram> telegram);
void process_IPMStatusMessage(std::shared_ptr<const Telegram> telegram);
void process_IPMTempMessage(std::shared_ptr<const Telegram> telegram);
void process_IPMSetMessage(std::shared_ptr<const Telegram> telegram);
void process_MMStatusMessage(std::shared_ptr<const Telegram> telegram);
void process_MMConfigMessage(std::shared_ptr<const Telegram> telegram);
void process_MMSetMessage(std::shared_ptr<const Telegram> telegram);
void process_HpPoolStatus(std::shared_ptr<const Telegram> telegram);
void process_IPMMonitorWW(std::shared_ptr<const Telegram> telegram);
void process_IPMHydrTemp(std::shared_ptr<const Telegram> telegram);
void process_IPMParameterWW(std::shared_ptr<const Telegram> telegram);
bool set_flowSetTemp(const char * value, const int8_t id);
bool set_pump(const char * value, const int8_t id);
bool set_activated(const char * value, const int8_t id);
bool set_setValveTime(const char * value, const int8_t id);
bool set_wwMaxTemp(const char * value, const int8_t id);
bool set_wwDiffTemp(const char * value, const int8_t id);
bool set_wwReducedTemp(const char * value, const int8_t id);
bool set_wwRequiredTemp(const char * value, const int8_t id);
bool set_wwDisinfectionTemp(const char * value, const int8_t id);
bool set_wwCircPump(const char * value, const int8_t id);
bool set_wwCircMode(const char * value, const int8_t id);
bool set_wwSelTemp(const char * value, const int8_t id);
bool set_wwFlowTempOffset(const char * value, const int8_t id);
bool set_wwHystOn(const char * value, const int8_t id);
bool set_wwHystOff(const char * value, const int8_t id);
enum class Type {
NONE,
HC, // heating circuit
WWC, // warm water circuit
MP // pool
};
private:
uint16_t flowTempHc_;
uint16_t flowTempVf_;
@@ -81,31 +53,7 @@ class Mixer : public EMSdevice {
uint8_t activated_;
uint8_t setValveTime_;
// MM100wwParam - 0x0313, 0x033B
uint8_t wwMaxTemp_;
uint8_t wwRequiredTemp_;
uint8_t wwReducedTemp_;
uint8_t wwDiffTemp_;
uint8_t wwDisinfectionTemp_;
uint8_t wwCircPump_;
uint8_t wwCircMode_;
// MP100 pool
int16_t poolTemp_;
uint8_t poolShuntStatus_;
uint8_t poolShunt_;
Type type_ = Type::NONE;
uint16_t hc_ = EMS_VALUE_USHORT_NOTSET;
uint8_t poolShuntStatus__ = EMS_VALUE_UINT_NOTSET; // temp value
uint8_t wwSelTemp_;
uint16_t wwCurTemp_1_;
uint16_t wwCurTemp_2_;
uint16_t HydrTemp_;
int8_t wwHystOn_; // Hyst on (default -5)
int8_t wwHystOff_; // Hyst off (default -1)
uint8_t wwFlowTempOffset_; // default 40
};
} // namespace emsesp

50
src/devices/pool.cpp Normal file
View File

@@ -0,0 +1,50 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020-2023 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pool.h"
namespace emsesp {
REGISTER_FACTORY(Pool, EMSdevice::DeviceType::POOL);
uuid::log::Logger Pool::logger_{F_(pool), uuid::log::Facility::CONSOLE};
Pool::Pool(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
// Pool module
register_telegram_type(0x5BA, "HpPoolStatus", true, MAKE_PF_CB(process_HpPoolStatus));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&poolTemp_,
DeviceValueType::SHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(poolTemp),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &poolShunt_, DeviceValueType::UINT, FL_(poolShunt), DeviceValueUOM::PERCENT);
}
// Mixer MP100 for pools - 0x5BA
void Pool::process_HpPoolStatus(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, poolTemp_, 0);
has_update(telegram, poolShunt_, 3); // 0-100% how much is the shunt open?
telegram->read_value(poolShuntStatus__, 2);
uint8_t pss = poolShunt_ == 100 ? 3 : (poolShunt_ == 0 ? 4 : poolShuntStatus__);
has_update(poolShuntStatus_, pss);
}
} // namespace emsesp

46
src/devices/pool.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020-2023 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EMSESP_POOL_H
#define EMSESP_POOL_H
#include "emsesp.h"
namespace emsesp {
class Pool : public EMSdevice {
public:
Pool(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
private:
static uuid::log::Logger logger_;
void process_HpPoolStatus(std::shared_ptr<const Telegram> telegram);
private:
// MP100 pool
int16_t poolTemp_;
uint8_t poolShuntStatus_;
uint8_t poolShunt_;
uint8_t poolShuntStatus__ = EMS_VALUE_UINT_NOTSET; // temp value
};
} // namespace emsesp
#endif

View File

@@ -34,32 +34,22 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
}
if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) {
if (device_id == 0x2A) { // SM100 DHW
register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature));
register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus));
register_telegram_type(0x07AB, "SM100wwCommand", false, MAKE_PF_CB(process_SM100wwCommand));
register_telegram_type(0x07A5, "SM100wwCirc", true, MAKE_PF_CB(process_SM100wwCirc));
register_telegram_type(0x07A6, "SM100wwParam", true, MAKE_PF_CB(process_SM100wwParam));
register_telegram_type(0x07AE, "SM100wwKeepWarm", true, MAKE_PF_CB(process_SM100wwKeepWarm));
register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2));
} else {
// F9 is not a telegram type, it's a flag for configure
// register_telegram_type(0xF9, "ParamCfg", false, MAKE_PF_CB(process_SM100ParamCfg));
register_telegram_type(0x0358, "SM100SystemConfig", true, MAKE_PF_CB(process_SM100SystemConfig));
register_telegram_type(0x035A, "SM100CircuitConfig", true, MAKE_PF_CB(process_SM100CircuitConfig));
register_telegram_type(0x035D, "SM100Circuit2Config", true, MAKE_PF_CB(process_SM100Circuit2Config));
register_telegram_type(0x0362, "SM100Monitor", false, MAKE_PF_CB(process_SM100Monitor));
register_telegram_type(0x0363, "SM100Monitor2", false, MAKE_PF_CB(process_SM100Monitor2));
register_telegram_type(0x0366, "SM100Config", false, MAKE_PF_CB(process_SM100Config));
register_telegram_type(0x0364, "SM100Status", false, MAKE_PF_CB(process_SM100Status));
register_telegram_type(0x036A, "SM100Status2", false, MAKE_PF_CB(process_SM100Status2));
register_telegram_type(0x0380, "SM100CollectorConfig", true, MAKE_PF_CB(process_SM100CollectorConfig));
register_telegram_type(0x038E, "SM100Energy", true, MAKE_PF_CB(process_SM100Energy));
register_telegram_type(0x0391, "SM100Time", true, MAKE_PF_CB(process_SM100Time));
register_telegram_type(0x035F, "SM100Config1", true, MAKE_PF_CB(process_SM100Config1));
register_telegram_type(0x035C, "SM100HeatAssist", true, MAKE_PF_CB(process_SM100HeatAssist));
register_telegram_type(0x0361, "SM100Differential", true, MAKE_PF_CB(process_SM100Differential));
}
// F9 is not a telegram type, it's a flag for configure
// register_telegram_type(0xF9, "ParamCfg", false, MAKE_PF_CB(process_SM100ParamCfg));
register_telegram_type(0x0358, "SM100SystemConfig", true, MAKE_PF_CB(process_SM100SystemConfig));
register_telegram_type(0x035A, "SM100CircuitConfig", true, MAKE_PF_CB(process_SM100CircuitConfig));
register_telegram_type(0x035D, "SM100Circuit2Config", true, MAKE_PF_CB(process_SM100Circuit2Config));
register_telegram_type(0x0362, "SM100Monitor", false, MAKE_PF_CB(process_SM100Monitor));
register_telegram_type(0x0363, "SM100Monitor2", false, MAKE_PF_CB(process_SM100Monitor2));
register_telegram_type(0x0366, "SM100Config", false, MAKE_PF_CB(process_SM100Config));
register_telegram_type(0x0364, "SM100Status", false, MAKE_PF_CB(process_SM100Status));
register_telegram_type(0x036A, "SM100Status2", false, MAKE_PF_CB(process_SM100Status2));
register_telegram_type(0x0380, "SM100CollectorConfig", true, MAKE_PF_CB(process_SM100CollectorConfig));
register_telegram_type(0x038E, "SM100Energy", true, MAKE_PF_CB(process_SM100Energy));
register_telegram_type(0x0391, "SM100Time", true, MAKE_PF_CB(process_SM100Time));
register_telegram_type(0x035F, "SM100Config1", true, MAKE_PF_CB(process_SM100Config1));
register_telegram_type(0x035C, "SM100HeatAssist", true, MAKE_PF_CB(process_SM100HeatAssist));
register_telegram_type(0x0361, "SM100Differential", true, MAKE_PF_CB(process_SM100Differential));
}
if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) {
@@ -69,94 +59,6 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
}
// device values...
// special case for a SM100 DHW device_id with 0x2A where it's not actual a solar module
if (device_id == 0x2A) {
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_1_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp1),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_3_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp3),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_4_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp4),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_5_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp5),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwTemp_7_,
DeviceValueType::USHORT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwTemp7),
DeviceValueUOM::DEGREES);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwMaxTemp_,
DeviceValueType::UINT,
FL_(wwMaxTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwMaxTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwSelTemp_,
DeviceValueType::UINT,
FL_(wwSelTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwSelTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwRedTemp_,
DeviceValueType::UINT,
FL_(wwRedTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwRedTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDailyTemp_,
DeviceValueType::UINT,
FL_(wwDailyTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDailyTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwDisinfectionTemp_,
DeviceValueType::UINT,
FL_(wwDisinfectionTemp),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwCircMode_,
DeviceValueType::ENUM,
FL_(enum_wwCircMode),
FL_(wwCircMode),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwCircMode));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwKeepWarm_,
DeviceValueType::BOOL,
FL_(wwKeepWarm),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_wwKeepWarm));
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT);
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
&wwFlow_,
DeviceValueType::UINT,
DeviceValueNumOp::DV_NUMOP_DIV10,
FL_(wwFlow),
DeviceValueUOM::LMIN);
return;
}
// common solar values for all modules (except dhw)
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA,
&collectorTemp_,
@@ -690,58 +592,6 @@ void Solar::process_SM100Monitor(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, retHeatAssist_, 10); // is *10 - TS15: return temperature heating assistance
}
// SM100wwTemperature - 0x07D6
// Solar Module(0x2A) -> (0x00), (0x7D6), data: 01 C1 00 00 02 5B 01 AF 01 AD 80 00 01 90
void Solar::process_SM100wwTemperature(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwTemp_1_, 0); // is *10
has_update(telegram, wwTemp_3_, 4); // is *10
has_update(telegram, wwTemp_4_, 6); // is *10
has_update(telegram, wwTemp_5_, 8); // is *10
has_update(telegram, wwTemp_7_, 12); // is *10
}
// SM100wwStatus - 0x07AA
// Solar Module(0x2A) -> (0x00), (0x7AA), data: 64 00 04 00 03 00 28 01 0F
void Solar::process_SM100wwStatus(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwPump_, 0);
}
// SM100wwParam - 0x07A6, Solar Module(0x2A) -> (0x00)
// data: FF 05 0F 5F 00 01 3C 3C 3C 3C 28 12 46 01 3C 1E 03 07 3C 00 0F 00 05
void Solar::process_SM100wwParam(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwMaxTemp_, 8);
has_update(telegram, wwSelTemp_, 9);
has_update(telegram, wwRedTemp_, 10);
has_update(telegram, wwDailyTemp_, 6);
has_update(telegram, wwDisinfectionTemp_, 12);
// (daily heating time thermostat 2F5, offset 9, offset 8 on/off)
}
// SM100wwCirc - 0x07A5
// Solar Module(0x2A) -> (0x00), (0x7A5), data:
void Solar::process_SM100wwCirc(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwCirc_, 0);
has_update(telegram, wwCircMode_, 3);
}
// SM100wwKeepWarm - 0x7AE, keepWarm
// Thermostat(0x10) -> Solar(0x2A), ?(0x7AE), data: FF
void Solar::process_SM100wwKeepWarm(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwKeepWarm_, 0);
}
/*
// SM100ww? - 0x7E0, some kind of status
// data: 00 00 46 00 00 01 06 0E 06 0E 00 00 00 00 00 03 03 03 03
// publishes single values offset 1/2(16bit), offset 5, offset 6, offset 7, offset 8, offset 9,
// status2 = 03:"no heat", 06:"heat request", 08:"disinfecting", 09:"hold"
*/
void Solar::process_SM100wwStatus2(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwFlow_, 7);
has_update(telegram, wwStatus2_, 8);
has_update(telegram, wwPumpMod_, 9);
}
// SM100Monitor2 - 0x0363 Heatcounter
// e.g. B0 00 FF 00 02 63 80 00 80 00 00 00 80 00 80 00 80 00 00 80 00 5A
// Solar(0x30) -> All(0x00), SM100Monitor2(0x363), data: 01 E1 01 6B 00 00 01 5D 02 8E 80 00 0F 80 00
@@ -753,17 +603,6 @@ void Solar::process_SM100Monitor2(std::shared_ptr<const Telegram> telegram) {
has_update(telegram->read_value(swapFlowTemp_, 8)); // is *10
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
// SM100wwCommand - 0x07AB
// Thermostat(0x10) -> Solar Module(0x2A), (0x7AB), data: 01 00 01
void Solar::process_SM100wwCommand(std::shared_ptr<const Telegram> telegram) {
// not implemented yet
}
#pragma GCC diagnostic pop
// SM100Config - 0x0366
// e.g. B0 00 FF 00 02 66 01 62 00 13 40 14
void Solar::process_SM100Config(std::shared_ptr<const Telegram> telegram) {
@@ -1249,76 +1088,4 @@ bool Solar::set_diffControl(const char * value, const int8_t id) {
return true;
}
bool Solar::set_wwSelTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
write_command(0x7A6, 9, (uint8_t)temperature, 0x7A6);
return true;
}
bool Solar::set_wwMaxTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
write_command(0x7A6, 8, (uint8_t)temperature, 0x7A6);
return true;
}
bool Solar::set_wwRedTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
write_command(0x7A6, 10, (uint8_t)temperature, 0x7A6);
return true;
}
bool Solar::set_wwDailyTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
write_command(0x7A6, 6, (uint8_t)temperature, 0x7A6);
return true;
}
bool Solar::set_wwDisinfectionTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
write_command(0x7A6, 12, (uint8_t)temperature, 0x7A6);
return true;
}
bool Solar::set_wwCirc(const char * value, const int8_t id) {
bool b;
if (!Helpers::value2bool(value, b)) {
return false;
}
write_command(0x7A5, 0, b ? 0xFF : 0x00, 0x7A5);
return true;
}
bool Solar::set_wwCircMode(const char * value, const int8_t id) {
uint8_t num;
if (!Helpers::value2enum(value, num, FL_(enum_wwCircMode))) {
return false;
}
write_command(0x7A5, 3, num, 0x7A5);
return true;
}
bool Solar::set_wwKeepWarm(const char * value, const int8_t id) {
bool b;
if (!Helpers::value2bool(value, b)) {
return false;
}
write_command(0x7AE, 0, b ? 0xFF : 0x00, 0x7AE);
return true;
}
} // namespace emsesp

View File

@@ -114,35 +114,6 @@ class Solar : public EMSdevice {
uint16_t collector2Area_; // Area of collector field 2
uint8_t collector2Type_; // Type of collector field 2, 01=flat, 02=vacuum
// SM100wwTemperature - 0x07D6
uint16_t wwTemp_1_;
uint16_t wwTemp_3_;
uint16_t wwTemp_4_;
uint16_t wwTemp_5_;
uint16_t wwTemp_7_;
// SM100wwStatus - 0x07AA
uint8_t wwPump_;
// SM100wwParam - 0x07A6
uint8_t wwMaxTemp_;
uint8_t wwSelTemp_;
uint8_t wwRedTemp_;
uint8_t wwDailyTemp_;
uint8_t wwDisinfectionTemp_;
// SM100wwKeepWarm - 0x07AE
uint8_t wwKeepWarm_;
// SM100wwCirc - 0x07A5
uint8_t wwCirc_;
uint8_t wwCircMode_;
// SM100wwStatus2 - 0x07E0
uint8_t wwFlow_;
uint8_t wwPumpMod_;
uint8_t wwStatus2_;
// SM10Config - 0x96
uint8_t wwMinTemp_;
uint8_t maxFlow_; // set this to calculate power
@@ -178,14 +149,6 @@ class Solar : public EMSdevice {
void process_SM100HeatAssist(std::shared_ptr<const Telegram> telegram);
void process_SM100Differential(std::shared_ptr<const Telegram> telegram);
void process_SM100wwTemperature(std::shared_ptr<const Telegram> telegram);
void process_SM100wwStatus(std::shared_ptr<const Telegram> telegram);
void process_SM100wwStatus2(std::shared_ptr<const Telegram> telegram);
void process_SM100wwCommand(std::shared_ptr<const Telegram> telegram);
void process_SM100wwCirc(std::shared_ptr<const Telegram> telegram);
void process_SM100wwParam(std::shared_ptr<const Telegram> telegram);
void process_SM100wwKeepWarm(std::shared_ptr<const Telegram> telegram);
void process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram);
void process_ISM1Set(std::shared_ptr<const Telegram> telegram);
void process_ISM2StatusMessage(std::shared_ptr<const Telegram> telegram);
@@ -226,14 +189,6 @@ class Solar : public EMSdevice {
bool set_heatAssist(const char * value, const int8_t id);
bool set_diffControl(const char * value, const int8_t id);
bool set_wwSelTemp(const char * value, const int8_t id);
bool set_wwMaxTemp(const char * value, const int8_t id);
bool set_wwRedTemp(const char * value, const int8_t id);
bool set_wwCirc(const char * value, const int8_t id);
bool set_wwCircMode(const char * value, const int8_t id);
bool set_wwKeepWarm(const char * value, const int8_t id);
bool set_wwDisinfectionTemp(const char * value, const int8_t id);
bool set_wwDailyTemp(const char * value, const int8_t id);
};
} // namespace emsesp

392
src/devices/water.cpp Normal file
View File

@@ -0,0 +1,392 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020-2023 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "water.h"
namespace emsesp {
REGISTER_FACTORY(Water, EMSdevice::DeviceType::WATER);
uuid::log::Logger Water::logger_{F_(water), uuid::log::Facility::CONSOLE};
Water::Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
uint8_t tag = DeviceValueTAG::TAG_WWC1 + device_id - EMSdevice::EMS_DEVICE_ID_DHW1;
if (device_id == 0x2A) { // SM100, DHW3
wwc_ = 2;
// telegram handlers
register_telegram_type(0x07D6, "SM100wwTemperature", false, MAKE_PF_CB(process_SM100wwTemperature));
register_telegram_type(0x07AA, "SM100wwStatus", false, MAKE_PF_CB(process_SM100wwStatus));
register_telegram_type(0x07AB, "SM100wwCommand", false, MAKE_PF_CB(process_SM100wwCommand));
register_telegram_type(0x07A5, "SM100wwCirc", true, MAKE_PF_CB(process_SM100wwCirc));
register_telegram_type(0x07A6, "SM100wwParam", true, MAKE_PF_CB(process_SM100wwParam));
register_telegram_type(0x07AE, "SM100wwKeepWarm", true, MAKE_PF_CB(process_SM100wwKeepWarm));
register_telegram_type(0x07E0, "SM100wwStatus2", true, MAKE_PF_CB(process_SM100wwStatus2));
// device values...
register_device_value(tag, &wwTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp1), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwTemp_3_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp3), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwTemp_4_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp4), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwTemp_5_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp5), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwTemp_6_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp6), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwTemp_7_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp7), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE);
register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp));
register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp));
register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp));
register_device_value(tag, &wwDailyTemp_, DeviceValueType::UINT, FL_(wwDailyTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDailyTemp));
register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc));
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
register_device_value(tag, &wwKeepWarm_, DeviceValueType::BOOL, FL_(wwKeepWarm), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwKeepWarm));
register_device_value(tag, &wwStatus2_, DeviceValueType::ENUM, FL_(enum_wwStatus2), FL_(wwStatus2), DeviceValueUOM::NONE);
register_device_value(tag, &wwPumpMod_, DeviceValueType::UINT, FL_(wwPumpMod), DeviceValueUOM::PERCENT);
register_device_value(tag, &wwFlow_, DeviceValueType::UINT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwFlow), DeviceValueUOM::LMIN);
} else if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW2) {
wwc_ = device_id - EMSdevice::EMS_DEVICE_ID_DHW1;
register_telegram_type(0x331 + wwc_, "MMPLUSStatusMessage_WWC", false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
register_telegram_type(0x313 + wwc_, "MMPLUSConfigMessage_WWC", true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC));
// register_telegram_type(0x33B + type_offset, "MMPLUSSetMessage_WWC", true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC));
// device values...
register_device_value(tag, &wwFlowTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwStatus_, DeviceValueType::INT, FL_(wwTempStatus), DeviceValueUOM::NONE);
register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE);
register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp));
register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp));
register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(tag, &wwRedTemp_, DeviceValueType::UINT, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRedTemp));
register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp));
register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc));
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
} else if (device_id == 0x40) { // flags == EMSdevice::EMS_DEVICE_FLAG_IPM, special DHW pos 10
wwc_ = 0;
tag = DeviceValueTAG::TAG_WWC1;
register_telegram_type(0x34, "UBAMonitorWW", false, MAKE_PF_CB(process_IPMMonitorWW));
register_telegram_type(0x1E, "HydrTemp", false, MAKE_PF_CB(process_IPMHydrTemp));
register_telegram_type(0x33, "UBAParameterWW", true, MAKE_PF_CB(process_IPMParameterWW));
// register_telegram_type(0x10D, "wwNTCStatus", false, MAKE_PF_CB(process_wwNTCStatus));
// device values...
register_device_value(tag, &wwSelTemp_, DeviceValueType::UINT, FL_(wwSelTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwSelTemp));
register_device_value(tag, &wwTemp_1_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp1), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwTemp_2_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(wwTemp2), DeviceValueUOM::DEGREES);
register_device_value(tag, &HydrTemp_, DeviceValueType::USHORT, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(hydrTemp), DeviceValueUOM::DEGREES);
register_device_value(tag, &wwPump_, DeviceValueType::BOOL, FL_(wwPump), DeviceValueUOM::NONE);
register_device_value(tag, &wwFlowTempOffset_, DeviceValueType::UINT, FL_(wwFlowTempOffset), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwFlowTempOffset));
register_device_value(tag, &wwHystOn_, DeviceValueType::INT, FL_(wwHystOn), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOn));
register_device_value(tag, &wwHystOff_, DeviceValueType::INT, FL_(wwHystOff), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwHystOff));
register_device_value(tag, &wwDisinfectionTemp_, DeviceValueType::UINT, FL_(wwDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwDisinfectionTemp));
register_device_value(tag, &wwCirc_, DeviceValueType::BOOL, FL_(wwCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCirc));
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
}
}
// SM100wwTemperature - 0x07D6
// Solar Module(0x2A) -> (0x00), (0x7D6), data: 01 C1 00 00 02 5B 01 AF 01 AD 80 00 01 90
void Water::process_SM100wwTemperature(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwTemp_1_, 0); // is *10
has_update(telegram, wwTemp_2_, 2); // is *10
has_update(telegram, wwTemp_3_, 4); // is *10
has_update(telegram, wwTemp_4_, 6); // is *10
has_update(telegram, wwTemp_5_, 8); // is *10
has_update(telegram, wwTemp_6_, 10); // is *10
has_update(telegram, wwTemp_7_, 12); // is *10
}
// SM100wwStatus - 0x07AA
// Solar Module(0x2A) -> (0x00), (0x7AA), data: 64 00 04 00 03 00 28 01 0F
void Water::process_SM100wwStatus(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwPump_, 0);
}
// SM100wwParam - 0x07A6, Solar Module(0x2A) -> (0x00)
// data: FF 05 0F 5F 00 01 3C 3C 3C 3C 28 12 46 01 3C 1E 03 07 3C 00 0F 00 05
void Water::process_SM100wwParam(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwMaxTemp_, 8);
has_update(telegram, wwSelTemp_, 9);
has_update(telegram, wwRedTemp_, 10);
has_update(telegram, wwDailyTemp_, 6);
has_update(telegram, wwDisinfectionTemp_, 12);
// (daily heating time thermostat 2F5, offset 9, offset 8 on/off)
}
// SM100wwCirc - 0x07A5
// Solar Module(0x2A) -> (0x00), (0x7A5), data:
void Water::process_SM100wwCirc(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwCirc_, 0);
has_update(telegram, wwCircMode_, 3);
}
// SM100wwKeepWarm - 0x7AE, keepWarm
// Thermostat(0x10) -> Solar(0x2A), ?(0x7AE), data: FF
void Water::process_SM100wwKeepWarm(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwKeepWarm_, 0);
}
/*
// SM100ww? - 0x7E0, some kind of status
// data: 00 00 46 00 00 01 06 0E 06 0E 00 00 00 00 00 03 03 03 03
// publishes single values offset 1/2(16bit), offset 5, offset 6, offset 7, offset 8, offset 9,
// status2 = 03:"no heat", 06:"heat request", 08:"disinfecting", 09:"hold"
*/
void Water::process_SM100wwStatus2(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwFlow_, 7);
has_update(telegram, wwStatus2_, 8);
has_update(telegram, wwPumpMod_, 9);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
// SM100wwCommand - 0x07AB
// Thermostat(0x10) -> Solar Module(0x2A), (0x7AB), data: 01 00 01
void Water::process_SM100wwCommand(std::shared_ptr<const Telegram> telegram) {
// not implemented yet
}
#pragma GCC diagnostic pop
/*
* MM100 messages
*/
// Mixer warm water loading/DHW - 0x0331, 0x0332
// e.g. A9 00 FF 00 02 32 02 6C 00 3C 00 3C 3C 46 02 03 03 00 3C // on 0x28
// A8 00 FF 00 02 31 02 35 00 3C 00 3C 3C 46 02 03 03 00 3C // in 0x29
void Water::process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwFlowTemp_, 0); // is * 10
has_bitupdate(telegram, wwPump_, 2, 0);
has_update(telegram, wwStatus_, 11); // temp status
}
// Config message 0x313, has to be fetched
void Water::process_MMPLUSConfigMessage_WWC(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwRequiredTemp_, 4);
has_update(telegram, wwRedTemp_, 5);
has_update(telegram, wwDiffTemp_, 7);
has_update(telegram, wwDisinfectionTemp_, 9);
has_update(telegram, wwMaxTemp_, 10);
}
// unknown, 2 examples from older threads
// Thermostat(0x10) -> Mixer(0x28), ?(0x33B), data: 01 01 00
// Thermostat -> Mixing Module, type 0x023B, telegram: 90 28 FF 00 02 3B 00 02 00 (CRC=68)
void Water::process_MMPLUSSetMessage_WWC(std::shared_ptr<const Telegram> telegram) {
}
// MMPLUS telegram 0x345 unknown
// Solar Module -> Mixing Module, type 0x0245, telegram: B0 28 FF 00 02 45 64 01 01 (CRC=36)
// ?
/*
* IPM messages
*/
// 0x34 only 8 bytes long
// Mixer(0x41) -> All(0x00), UBAMonitorWW(0x34), data: 37 02 1E 02 1E 00 00 00 00
void Water::process_IPMMonitorWW(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, wwSelTemp_, 0);
has_update(telegram, wwTemp_1_, 1);
has_update(telegram, wwTemp_2_, 3);
has_bitupdate(telegram, wwPump_, 5, 3);
}
// Mixer(0x41) -> Me(0x0B), UBAParameterWW(0x33), data: 08 FF 46 FB FF 28 FF 07 46 00 FF 00
void Water::process_IPMParameterWW(std::shared_ptr<const Telegram> telegram) {
// has_update(telegram, wwActivated_, 1); // 0xFF means on
// has_update(telegram, wwSelTemp_, 2);
has_update(telegram, wwHystOn_, 3); // Hyst on (default -5)
has_update(telegram, wwHystOff_, 4); // Hyst off (default -1)
has_update(telegram, wwFlowTempOffset_, 5); // default 40
has_update(telegram, wwCirc_, 6); // 0xFF means on
has_update(telegram, wwCircMode_, 7); // 1=1x3min 6=6x3min 7=continuous
has_update(telegram, wwDisinfectionTemp_, 8);
// has_bitupdate(telegram, wwChargeType_, 10, 0); // 0 = charge pump, 0xff = 3-way valve
}
// 0x1E, only16 bit temperature
// Mixer(0x41) -> Boiler(0x08), HydrTemp(0x1E), data: 01 D8
void Water::process_IPMHydrTemp(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, HydrTemp_, 0);
}
/*
* Settings
*/
bool Water::set_wwSelTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
write_command(0x35, 3, (uint8_t)temperature, 0x34);
} else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
return false;
} else { // SM100
write_command(0x7A6, 9, (uint8_t)temperature, 0x7A6);
}
return true;
}
bool Water::set_wwMaxTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
return false;
} else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
write_command(0x313 + wwc_, 10, (uint8_t)temperature, 0x313 + wwc_);
} else { // SM100
write_command(0x7A6, 8, (uint8_t)temperature, 0x7A6);
}
return true;
}
bool Water::set_wwRedTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
return false;
} else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
write_command(0x313 + wwc_, 5, (uint8_t)temperature, 0x313 + wwc_);
} else { // SM100
write_command(0x7A6, 10, (uint8_t)temperature, 0x7A6);
}
return true;
}
bool Water::set_wwDailyTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
write_command(0x7A6, 6, (uint8_t)temperature, 0x7A6);
return true;
}
bool Water::set_wwDisinfectionTemp(const char * value, const int8_t id) {
int temperature;
if (!Helpers::value2temperature(value, temperature)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
write_command(0x33, 8, (uint8_t)temperature, 0x33);
} else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
write_command(0x313 + wwc_, 9, (uint8_t)temperature, 0x313 + wwc_);
} else { // SM100
write_command(0x7A6, 12, (uint8_t)temperature, 0x7A6);
}
return true;
}
bool Water::set_wwCirc(const char * value, const int8_t id) {
bool b;
if (!Helpers::value2bool(value, b)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
write_command(0x33, 6, b ? 0xFF : 0x00, 0x33);
} else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
write_command(0x33B + wwc_, 0, b ? 0x01 : 0x00, 0x33B + wwc_);
} else { // SM100
write_command(0x7A5, 0, b ? 0xFF : 0x00, 0x7A5);
}
return true;
}
bool Water::set_wwCircMode(const char * value, const int8_t id) {
uint8_t num;
if (!Helpers::value2enum(value, num, FL_(enum_wwCircMode))) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_IPM) {
write_command(0x33, 7, num, 0x33);
} else if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
write_command(0x313 + wwc_, 0, num, 0x313 + wwc_);
} else { // SM100
write_command(0x7A5, 3, num, 0x7A5);
}
return true;
}
bool Water::set_wwKeepWarm(const char * value, const int8_t id) {
bool b;
if (!Helpers::value2bool(value, b)) {
return false;
}
write_command(0x7AE, 0, b ? 0xFF : 0x00, 0x7AE);
return true;
}
bool Water::set_wwDiffTemp(const char * value, const int8_t id) {
uint8_t wwc = device_id() - 0x28;
float v;
if (!Helpers::value2temperature(value, v)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
write_command(0x313 + wwc, 7, (int8_t)(v * 10), 0x313 + wwc);
return true;
}
return false;
}
bool Water::set_wwRequiredTemp(const char * value, const int8_t id) {
uint8_t wwc = device_id() - 0x28;
float v;
if (!Helpers::value2temperature(value, v)) {
return false;
}
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
write_command(0x313 + wwc, 4, (uint8_t)v, 0x313 + wwc);
return true;
}
return false;
}
bool Water::set_wwFlowTempOffset(const char * value, const int8_t id) {
int n;
if (!Helpers::value2number(value, n)) {
return false;
}
write_command(0x33, 5, n, 0x33);
return true;
}
bool Water::set_wwHystOn(const char * value, const int8_t id) {
int n;
if (!Helpers::value2number(value, n)) {
return false;
}
write_command(0x33, 3, n, 0x33);
return true;
}
bool Water::set_wwHystOff(const char * value, const int8_t id) {
int n;
if (!Helpers::value2number(value, n)) {
return false;
}
write_command(0x33, 4, n, 0x33);
return true;
}
} // namespace emsesp

115
src/devices/water.h Normal file
View File

@@ -0,0 +1,115 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020-2023 Paul Derbyshire
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EMSESP_WATER_H
#define EMSESP_WATER_H
#include "emsesp.h"
namespace emsesp {
class Water : public EMSdevice {
public:
Water(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand);
private:
static uuid::log::Logger logger_;
uint8_t wwc_;
// SM100wwTemperature - 0x07D6
uint16_t wwTemp_1_;
uint16_t wwTemp_2_;
uint16_t wwTemp_3_;
uint16_t wwTemp_4_;
uint16_t wwTemp_5_;
uint16_t wwTemp_6_;
uint16_t wwTemp_7_;
// SM100wwStatus - 0x07AA
uint8_t wwPump_;
// SM100wwParam - 0x07A6
uint8_t wwMaxTemp_;
uint8_t wwSelTemp_;
uint8_t wwRedTemp_;
uint8_t wwDailyTemp_;
uint8_t wwDisinfectionTemp_;
// SM100wwKeepWarm - 0x07AE
uint8_t wwKeepWarm_;
// SM100wwCirc - 0x07A5
uint8_t wwCirc_;
uint8_t wwCircMode_;
// SM100wwStatus2 - 0x07E0
uint8_t wwFlow_;
uint8_t wwPumpMod_;
uint8_t wwStatus2_;
// mixer
uint8_t wwStatus_;
uint16_t wwFlowTemp_;
int8_t wwDiffTemp_;
uint8_t wwRequiredTemp_;
// IPM
uint16_t HydrTemp_;
int8_t wwHystOn_; // Hyst on (default -5)
int8_t wwHystOff_; // Hyst off (default -1)
uint8_t wwFlowTempOffset_; // default 40
void process_SM100wwTemperature(std::shared_ptr<const Telegram> telegram);
void process_SM100wwStatus(std::shared_ptr<const Telegram> telegram);
void process_SM100wwStatus2(std::shared_ptr<const Telegram> telegram);
void process_SM100wwCommand(std::shared_ptr<const Telegram> telegram);
void process_SM100wwCirc(std::shared_ptr<const Telegram> telegram);
void process_SM100wwParam(std::shared_ptr<const Telegram> telegram);
void process_SM100wwKeepWarm(std::shared_ptr<const Telegram> telegram);
void process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram);
void process_MMPLUSSetMessage_WWC(std::shared_ptr<const Telegram> telegram);
void process_MMPLUSConfigMessage_WWC(std::shared_ptr<const Telegram> telegram);
void process_IPMMonitorWW(std::shared_ptr<const Telegram> telegram);
void process_IPMHydrTemp(std::shared_ptr<const Telegram> telegram);
void process_IPMParameterWW(std::shared_ptr<const Telegram> telegram);
bool set_wwSelTemp(const char * value, const int8_t id);
bool set_wwMaxTemp(const char * value, const int8_t id);
bool set_wwRedTemp(const char * value, const int8_t id);
bool set_wwCirc(const char * value, const int8_t id);
bool set_wwCircMode(const char * value, const int8_t id);
bool set_wwKeepWarm(const char * value, const int8_t id);
bool set_wwDisinfectionTemp(const char * value, const int8_t id);
bool set_wwDailyTemp(const char * value, const int8_t id);
bool set_wwDiffTemp(const char * value, const int8_t id);
bool set_wwRequiredTemp(const char * value, const int8_t id);
bool set_wwFlowTempOffset(const char * value, const int8_t id);
bool set_wwHystOn(const char * value, const int8_t id);
bool set_wwHystOff(const char * value, const int8_t id);
};
} // namespace emsesp
#endif

View File

@@ -107,6 +107,8 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) {
return F_(system);
case DeviceType::SCHEDULER:
return F_(scheduler);
case DeviceType::CUSTOM:
return F_(custom);
case DeviceType::BOILER:
return F_(boiler);
case DeviceType::THERMOSTAT:
@@ -135,10 +137,12 @@ const char * EMSdevice::device_type_2_device_name(const uint8_t device_type) {
return F_(extension);
case DeviceType::HEATSOURCE:
return F_(heatsource);
case DeviceType::CUSTOM:
return F_(custom);
case DeviceType::VENTILATION:
return F_(ventilation);
case DeviceType::WATER:
return F_(water);
case DeviceType::POOL:
return F_(pool);
default:
return Helpers::translated_word(FL_(unknown), true);
}
@@ -174,6 +178,10 @@ const char * EMSdevice::device_type_2_device_name_translated() {
return Helpers::translated_word(FL_(heatsource_device));
case DeviceType::VENTILATION:
return Helpers::translated_word(FL_(ventilation_device));
case DeviceType::WATER:
return Helpers::translated_word(FL_(water_device));
case DeviceType::POOL:
return Helpers::translated_word(FL_(pool_device));
default:
break;
}
@@ -241,6 +249,12 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) {
if (!strcmp(lowtopic, F_(ventilation))) {
return DeviceType::VENTILATION;
}
if (!strcmp(lowtopic, F_(water))) {
return DeviceType::WATER;
}
if (!strcmp(lowtopic, F_(pool))) {
return DeviceType::POOL;
}
return DeviceType::UNKNOWN;
}

View File

@@ -339,7 +339,9 @@ class EMSdevice {
SYSTEM = 0, // this is us (EMS-ESP)
TEMPERATURESENSOR, // for internal temperature sensors
ANALOGSENSOR, // for internal analog sensors
SCHEDULER,
SCHEDULER, // for internal schedule
CUSTOM, // for user defined entities
BOILER,
THERMOSTAT,
MIXER,
@@ -353,8 +355,9 @@ class EMSdevice {
EXTENSION,
GENERIC,
HEATSOURCE,
CUSTOM,
VENTILATION,
WATER,
POOL,
UNKNOWN
};
@@ -379,8 +382,11 @@ class EMSdevice {
static constexpr uint8_t EMS_DEVICE_ID_MODEM = 0x48;
static constexpr uint8_t EMS_DEVICE_ID_RFSENSOR = 0x40; // RF sensor only sending, no reply
static constexpr uint8_t EMS_DEVICE_ID_RFBASE = 0x50;
static constexpr uint8_t EMS_DEVICE_ID_ROOMTHERMOSTAT = 0x17; // TADO using this with no version reply
static constexpr uint8_t EMS_DEVICE_ID_TADO_OLD = 0x19; // TADO using this with no broadcast and version
static constexpr uint8_t EMS_DEVICE_ID_ROOMTHERMOSTAT = 0x17; // TADO using this with no version reply #174
static constexpr uint8_t EMS_DEVICE_ID_TADO_OLD = 0x19; // older TADO using this with no version reply, #1031
static constexpr uint8_t EMS_DEVICE_ID_DHW1 = 0x28; // 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?
// generic type IDs
static constexpr uint16_t EMS_TYPE_VERSION = 0x02; // type ID for Version information. Generic across all EMS devices.

View File

@@ -480,6 +480,7 @@ void EMSESP::publish_all(bool force) {
publish_device_values(EMSdevice::DeviceType::THERMOSTAT);
publish_device_values(EMSdevice::DeviceType::SOLAR);
publish_device_values(EMSdevice::DeviceType::MIXER);
publish_device_values(EMSdevice::DeviceType::WATER);
publish_other_values(); // switch and heat pump, ...
webSchedulerService.publish();
webCustomEntityService.publish();
@@ -513,14 +514,17 @@ void EMSESP::publish_all_loop() {
publish_device_values(EMSdevice::DeviceType::MIXER);
break;
case 5:
publish_device_values(EMSdevice::DeviceType::WATER);
break;
case 6:
publish_other_values(); // switch and heat pump
webSchedulerService.publish(true);
webCustomEntityService.publish(true);
break;
case 6:
case 7:
publish_sensor_values(true, true);
break;
case 7:
case 8:
if (Mqtt::ha_enabled()) {
Mqtt::ha_status();
}
@@ -602,6 +606,7 @@ void EMSESP::publish_other_values() {
publish_device_values(EMSdevice::DeviceType::VENTILATION);
publish_device_values(EMSdevice::DeviceType::EXTENSION);
publish_device_values(EMSdevice::DeviceType::ALERT);
publish_device_values(EMSdevice::DeviceType::POOL);
// other devices without values yet
// publish_device_values(EMSdevice::DeviceType::GATEWAY);
// publish_device_values(EMSdevice::DeviceType::CONNECT);
@@ -1080,7 +1085,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
auto device_type = device_p->device_type;
auto flags = device_p->flags;
// check for integrated modules with same product id
// check for integrated modules with same product id, but different function (device_id)
if (device_type == DeviceType::HEATPUMP) {
if (device_id == EMSdevice::EMS_DEVICE_ID_MODEM) {
device_type = DeviceType::GATEWAY;
@@ -1090,6 +1095,9 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
name = "Wireless sensor base";
}
}
if (device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW8) {
device_type = DeviceType::WATER;
}
// empty reply to version, read a generic device from database
if (product_id == 0) {

View File

@@ -102,6 +102,8 @@ MAKE_WORD(heatsource)
MAKE_WORD(scheduler)
MAKE_WORD(custom)
MAKE_WORD(ventilation)
MAKE_WORD(water)
MAKE_WORD(pool)
// brands
MAKE_WORD_CUSTOM(bosch, "Bosch")

View File

@@ -54,6 +54,8 @@ MAKE_WORD_TRANSLATION(unknown_device, "Unknown", "Unbekannt", "Onbekend", "Okän
MAKE_WORD_TRANSLATION(custom_device, "Custom", "Nutzerdefiniert", "Aangepast", "", "Niestandardowe", "", "", "Özel", "Personalizzato") // TODO translate
MAKE_WORD_TRANSLATION(custom_device_name, "User defined entities", "Nutzer deklarierte Entitäten", "Gebruiker gedefineerd", "", "Encje zdefiniowane przez użytkownika", "", "", "Kullanıcı tarafından tanımlanmış varlıklar", "Entità definita da utente") // TODO translate
MAKE_WORD_TRANSLATION(ventilation_device, "Ventilation", "Lüftung", "Ventilatie", "", "", "", "", "Havalandırma", "Ventilazione") // TODO translate
MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "", "", "", "", "") // TODO translate
MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "", "", "", "", "") // TODO translate
// commands
// TODO translate
@@ -687,10 +689,6 @@ MAKE_TRANSLATION(pumpStatus, "pumpstatus", "pump status (PC1)", "Pumpenstatus HK
MAKE_TRANSLATION(mixerStatus, "valvestatus", "mixing valve actuator (VC1)", "Mischerventil Position (VC1)", "positie mixerklep (VC1)", "Shuntventil Status (VC1)", "siłownik zaworu mieszającego (VC1)", "shuntventil status (VC1)", "actionnement vanne mélangeur (VC1)", "karışım vanası aktüatörü (VC1)", "posizione valvola miscela (VC1)")
MAKE_TRANSLATION(flowTempVf, "flowtempvf", "flow temperature in header (T0/Vf)", "Vorlauftemperatur am Verteiler (T0/Vf)", "aanvoertemperatuur verdeler (T0/Vf)", "Flödestemperatur Fördelare (T0/Vf)", "temperatura zasilania na rozdzielaczu (T0/Vf)", "turtemperatur ved fordeleren (T0/Vf)", "température départ collecteur (T0/Vf)", "başlıkta akış sıcaklığı", "Temperatura di mandata al distributore (T0/Vf)")
MAKE_TRANSLATION(mixerSetTime, "valvesettime", "time to set valve", "Zeit zum Einstellen des Ventils", "Inschakeltijd mengklep", "Inställningstid Ventil", "czas na ustawienie zaworu", "instillningstid ventil", "délai activation vanne", "vana ayar zamanı", "ritardo attivazione valvola")
// mixer prefixed with wwc
MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned wwc (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe wwc (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)")
MAKE_TRANSLATION(wwTempStatus, "wwtempstatus", "temperature switch in assigned wwc (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule wwc (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)")
MAKE_TRANSLATION(wwTemp, "wwtemp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale")
// mixer pool
MAKE_TRANSLATION(poolSetTemp, "poolsettemp", "pool set temperature", "Pool Solltemperatur", "Streeftemperatuur zwembad", "Pool Temperatur Börvärde", "zadana temperatura basenu", "valgt temp basseng", "température consigne piscine", "hedef havuz sıcaklığı", "temperatura nominale piscina")
MAKE_TRANSLATION(poolTemp, "pooltemp", "pool temperature", "Pool Temperatur", "Zwembadtemperatuur", "Pooltemperatur", "temperatura basenu", "bassengtemperatur", "température piscine", "havuz sıcaklığı", "temperatura piscina")
@@ -737,10 +735,12 @@ MAKE_TRANSLATION(energyToday, "energytoday", "total energy today", "Energie heut
// solar ww
MAKE_TRANSLATION(wwTemp1, "wwtemp1", "temperature 1", "Temperatur 1", "Temperatuur 1", "Temperatur 1", "temperatura 1", "temperatur 1", "température 1", "sıcaklık 1", "Temperatura 1")
MAKE_TRANSLATION(wwTemp3, "wwtemp3", "temperature 3", "Temperatur 3", "Temperatuur 2", "Temperatur 2", "temperatura 2", "Temperatur 3", "température 3", "sıcaklık 3", "Temperatura 3")
MAKE_TRANSLATION(wwTemp4, "wwtemp4", "temperature 4", "Temperatur 4", "Temperatuur 3", "Temperatur 3", "temperatura 3", "Temperatur 4", "température 4", "sıcaklık 4", "Temperatura 4")
MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 4", "temperatura 4", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5")
MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 5", "temperatura 5", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7")
MAKE_TRANSLATION(wwTemp2, "wwtemp2", "temperature 2", "Temperatur 2", "Temperatuur 2", "Temperatur 2", "temperatura 2", "temperatur 2", "température 2", "sıcaklık 2", "Temperatura 2")
MAKE_TRANSLATION(wwTemp3, "wwtemp3", "temperature 3", "Temperatur 3", "Temperatuur 3", "Temperatur 3", "temperatura 3", "Temperatur 3", "température 3", "sıcaklık 3", "Temperatura 3")
MAKE_TRANSLATION(wwTemp4, "wwtemp4", "temperature 4", "Temperatur 4", "Temperatuur 4", "Temperatur 4", "temperatura 4", "Temperatur 4", "température 4", "sıcaklık 4", "Temperatura 4")
MAKE_TRANSLATION(wwTemp5, "wwtemp5", "temperature 5", "Temperatur 5", "Temperatuur 5", "Temperatur 5", "temperatura 5", "Temperatur 5", "température 5", "sıcaklık 5", "Temperatura 5")
MAKE_TRANSLATION(wwTemp6, "wwtemp6", "temperature 1", "Temperatur 6", "Temperatuur 6", "Temperatur 6", "temperatura 6", "temperatur 6", "température 6", "sıcaklık 6", "Temperatura 6")
MAKE_TRANSLATION(wwTemp7, "wwtemp7", "temperature 7", "Temperatur 7", "Temperatuur 7", "Temperatur 7", "temperatura 7", "Temperatur 7", "température 7", "sıcaklık 7", "Temperatura 7")
MAKE_TRANSLATION(wwPump, "wwpump", "pump", "Pumpe", "Pomp", "Pump", "pompa", "pumpe", "pompe", "pompa", "Pompa")
// solar ww and mixer wwc
MAKE_TRANSLATION(wwMinTemp, "wwmintemp", "minimum temperature", "minimale Temperatur", "Minimale temperatuur", "Min Temperatur", "temperatura minimalna", "min temperatur", "température min", "minimum sıcaklık", "temperatura minima")
@@ -753,6 +753,9 @@ MAKE_TRANSLATION(wwFlow, "wwflow", "flow rate", "Volumenstrom", "Doorstroomsnelh
// extra mixer ww
MAKE_TRANSLATION(wwRequiredTemp, "wwrequiredtemp", "required temperature", "benötigte Temperatur", "Benodigde temperatuur", "Nödvändig Temperatur", "temperatura wymagana", "nødvendig temperatur", "température requise", "gerekli sıcaklık", "temperatura richiesta")
MAKE_TRANSLATION(wwDiffTemp, "wwdifftemp", "start differential temperature", "Start Differential Temperatur", "Start differentiele temperatuur", "Start Differentialtemperatur", "start temperatury różnicowej", "start differensialtemperatur", "température différentielle de départ", "diferansiyel sıcaklık", "avvia temperatura differenziale")
MAKE_TRANSLATION(wwPumpStatus, "pumpstatus", "pump status in assigned wwc (PC1)", "Pumpenstatus des wwk (PC1)", "Pompstatus in WW circuit (PC1)", "Pumpstatus i VV-krets (PC1)", "stan pompy w obwodzie c.w.u. (PC1)", "Pumpestatus i VV-krets (PC1)", "état pompe wwc (PC1)", "Kullanım suyu devresindeki(PC1) pompa durumu", "stato pompa assegnato nel ciruito WW (PC1)")
MAKE_TRANSLATION(wwTempStatus, "wwtempstatus", "temperature switch in assigned wwc (MC1)", "Temperaturschalter des wwk (MC1)", "Temperatuurschakeling in WW circuit (MC1)", "Temperaturventil i VV-krets (MC1)", "temperatura w obwodzie c.w.u. (MC1)", "temperaturventil i VV-krets (MC1)", "température bascule wwc (MC1).", "atanmış sıcak su devresinde sıcaklık", "interruttore di temperatura del wwk (MC1)")
MAKE_TRANSLATION(wwTemp, "wwtemp", "current temperature", "aktuelle Temperatur", "huidige temperatuur", "Aktuell Temperatur", "temperatura c.w.u.", "aktuell temperatur", "température actuelle", "güncel sıcaklık", "temperatura attuale")
// SM100
MAKE_TRANSLATION(heatTransferSystem, "heattransfersystem", "heattransfer system", "Wärmeübertragungs-System", "Warmteoverdrachtssysteem", "Värmeöverföringssystem", "system wymiany ciepła", "varmeoverføringssystem", "système de transfert de chaleur", "ıs transfer sistemi", "sistema di trasferimento del calore")

View File

@@ -34,6 +34,7 @@ uint32_t Mqtt::publish_time_boiler_;
uint32_t Mqtt::publish_time_thermostat_;
uint32_t Mqtt::publish_time_solar_;
uint32_t Mqtt::publish_time_mixer_;
uint32_t Mqtt::publish_time_water_;
uint32_t Mqtt::publish_time_sensor_;
uint32_t Mqtt::publish_time_other_;
uint32_t Mqtt::publish_time_heartbeat_;
@@ -170,6 +171,11 @@ void Mqtt::loop() {
EMSESP::publish_device_values(EMSdevice::DeviceType::MIXER);
} else
if (publish_time_water_ && (currentMillis - last_publish_mixer_ > publish_time_water_)) {
last_publish_water_ = (currentMillis / publish_time_water_) * publish_time_water_;
EMSESP::publish_device_values(EMSdevice::DeviceType::WATER);
} else
if (publish_time_other_ && (currentMillis - last_publish_other_ > publish_time_other_)) {
last_publish_other_ = (currentMillis / publish_time_other_) * publish_time_other_;
EMSESP::publish_other_values(); // switch and heatpump
@@ -330,6 +336,7 @@ void Mqtt::reset_mqtt() {
}
}
// load the settings from service
void Mqtt::load_settings() {
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & mqttSettings) {
mqtt_base_ = mqttSettings.base.c_str(); // Convert String to std::string
@@ -350,6 +357,7 @@ void Mqtt::load_settings() {
publish_time_thermostat_ = mqttSettings.publish_time_thermostat * 1000;
publish_time_solar_ = mqttSettings.publish_time_solar * 1000;
publish_time_mixer_ = mqttSettings.publish_time_mixer * 1000;
publish_time_water_ = mqttSettings.publish_time_water * 1000;
publish_time_other_ = mqttSettings.publish_time_other * 1000;
publish_time_sensor_ = mqttSettings.publish_time_sensor * 1000;
publish_time_heartbeat_ = mqttSettings.publish_time_heartbeat * 1000;
@@ -361,6 +369,7 @@ void Mqtt::load_settings() {
std::replace(mqtt_basename_.begin(), mqtt_basename_.end(), '/', '_');
}
// start mqtt
void Mqtt::start() {
mqttClient_ = EMSESP::esp8266React.getMqttClient();
@@ -412,6 +421,10 @@ void Mqtt::set_publish_time_mixer(uint16_t publish_time) {
publish_time_mixer_ = publish_time * 1000; // convert to milliseconds
}
void Mqtt::set_publish_time_water(uint16_t publish_time) {
publish_time_water_ = publish_time * 1000; // convert to milliseconds
}
void Mqtt::set_publish_time_other(uint16_t publish_time) {
publish_time_other_ = publish_time * 1000; // convert to milliseconds
}
@@ -444,6 +457,10 @@ bool Mqtt::get_publish_onchange(uint8_t device_type) {
if (!publish_time_mixer_) {
return true;
}
} else if (device_type == EMSdevice::DeviceType::WATER) {
if (!publish_time_water_) {
return true;
}
} else if (!publish_time_other_) {
return true;
}

View File

@@ -47,6 +47,7 @@ class Mqtt {
void set_publish_time_thermostat(uint16_t publish_time);
void set_publish_time_solar(uint16_t publish_time);
void set_publish_time_mixer(uint16_t publish_time);
void set_publish_time_water(uint16_t publish_time);
void set_publish_time_other(uint16_t publish_time);
void set_publish_time_sensor(uint16_t publish_time);
void set_publish_time_heartbeat(uint16_t publish_time);
@@ -253,6 +254,7 @@ class Mqtt {
uint32_t last_publish_thermostat_ = 0;
uint32_t last_publish_solar_ = 0;
uint32_t last_publish_mixer_ = 0;
uint32_t last_publish_water_ = 0;
uint32_t last_publish_other_ = 0;
uint32_t last_publish_sensor_ = 0;
uint32_t last_publish_heartbeat_ = 0;
@@ -279,6 +281,7 @@ class Mqtt {
static uint32_t publish_time_thermostat_;
static uint32_t publish_time_solar_;
static uint32_t publish_time_mixer_;
static uint32_t publish_time_water_;
static uint32_t publish_time_other_;
static uint32_t publish_time_sensor_;
static uint32_t publish_time_heartbeat_;

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.6.3-dev.5b"
#define EMSESP_APP_VERSION "3.6.3-dev.6a"