Merge branch 'idf4' into idf4_no_master

This commit is contained in:
MichaelDvP
2022-05-29 19:12:58 +02:00
26 changed files with 1004 additions and 773 deletions

View File

@@ -9,9 +9,10 @@ jobs:
build:
name: Build
runs-on: ubuntu-latest
if: github.repository_owner == 'emsesp'
# if: github.repository == 'emsesp/EMS-ESP32'
env:
# https://binaries.sonarsource.com/?prefix=Distribution/sonar-scanner-cli/
# SONAR_SCANNER_VERSION: 4.6.1.2450
SONAR_SCANNER_VERSION: 4.7.0.2747
SONAR_SERVER_URL: "https://sonarcloud.io"
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory

View File

@@ -5,6 +5,108 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
# [3.4.1] May 29 2022
## Fixed
- Fix memory leak in api [#524](https://github.com/emsesp/EMS-ESP32/issues/524)
## Changed
- Controller data in web-ui only for IVT [#522](https://github.com/emsesp/EMS-ESP32/issues/522)
- Rename hidden `climate` to a more explaining name [#523](https://github.com/emsesp/EMS-ESP32/issues/523)
- Minor changes to the Customizations web page [#527](https://github.com/emsesp/EMS-ESP32/pull/527)
# [3.4.0] May 23 2022
## Added
- WebUI optimizations, updated look&feel and better performance [#124](https://github.com/emsesp/EMS-ESP32/issues/124)
- Auto refresh of WebUI after successful firmware upload [#178](https://github.com/emsesp/EMS-ESP32/issues/178)
- New Customization Service in WebUI. First feature is the ability to enable/disabled Enitites (device values) from EMS devices [#206](https://github.com/emsesp/EMS-ESP32/issues/206)
- Option to disable Telnet Console [#209](https://github.com/emsesp/EMS-ESP32/issues/209)
- Added Hide SSID, Max Clients and Preferred Channel to Access Point
- Merged in MichaelDvP's changes like Fahrenheit conversion, publish single (for IOBroker) and a few other critical optimizations
- Enabled bi-directional read/write with Home Assistant, so values can be changed automatically from the UI without scripting [#265](https://github.com/emsesp/EMS-ESP32/issues/265)
- Added GC7000F Boiler [#270](https://github.com/emsesp/EMS-ESP32/issues/270)
- Revised LED flash sequence on boot up to show system health (1 flash=no ems, 2 flashes=no wifi) [#224](https://github.com/emsesp/EMS-ESP32/issues/224)
- Analog Sensor support [#271](https://github.com/emsesp/EMS-ESP32/issues/271)
- Solar cylinder priority [#247](https://github.com/emsesp/EMS-ESP32/issues/247)
- Read only mode in Settings, where EMS Tx/Write commands are blocked [#286](https://github.com/emsesp/EMS-ESP32/issues/286)
- Added 8700i Boiler device
- Added Cascade CM10 Controller device
- Add Olimex ESP32-POE-ISO to board profiles plus settings to customize Ethernet modules [#301](https://github.com/emsesp/EMS-ESP32/issues/301)
- Help text for string commands in WebUI [#320](https://github.com/emsesp/EMS-ESP32/issues/320)
- Germany translations (at compile time)
- #entities added to system/info` endpoint [#322](https://github.com/emsesp/EMS-ESP32/issues/322)
- analog outputs digital/pwm/dac
- remove MQTT retained configs if discovery is disabled
- timeout 10 min for MQTT-QoS wait
- Moduline 300 auto-temperatures T1-T4, RC300 romminfluencefactor
- RC35 parameters [#392](https://github.com/emsesp/EMS-ESP32/issues/392), [#398](https://github.com/emsesp/EMS-ESP32/issues/398)
- sync time with thermostat [#386](https://github.com/emsesp/EMS-ESP32/issues/386), [#408](https://github.com/emsesp/EMS-ESP32/issues/408)
- set mode has immediate effect [#395](https://github.com/emsesp/EMS-ESP32/issues/395)
- min/max in web value setting
- Extend customization to select if an entity is to be shown in the WebUI or forced as read-only [#317](https://github.com/emsesp/EMS-ESP32/issues/317)
- Added Moduline 400 installation parameters [PR #449 by @kwertie01](https://github.com/emsesp/EMS-ESP32/pull/449)
- Read time from IVT-controller [#439](https://github.com/emsesp/EMS-ESP32/issues/439)
- Hybrid Heatpump product-id 168 [#459](https://github.com/emsesp/EMS-ESP32/issues/459), thermostat settings
- Junkers ISM2 and IPM in warm water mode [#437](https://github.com/emsesp/EMS-ESP32/issues/437)
- Added Shower Alert trigger time and cold shot time [#436](https://github.com/emsesp/EMS-ESP32/issues/436)
- Improved Table layout in Web UI (searching, filtering, sorting, exporting to CSV)
- API fetch individual attributes from an entity [#462](https://github.com/emsesp/EMS-ESP32/issues/462)
- Option to disable mDNS
- Option for rendering booleans on dashboard [#456](https://github.com/emsesp/EMS-ESP32/issues/456)
- Upload customization settings from a file [#256](https://github.com/emsesp/EMS-ESP32/issues/256)
## Fixed
- lastcode broke MQTT JSON structure [#228](https://github.com/emsesp/EMS-ESP32/issues/228)
- fixed issue with overlapping while reading sequence of EMS1.0 telegrams
- fixed redundant telegram readings (because of offset overflow)
- added missing RC30/Moduline 400 [#243](https://github.com/emsesp/EMS-ESP32/issues/243)
- Correct modes for RC25 [#106](https://github.com/emsesp/EMS-ESP32/issues/106)
- Clean up old HA config's in MQTT before publishing data. This will prevent HA giving the 'dict' warnings [#229](https://github.com/emsesp/EMS-ESP32/issues/229)
- RC25 temperature setting [#272](https://github.com/emsesp/EMS-ESP32/issues/272)
- Buderus RC25 - "hc1 mode type" incorrect value [#273](https://github.com/emsesp/EMS-ESP32/issues/273)
- Increased number of Mixers and Heating Circuits [#294](https://github.com/emsesp/EMS-ESP32/issues/294)
- Check receive status before removing a telegram fetch [#268](https://github.com/emsesp/EMS-ESP32/issues/268), [#282](https://github.com/emsesp/EMS-ESP32/issues/282)
- Fix uploading firmware on OSX [#345](https://github.com/emsesp/EMS-ESP32/issues/345)
- Non-nested MQTT would corrupt the json [#354](https://github.com/emsesp/EMS-ESP32/issues/354)
- Burner selected max power can have a value higher than 100% [#314](https://github.com/emsesp/EMS-ESP32/issues/314)
- some missing fahrenheit calculations
- limited number of exclusions [#339](https://github.com/emsesp/EMS-ESP32/issues/339)
- MQTT sometimes would not reconnect after a WiFi outage
## Changed
- Use flash system to show system health (1 flash=no ems, 2 flashes=no wifi) [#224](https://github.com/emsesp/EMS-ESP32/issues/224)
- Renamed Dallas Sensor to Temperature Sensor in UI
- Dallas Format removed. Use the name to give each sensor an alias
- No longer MQTT subscribes to topic `/thermostat_hc<n>` as it supports a path similar to the API endpoint construct
- Show Sensors quality in WebUI
- Controller not shown in WebUI dashboard
- renamed "Home Assistant Integration" to "MQTT Discovery" in MQTT Settings [#290](https://github.com/emsesp/EMS-ESP32/issues/290)
- Show ems tx reads and writes separately
- Show ems device handlers separated for received, fetched and pending handlers.
- Wired renamed to Ethernet
- removed system/pin command, new commands in analogsensors
- system/info device-info split to name/version/brand
- exclude list uses short-names, possible flags for web/api/mqtt excludes, readonly and favorite (selection not yet implemented)
- thermostat clock formate date-time: dd.mm.yyyy hh:mm
- RC300 summermode as other thermostats `winter/summer` instead of `off/on`
## **BREAKING CHANGES:**
- Settings:
- order of Boolean Format has changed in Application Settings - check your settings
- Dallas Format setting removed. Now customize name of each Dallas sensor via the UI
- MQTT/API
- Boiler `wwheat` renamed to `ww3wayon` [#211](https://github.com/emsesp/EMS-ESP32/issues/211)
- Boiler `ww` tag renamed to `dhw`. Any custom Home Assistant lovelace dashboards will need updating.
- Renamed description of `wwtapactivated` to "turn on/off DHW". Otherwise would have looked like "boiler_dhw_turn_on_off_dhw" in HA.
- `/api/system/info` endpoint has updated keys. Now lowercase, no underscores and not capitalized. Replace "handlers" with "handlers received", "handlers fetched" and "handlers pending".
# [3.3.1] January 20 2022
- lastcode broke MQTT JSON structure [#228](https://github.com/emsesp/EMS-ESP32/issues/228)

View File

@@ -1,92 +1,19 @@
# Changelog
## [3.4.0]
# [3.4.2]
### Added
## Added
- WebUI optimizations, updated look&feel and better performance [#124](https://github.com/emsesp/EMS-ESP32/issues/124)
- Auto refresh of WebUI after successful firmware upload [#178](https://github.com/emsesp/EMS-ESP32/issues/178)
- New Customization Service in WebUI. First feature is the ability to enable/disabled Enitites (device values) from EMS devices [#206](https://github.com/emsesp/EMS-ESP32/issues/206)
- Option to disable Telnet Console [#209](https://github.com/emsesp/EMS-ESP32/issues/209)
- Added Hide SSID, Max Clients and Preferred Channel to Access Point
- Merged in MichaelDvP's changes like Fahrenheit conversion, publish single (for IOBroker) and a few other critical optimizations
- Enabled bi-directional read/write with Home Assistant, so values can be changed automatically from the UI without scripting [#265](https://github.com/emsesp/EMS-ESP32/issues/265)
- Added GC7000F Boiler [#270](https://github.com/emsesp/EMS-ESP32/issues/270)
- Revised LED flash sequence on boot up to show system health (1 flash=no ems, 2 flashes=no wifi) [#224](https://github.com/emsesp/EMS-ESP32/issues/224)
- Analog Sensor support [#271](https://github.com/emsesp/EMS-ESP32/issues/271)
- Solar cylinder priority [#247](https://github.com/emsesp/EMS-ESP32/issues/247)
- Read only mode in Settings, where EMS Tx/Write commands are blocked [#286](https://github.com/emsesp/EMS-ESP32/issues/286)
- Added 8700i Boiler device
- Added Cascade CM10 Controller device
- Add Olimex ESP32-POE-ISO to board profiles plus settings to customize Ethernet modules [#301](https://github.com/emsesp/EMS-ESP32/issues/301)
- Help text for string commands in WebUI [#320](https://github.com/emsesp/EMS-ESP32/issues/320)
- Germany translations (at compile time)
- #entities added to system/info` endpoint [#322](https://github.com/emsesp/EMS-ESP32/issues/322)
- analog outputs digital/pwm/dac
- remove MQTT retained configs if discovery is disabled
- timeout 10 min for MQTT-QoS wait
- Moduline 300 auto-temperatures T1-T4, RC300 romminfluencefactor
- RC35 parameters [#392](https://github.com/emsesp/EMS-ESP32/issues/392), [#398](https://github.com/emsesp/EMS-ESP32/issues/398)
- sync time with thermostat [#386](https://github.com/emsesp/EMS-ESP32/issues/386), [#408](https://github.com/emsesp/EMS-ESP32/issues/408)
- set mode has immediate effect [#395](https://github.com/emsesp/EMS-ESP32/issues/395)
- min/max in web value setting
- Extend customization to select if an entity is to be shown in the WebUI or forced as read-only [#317](https://github.com/emsesp/EMS-ESP32/issues/317)
- Added Moduline 400 installation parameters [PR #449 by @kwertie01](https://github.com/emsesp/EMS-ESP32/pull/449)
- Read time from IVT-controller [#439](https://github.com/emsesp/EMS-ESP32/issues/439)
- Hybrid Heatpump product-id 168 [#459](https://github.com/emsesp/EMS-ESP32/issues/459), thermostat settings
- Junkers ISM2 and IPM in warm water mode [#437](https://github.com/emsesp/EMS-ESP32/issues/437)
- Added Shower Alert trigger time and cold shot time [#436](https://github.com/emsesp/EMS-ESP32/issues/436)
- Improved Table layout in Web UI (searching, filtering, sorting, exporting to CSV)
- API fetch individual attributes from an entity [#462](https://github.com/emsesp/EMS-ESP32/issues/462)
- Option to disable mDNS
- Option for rendering booleans on dashboard [#456](https://github.com/emsesp/EMS-ESP32/issues/456)
- Upload customization settings from a file [#256](https://github.com/emsesp/EMS-ESP32/issues/256)
- RC310 additions [#520](https://github.com/emsesp/EMS-ESP32/pull/520)
- damping
- wwprio for RC310 heating circuits
- switchonoptimization for RC310 heating circuits
- enum_controlmode for RC310 (new enum list)
- nofrostmode, reducemode, reducetemp & noreducetemp for RC310
- emergencyops and emergencytemp, wwmaxtemp, wwflowtempoffset and wwcomfort1 for RC310
### Fixed
## Fixed
- lastcode broke MQTT JSON structure [#228](https://github.com/emsesp/EMS-ESP32/issues/228)
- fixed issue with overlapping while reading sequence of EMS1.0 telegrams
- fixed redundant telegram readings (because of offset overflow)
- added missing RC30/Moduline 400 [#243](https://github.com/emsesp/EMS-ESP32/issues/243)
- Correct modes for RC25 [#106](https://github.com/emsesp/EMS-ESP32/issues/106)
- Clean up old HA config's in MQTT before publishing data. This will prevent HA giving the 'dict' warnings [#229](https://github.com/emsesp/EMS-ESP32/issues/229)
- RC25 temperature setting [#272](https://github.com/emsesp/EMS-ESP32/issues/272)
- Buderus RC25 - "hc1 mode type" incorrect value [#273](https://github.com/emsesp/EMS-ESP32/issues/273)
- Increased number of Mixers and Heating Circuits [#294](https://github.com/emsesp/EMS-ESP32/issues/294)
- Check receive status before removing a telegram fetch [#268](https://github.com/emsesp/EMS-ESP32/issues/268), [#282](https://github.com/emsesp/EMS-ESP32/issues/282)
- Fix uploading firmware on OSX [#345](https://github.com/emsesp/EMS-ESP32/issues/345)
- Non-nested MQTT would corrupt the json [#354](https://github.com/emsesp/EMS-ESP32/issues/354)
- Burner selected max power can have a value higher than 100% [#314](https://github.com/emsesp/EMS-ESP32/issues/314)
- some missing fahrenheit calculations
- limited number of exclusions [#339](https://github.com/emsesp/EMS-ESP32/issues/339)
- MQTT sometimes would not reconnect after a WiFi outage
### Changed
- Use flash system to show system health (1 flash=no ems, 2 flashes=no wifi) [#224](https://github.com/emsesp/EMS-ESP32/issues/224)
- Renamed Dallas Sensor to Temperature Sensor in UI
- Dallas Format removed. Use the name to give each sensor an alias
- No longer MQTT subscribes to topic `/thermostat_hc<n>` as it supports a path similar to the API endpoint construct
- Show Sensors quality in WebUI
- Controller not shown in WebUI dashboard
- renamed "Home Assistant Integration" to "MQTT Discovery" in MQTT Settings [#290](https://github.com/emsesp/EMS-ESP32/issues/290)
- Show ems tx reads and writes separately
- Show ems device handlers separated for received, fetched and pending handlers.
- Wired renamed to Ethernet
- removed system/pin command, new commands in analogsensors
- system/info device-info split to name/version/brand
- remove master-thermostat
- exclude list uses short-names, possible flags for web/api/mqtt excludes, readonly and favorite (selection not yet implemented)
- thermostat clock formate date-time: dd.mm.yyyy hh:mm
- RC300 summermode as other thermostats `winter/summer` instead of `off/on`
## Changed
## **BREAKING CHANGES:**
- Settings:
- order of Boolean Format has changed in Application Settings - check your settings
- Dallas Format setting removed. Now customize name of each Dallas sensor via the UI
- MQTT/API
- Boiler `wwheat` renamed to `ww3wayon` [#211](https://github.com/emsesp/EMS-ESP32/issues/211)
- Boiler `ww` tag renamed to `dhw`. Any custom Home Assistant lovelace dashboards will need updating.
- Renamed description of `wwtapactivated` to "turn on/off DHW". Otherwise would have looked like "boiler_dhw_turn_on_off_dhw" in HA.
- `/api/system/info` endpoint has updated keys. Now lowercase, no underscores and not capitalized. Replace "handlers" with "handlers received", "handlers fetched" and "handlers pending".

File diff suppressed because it is too large Load Diff

View File

@@ -9,9 +9,9 @@
"@msgpack/msgpack": "^2.7.2",
"@mui/icons-material": "^5.8.0",
"@mui/material": "^5.8.1",
"@table-library/react-table-library": "^3.1.2",
"@table-library/react-table-library": "^3.1.4",
"@types/lodash": "^4.14.182",
"@types/node": "^17.0.35",
"@types/node": "^17.0.36",
"@types/react": "^18.0.9",
"@types/react-dom": "^18.0.5",
"@types/react-router-dom": "^5.3.3",
@@ -30,7 +30,7 @@
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"sockette": "^2.0.6",
"typescript": "^4.6.4"
"typescript": "^4.7.2"
},
"scripts": {
"start": "react-app-rewired start",

View File

@@ -1,15 +1,15 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
const root = createRoot(document.getElementById('root') as HTMLElement);
root.render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
</StrictMode>
);

View File

@@ -384,7 +384,10 @@ const DashboardData: FC = () => {
const handleDownloadCsv = () => {
const columns = [
{ accessor: (dv: any) => dv.id.slice(2), name: 'Entity' },
{ accessor: (dv: any) => (typeof dv.v === 'number') ? new Intl.NumberFormat().format(dv.v) : dv.v, name: 'Value' },
{
accessor: (dv: any) => (typeof dv.v === 'number' ? new Intl.NumberFormat().format(dv.v) : dv.v),
name: 'Value'
},
{ accessor: (dv: any) => DeviceValueUOM_s[dv.u], name: 'UoM' }
];
downloadAsCsv(
@@ -449,7 +452,7 @@ const DashboardData: FC = () => {
}
};
const isCmdOnly = (dv: DeviceValue) => dv.v === undefined && dv.c;
const isCmdOnly = (dv: DeviceValue) => dv.v === '' && dv.c;
function formatValue(value: any, uom: number) {
if (value === undefined) {

View File

@@ -0,0 +1,39 @@
import { FC } from 'react';
import { SvgIconProps } from '@mui/material';
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import StarIcon from '@mui/icons-material/Star';
import StarOutlineIcon from '@mui/icons-material/StarOutline';
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import InsertCommentOutlinedIcon from '@mui/icons-material/InsertCommentOutlined';
type OptionType = 'readonly' | 'web_exclude' | 'api_mqtt_exclude' | 'favorite';
const OPTION_ICONS: { [type in OptionType]: [React.ComponentType<SvgIconProps>, React.ComponentType<SvgIconProps>] } = {
readonly: [EditOffOutlinedIcon, EditOutlinedIcon],
web_exclude: [VisibilityOffOutlinedIcon, VisibilityOutlinedIcon],
api_mqtt_exclude: [CommentsDisabledOutlinedIcon, InsertCommentOutlinedIcon],
favorite: [StarIcon, StarOutlineIcon]
};
interface OptionIconProps {
type: OptionType;
isSet: boolean;
}
const OptionIcon: FC<OptionIconProps> = ({ type, isSet }) => {
const Icon = OPTION_ICONS[type][isSet ? 0 : 1];
return isSet ? (
<Icon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />
) : (
<Icon sx={{ fontSize: 14, verticalAlign: 'middle' }} />
);
};
export default OptionIcon;

View File

@@ -25,10 +25,12 @@ import { useSnackbar } from 'notistack';
import SaveIcon from '@mui/icons-material/Save';
import CancelIcon from '@mui/icons-material/Cancel';
import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
import StarIcon from '@mui/icons-material/Star';
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
// import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined';
// import StarIcon from '@mui/icons-material/Star';
// import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined';
// import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined';
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined';
import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined';
@@ -36,6 +38,8 @@ import UnfoldMoreOutlinedIcon from '@mui/icons-material/UnfoldMoreOutlined';
import SearchIcon from '@mui/icons-material/Search';
import FilterListIcon from '@mui/icons-material/FilterList';
import OptionIcon from './OptionIcon';
import { ButtonRow, FormLoader, ValidatedTextField, SectionContent } from '../components';
import * as EMSESP from './api';
@@ -47,7 +51,7 @@ import { DeviceShort, Devices, DeviceEntity, DeviceEntityMask } from './types';
const SettingsCustomization: FC = () => {
const { enqueueSnackbar } = useSnackbar();
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([{ id: '', v: 0, s: '', m: 0, w: false }]);
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([{ id: '', v: 0, n: '', m: 0, w: false }]);
const [devices, setDevices] = useState<Devices>();
const [errorMessage, setErrorMessage] = useState<string>();
const [selectedDevice, setSelectedDevice] = useState<number>(0);
@@ -199,6 +203,15 @@ const SettingsCustomization: FC = () => {
return value;
}
function formatName(de: DeviceEntity) {
if (de.n === undefined || de.n === de.id) {
return de.id;
} else if (de.n === '') {
return 'Command: ' + de.id;
}
return de.n + ' (' + de.id + ')';
}
const getMaskNumber = (newMask: string[]) => {
var new_mask = 0;
for (let entry of newMask) {
@@ -272,7 +285,7 @@ const SettingsCustomization: FC = () => {
if (deviceEntities && selectedDevice) {
const masked_entities = deviceEntities
.filter((de) => de.m !== de.om)
.map((new_de) => new_de.m.toString(16).padStart(2, '0') + new_de.s);
.map((new_de) => new_de.m.toString(16).padStart(2, '0') + new_de.id);
if (masked_entities.length > 60) {
enqueueSnackbar('Selected entities exceeded limit of 60. Please Save in batches', { variant: 'warning' });
@@ -303,8 +316,18 @@ const SettingsCustomization: FC = () => {
return (
<>
<Box color="warning.main">
<Typography variant="body2">Select a device and customize each of its entities using the options.</Typography>
<Box mb={2} color="warning.main">
<Typography variant="body2">Select a device and customize each of its entities using the options:</Typography>
<Typography variant="body2">
<OptionIcon type="favorite" isSet={true} />
=mark as a favorite&nbsp;&nbsp;
<OptionIcon type="readonly" isSet={true} />
=disable write action&nbsp;&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={true} />
=exclude from MQTT and API outputs&nbsp;&nbsp;
<OptionIcon type="web_exclude" isSet={true} />
=hide from Web Dashboard
</Typography>
</Box>
<ValidatedTextField
name="device"
@@ -363,9 +386,11 @@ const SettingsCustomization: FC = () => {
}}
/>
</Grid>
<Tooltip arrow placement="top" title="apply filter">
<Grid item>
<FilterListIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />:
</Grid>
</Tooltip>
<Grid item>
<ToggleButtonGroup
size="small"
@@ -376,34 +401,22 @@ const SettingsCustomization: FC = () => {
}}
>
<ToggleButton value="8">
<Tooltip arrow placement="top" title="filter favorites">
<StarIcon sx={{ fontSize: 14 }} />
</Tooltip>
<OptionIcon type="favorite" isSet={true} />
</ToggleButton>
<ToggleButton value="4">
<Tooltip arrow placement="top" title="filter entities with write action disabled">
<EditOffOutlinedIcon sx={{ fontSize: 14 }} />
</Tooltip>
<OptionIcon type="readonly" isSet={true} />
</ToggleButton>
<ToggleButton value="2">
<Tooltip arrow placement="top" title="filter entities excluded from MQTT and API outputs">
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14 }} />
</Tooltip>
<OptionIcon type="api_mqtt_exclude" isSet={true} />
</ToggleButton>
<ToggleButton value="1">
<Tooltip arrow placement="top" title="filter entities hidden from Web Dashboard">
<VisibilityOffOutlinedIcon sx={{ fontSize: 14 }} />
</Tooltip>
<OptionIcon type="web_exclude" isSet={true} />
</ToggleButton>
</ToggleButtonGroup>
</Grid>
<Grid item>
<CommentsDisabledOutlinedIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />
<VisibilityOffOutlinedIcon color="primary" sx={{ fontSize: 14, verticalAlign: 'middle' }} />:
</Grid>
<Grid item>
<Tooltip arrow placement="top" title="mark shown entities to be all visible and output ">
<Tooltip arrow placement="top" title="set selected entities to be both visible and output">
<Button
size="small"
sx={{ fontSize: 10 }}
@@ -411,12 +424,14 @@ const SettingsCustomization: FC = () => {
color="inherit"
onClick={() => maskDisabled(false)}
>
enable
set all&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={false} />
<OptionIcon type="web_exclude" isSet={false} />
</Button>
</Tooltip>
</Grid>
<Grid item>
<Tooltip arrow placement="top" title="mark shown entities to be not visible or output ">
<Tooltip arrow placement="top" title="set selected entities to be not visible and not output">
<Button
size="small"
sx={{ fontSize: 10 }}
@@ -424,7 +439,9 @@ const SettingsCustomization: FC = () => {
color="inherit"
onClick={() => maskDisabled(true)}
>
disable
set all&nbsp;
<OptionIcon type="api_mqtt_exclude" isSet={true} />
<OptionIcon type="web_exclude" isSet={true} />
</Button>
</Tooltip>
</Grid>
@@ -458,29 +475,44 @@ const SettingsCustomization: FC = () => {
value={getMaskString(de.m)}
onChange={(event, mask) => {
de.m = getMaskNumber(mask);
if (de.n === '' && de.m & DeviceEntityMask.DV_READONLY) {
de.m = de.m | DeviceEntityMask.DV_WEB_EXCLUDE;
}
if (de.m & DeviceEntityMask.DV_WEB_EXCLUDE) {
de.m = de.m & ~DeviceEntityMask.DV_FAVORITE;
}
setMasks(['']);
}}
>
<ToggleButton value="8" disabled={(de.m & 1) !== 0 || de.id === ''}>
<StarIcon sx={{ fontSize: 14 }} />
<ToggleButton value="8" disabled={(de.m & 1) !== 0 || de.n === undefined}>
<OptionIcon
type="favorite"
isSet={(de.m & DeviceEntityMask.DV_FAVORITE) === DeviceEntityMask.DV_FAVORITE}
/>
</ToggleButton>
<ToggleButton value="4" disabled={!de.w || (de.m & 3) === 3}>
<EditOffOutlinedIcon sx={{ fontSize: 14 }} />
<OptionIcon
type="readonly"
isSet={(de.m & DeviceEntityMask.DV_READONLY) === DeviceEntityMask.DV_READONLY}
/>
</ToggleButton>
<ToggleButton value="2">
<CommentsDisabledOutlinedIcon sx={{ fontSize: 14 }} />
<ToggleButton value="2" disabled={de.n === ''}>
<OptionIcon
type="api_mqtt_exclude"
isSet={
(de.m & DeviceEntityMask.DV_API_MQTT_EXCLUDE) === DeviceEntityMask.DV_API_MQTT_EXCLUDE
}
/>
</ToggleButton>
<ToggleButton value="1">
<VisibilityOffOutlinedIcon sx={{ fontSize: 14 }} />
<ToggleButton value="1" disabled={de.n === undefined}>
<OptionIcon
type="web_exclude"
isSet={(de.m & DeviceEntityMask.DV_WEB_EXCLUDE) === DeviceEntityMask.DV_WEB_EXCLUDE}
/>
</ToggleButton>
</ToggleButtonGroup>
</Cell>
<Cell>
{de.id}&nbsp;({de.s})
</Cell>
<Cell>{formatName(de)}</Cell>
<Cell>{formatValue(de.v)}</Cell>
</Row>
))}

View File

@@ -131,9 +131,9 @@ export interface DeviceData {
}
export interface DeviceEntity {
id: string; // name
v: any; // value, in any format
s: string; // shortname
id: string; // shortname
v?: any; // value, in any format, optional
n?: string; // fullname, optional
m: number; // mask
om?: number; // original mask before edits
w: boolean; // writeable

View File

@@ -14,7 +14,7 @@
"express": "^4.18.1",
"express-sse": "^0.5.3",
"nodemon": "^2.0.16",
"ws": "^8.6.0"
"ws": "^8.7.0"
}
},
"node_modules/@msgpack/msgpack": {
@@ -1811,9 +1811,9 @@
}
},
"node_modules/ws": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
"integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
"integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
"engines": {
"node": ">=10.0.0"
},
@@ -3169,9 +3169,9 @@
}
},
"ws": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
"integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz",
"integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==",
"requires": {}
},
"xdg-basedir": {

View File

@@ -16,6 +16,6 @@
"express": "^4.18.1",
"express-sse": "^0.5.3",
"nodemon": "^2.0.16",
"ws": "^8.6.0"
"ws": "^8.7.0"
}
}

View File

@@ -336,6 +336,7 @@ settings = {
pbutton_gpio: 0,
board_profile: 'S32',
bool_format: 1,
bool_dashboard: 1,
enum_format: 1,
}
@@ -472,7 +473,7 @@ const emsesp_devicedata_1 = {
const emsesp_devicedata_2 = {
label: 'Boiler: Nefit GBx72/Trendline/Cerapur/Greenstar Si/27i',
data: [
{ v: 0, u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
{ v: '', u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
{ v: 'false', u: 0, id: '08heating active' },
{ v: 'false', u: 0, id: '04tapwater active' },
{ v: 5, u: 1, id: '04selected flow temperature', c: 'selflowtemp' },
@@ -574,145 +575,161 @@ const emsesp_devicedata_4 = {
],
}
// CUSTOMIZATION
const emsesp_deviceentities_1 = [
{
v: '(0)',
n: 'error code',
id: 'errorcode',
s: 'errorcode',
m: 0,
w: false,
},
{
v: '14:54:39 06/06/2021',
id: 'date/time',
s: 'datetime',
n: 'date/time',
id: 'datetime',
m: 0,
w: false,
},
{
v: 'test data',
n: 'test',
id: 'test',
m: 0,
w: false,
},
{
v: 'roomTemp',
id: 'hc1/HA climate config creation',
m: 0,
w: false,
},
{
v: 18.2,
id: 'hc1 selected room temperature',
s: 'hc1/seltemp',
n: 'hc1 selected room temperature',
id: 'hc1/seltemp',
m: 0,
w: true,
},
{
v: 22.6,
id: 'hc1 current room temperature',
s: 'hc1/curtemp',
n: 'hc1 current room temperature',
id: 'hc1/curtemp',
m: 0,
w: false,
},
{
v: 'auto',
id: 'hc1 mode',
s: 'hc1/mode',
n: 'hc1 mode',
id: 'hc1/mode',
m: 0,
w: true,
},
]
const emsesp_deviceentities_2 = [
{ v: false, id: 'heating active', s: 'heatingactive', m: 0, w: false },
{ v: false, id: 'tapwater active', s: 'tapwateractive', m: 0, w: false },
{ v: 5, id: 'selected flow temperature', s: 'selflowtemp', m: 0, w: true },
{ v: 0, id: 'burner selected max power', s: 'selburnpow', m: 0, w: true },
{ v: 0, id: 'heating pump modulation', s: 'heatingpumpmod', m: 0, w: false },
{ id: 'heating pump 2 modulation', s: 'heatingpump2mod', m: 0, w: false },
{ id: 'outside temperature', s: 'outdoortemp', m: 0, w: false },
{ v: 53, id: 'current flow temperature', s: 'curflowtemp', m: 0, w: false },
{ v: 51.8, id: 'return temperature', s: 'rettemp', m: 0, w: false },
{ id: 'mixing switch temperature', s: 'switchtemp', m: 0, w: false },
{ v: 1.3, id: 'system pressure', s: 'syspress', m: 0, w: false },
{ v: 54.6, id: 'actual boiler temperature', s: 'boiltemp', m: 0, w: false },
{ id: 'exhaust temperature', s: 'exhausttemp', m: 0, w: false },
{ v: false, id: 'gas', s: 'burngas', m: 0, w: false },
{ v: false, id: 'gas stage 2', s: 'burngas2', m: 0, w: false },
{ v: 0, id: 'flame current', s: 'flamecurr', m: 0, w: false },
{ v: false, id: 'heating pump', s: 'heatingpump', m: 0, w: false },
{ v: false, id: 'fan', s: 'fanwork', m: 0, w: false },
{ v: false, id: 'ignition', s: 'ignwork', m: 0, w: false },
{ v: false, id: 'oil preheating', s: 'oilpreheat', m: 0, w: false },
{ v: true, id: 'heating activated', s: 'heatingactivated', m: 0, w: false },
{ v: 80, id: 'heating temperature', s: 'heatingtemp', m: 0, w: false },
{ v: 70, id: 'burner pump max power', s: 'pumpmodmax', m: 0, w: false },
{ v: 30, id: 'burner pump min power', s: 'pumpmodmin', m: 0, w: false },
{ v: 1, id: 'pump delay', s: 'pumpdelay', m: 0, w: false },
{ v: 10, id: 'burner min period', s: 'burnminperiod', m: 0, w: false },
{ v: 0, id: 'burner min power', s: 'burnminpower', m: 0, w: false },
{ v: 50, id: 'burner max power', s: 'burnmaxpower', m: 0, w: false },
{ v: -6, id: 'hysteresis on temperature', s: 'boilhyston', m: 0, w: false },
{ v: 6, id: 'hysteresis off temperature', s: 'boilhystoff', m: 0, w: false },
{ v: 0, id: 'set flow temperature', s: 'setflowtemp', m: 0, w: true },
{ v: 0, id: 'burner set power', s: 'setburnpow', m: 0, w: false },
{ v: 0, id: 'burner current power', s: 'curburnpow', m: 0, w: false },
{ v: 326323, id: 'burner starts', s: 'burnstarts', m: 0, w: false },
{ v: 553437, id: 'total burner operating time', s: 'burnworkmin', m: 0, w: false },
{ v: 451286, id: 'total heat operating time', s: 'heatworkmin', m: 0, w: false },
{ v: 4672175, id: 'total UBA operating time', s: 'ubauptime', m: 0, w: false },
{ v: '1C(210) 06.06.2020 12:07 (0 min)', id: 'last error code', s: 'lastcode', m: 0, w: false },
{ v: '0H', id: 'service code', s: 'servicecode', m: 0, w: false },
{ v: 203, id: 'service code number', s: 'servicecodenumber', m: 0, w: false },
{ v: 'H00', id: 'maintenance message', s: 'maintenancemessage', m: 0, w: false },
{ v: 'manual', id: 'maintenance scheduled', s: 'maintenance', m: 0, w: false },
{ v: 6000, id: 'time to next maintenance', s: 'maintenancetime', m: 0, w: false },
{ v: '01.01.2012', id: 'next maintenance date', s: 'maintenancedate', m: 0, w: false },
{ v: true, id: 'dhw turn on/off', s: 'wwtapactivated', m: 0, w: false },
{ v: 62, id: 'dhw set temperature', s: 'wwsettemp', m: 0, w: false },
{ v: 60, id: 'dhw selected temperature', s: 'wwseltemp', m: 0, w: true },
{ id: 'dhw selected lower temperature', s: 'wwseltemplow', m: 2 },
{ id: 'dhw selected temperature for off', s: 'wwseltempoff', m: 2 },
{ id: 'dhw single charge temperature', s: 'wwseltempsingle', m: 2 },
{ v: 'flow', id: 'dhw type', s: 'wwtype', m: 0, w: false },
{ v: 'hot', id: 'dhw comfort', s: 'wwcomfort', m: 0, w: false },
{ v: 40, id: 'dhw flow temperature offset', s: 'wwflowtempoffset', m: 0, w: false },
{ v: 100, id: 'dhw max power', s: 'wwmaxpower', m: 0, w: false },
{ v: false, id: 'dhw circulation pump available', s: 'wwcircpump', m: 0, w: false },
{ v: '3-way valve', id: 'dhw charging type', s: 'wwchargetype', m: 0, w: false },
{ v: -5, id: 'dhw hysteresis on temperature', s: 'wwhyston', m: 0, w: false },
{ v: 0, id: 'dhw hysteresis off temperature', s: 'wwhystoff', m: 0, w: false },
{ v: 70, id: 'dhw disinfection temperature', s: 'wwdisinfectiontemp', m: 0, w: false },
{ v: 'off', id: 'dhw circulation pump mode', s: 'wwcircmode', m: 0, w: false },
{ v: false, id: 'dhw circulation active', s: 'wwcirc', m: 0, w: false },
{ v: 46.4, id: 'dhw current intern temperature', s: 'wwcurtemp', m: 0, w: false },
{ id: 'dhw current extern temperature', s: 'wwcurtemp2', m: 2 },
{ v: 0, id: 'dhw current tap water flow', s: 'wwcurflow', m: 0, w: false },
{ v: 46.3, id: 'dhw storage intern temperature', s: 'wwstoragetemp1', m: 0, w: false },
{ id: 'dhw storage extern temperature', s: 'wwstoragetemp2', m: 2 },
{ v: true, id: 'dhw activated', s: 'wwactivated', m: 0, w: false },
{ v: false, id: 'dhw one time charging', s: 'wwonetime', m: 0, w: false },
{ v: false, id: 'dhw disinfecting', s: 'wwdisinfecting', m: 0, w: false },
{ v: false, id: 'dhw charging', s: 'wwcharging', m: 0, w: false },
{ v: false, id: 'dhw recharging', s: 'wwrecharging', m: 0, w: false },
{ v: true, id: 'dhw temperature ok', s: 'wwtempok', m: 0, w: false },
{ v: false, id: 'dhw active', s: 'wwactive', m: 0, w: false },
{ v: true, id: 'dhw 3way valve active', s: 'ww3wayvalve', m: 0, w: false },
{ v: 0, id: 'dhw set pump power', s: 'wwsetpumppower', m: 0, w: true },
{ id: 'dhw mixer temperature', s: 'wwmixertemp', m: 2 },
{ id: 'dhw cylinder middle temperature (TS3)', s: 'wwcylmiddletemp', m: 2 },
{ v: 288768, id: 'dhw starts', s: 'wwstarts', m: 0, w: false },
{ v: 102151, id: 'dhw active time', s: 'wwworkm', m: 0, w: false },
{ u: 0, n: '', id: 'reset', m: 8, w: false },
{ v: false, n: 'heating active', id: 'heatingactive', m: 8, w: false },
{ v: false, n: 'tapwater active', id: 'tapwateractive', m: 4, w: false },
{ v: 5, n: 'selected flow temperature', id: 'selflowtemp', m: 4, w: true },
{ v: 0, n: 'burner selected max power', id: 'selburnpow', m: 14, w: true },
{ v: 0, n: 'heating pump modulation', id: 'heatingpumpmod', m: 0, w: false },
{ n: 'heating pump 2 modulation', id: 'heatingpump2mod', m: 0, w: false },
{ n: 'outside temperature', id: 'outdoortemp', m: 0, w: false },
{ v: 53, n: 'current flow temperature', id: 'curflowtemp', m: 0, w: false },
{ v: 51.8, n: 'return temperature', id: 'rettemp', m: 0, w: false },
{ n: 'mixing switch temperature', id: 'switchtemp', m: 0, w: false },
{ v: 1.3, n: 'system pressure', id: 'syspress', m: 0, w: false },
{ v: 54.6, n: 'actual boiler temperature', id: 'boiltemp', m: 0, w: false },
{ n: 'exhaust temperature', id: 'exhausttemp', m: 0, w: false },
{ v: false, n: 'gas', id: 'burngas', m: 0, w: false },
{ v: false, n: 'gas stage 2', id: 'burngas2', m: 0, w: false },
{ v: 0, n: 'flame current', id: 'flamecurr', m: 0, w: false },
{ v: false, n: 'heating pump', id: 'heatingpump', m: 0, w: false },
{ v: false, n: 'fan', id: 'fanwork', m: 0, w: false },
{ v: false, n: 'ignition', id: 'ignwork', m: 0, w: false },
{ v: false, n: 'oil preheating', id: 'oilpreheat', m: 0, w: false },
{ v: true, n: 'heating activated', id: 'heatingactivated', m: 0, w: false },
{ v: 80, n: 'heating temperature', id: 'heatingtemp', m: 0, w: false },
{ v: 70, n: 'burner pump max power', id: 'pumpmodmax', m: 0, w: false },
{ v: 30, n: 'burner pump min power', id: 'pumpmodmin', m: 0, w: false },
{ v: 1, n: 'pump delay', id: 'pumpdelay', m: 0, w: false },
{ v: 10, n: 'burner min period', id: 'burnminperiod', m: 0, w: false },
{ v: 0, n: 'burner min power', id: 'burnminpower', m: 0, w: false },
{ v: 50, n: 'burner max power', id: 'burnmaxpower', m: 0, w: false },
{ v: -6, n: 'hysteresis on temperature', id: 'boilhyston', m: 0, w: false },
{ v: 6, n: 'hysteresis off temperature', id: 'boilhystoff', m: 0, w: false },
{ v: 0, n: 'set flow temperature', id: 'setflowtemp', m: 0, w: true },
{ v: 0, n: 'burner set power', id: 'setburnpow', m: 0, w: false },
{ v: 0, n: 'burner current power', id: 'curburnpow', m: 0, w: false },
{ v: 326323, n: 'burner starts', id: 'burnstarts', m: 0, w: false },
{ v: 553437, n: 'total burner operating time', id: 'burnworkmin', m: 0, w: false },
{ v: 451286, n: 'total heat operating time', id: 'heatworkmin', m: 0, w: false },
{ v: 4672175, n: 'total UBA operating time', id: 'ubauptime', m: 0, w: false },
{ v: '1C(210) 06.06.2020 12:07 (0 min)', n: 'last error code', id: 'lastcode', m: 0, w: false },
{ v: '0H', n: 'service code', id: 'servicecode', m: 0, w: false },
{ v: 203, n: 'service code number', id: 'servicecodenumber', m: 0, w: false },
{ v: 'H00', n: 'maintenance message', id: 'maintenancemessage', m: 0, w: false },
{ v: 'manual', n: 'maintenance scheduled', id: 'maintenance', m: 0, w: false },
{ v: 6000, n: 'time to next maintenance', id: 'maintenancetime', m: 0, w: false },
{ v: '01.01.2012', n: 'next maintenance date', id: 'maintenancedate', m: 0, w: false },
{ v: true, n: 'dhw turn on/off', id: 'wwtapactivated', m: 0, w: false },
{ v: 62, n: 'dhw set temperature', id: 'wwsettemp', m: 0, w: false },
{ v: 60, n: 'dhw selected temperature', id: 'wwseltemp', m: 0, w: true },
{ n: 'dhw selected lower temperature', id: 'wwseltemplow', m: 2 },
{ n: 'dhw selected temperature for off', id: 'wwseltempoff', m: 2 },
{ n: 'dhw single charge temperature', id: 'wwseltempsingle', m: 2 },
{ v: 'flow', n: 'dhw type', id: 'wwtype', m: 0, w: false },
{ v: 'hot', n: 'dhw comfort', id: 'wwcomfort', m: 0, w: false },
{ v: 40, n: 'dhw flow temperature offset', id: 'wwflowtempoffset', m: 0, w: false },
{ v: 100, n: 'dhw max power', id: 'wwmaxpower', m: 0, w: false },
{ v: false, n: 'dhw circulation pump available', id: 'wwcircpump', m: 0, w: false },
{ v: '3-way valve', n: 'dhw charging type', id: 'wwchargetype', m: 0, w: false },
{ v: -5, n: 'dhw hysteresis on temperature', id: 'wwhyston', m: 0, w: false },
{ v: 0, n: 'dhw hysteresis off temperature', id: 'wwhystoff', m: 0, w: false },
{ v: 70, n: 'dhw disinfection temperature', id: 'wwdisinfectiontemp', m: 0, w: false },
{ v: 'off', n: 'dhw circulation pump mode', id: 'wwcircmode', m: 0, w: false },
{ v: false, n: 'dhw circulation active', id: 'wwcirc', m: 0, w: false },
{ v: 46.4, n: 'dhw current intern temperature', id: 'wwcurtemp', m: 0, w: false },
{ n: 'dhw current extern temperature', id: 'wwcurtemp2', m: 2 },
{ v: 0, n: 'dhw current tap water flow', id: 'wwcurflow', m: 0, w: false },
{ v: 46.3, n: 'dhw storage intern temperature', id: 'wwstoragetemp1', m: 0, w: false },
{ n: 'dhw storage extern temperature', id: 'wwstoragetemp2', m: 2 },
{ v: true, n: 'dhw activated', id: 'wwactivated', m: 0, w: false },
{ v: false, n: 'dhw one time charging', id: 'wwonetime', m: 0, w: false },
{ v: false, n: 'dhw disinfecting', id: 'wwdisinfecting', m: 0, w: false },
{ v: false, n: 'dhw charging', id: 'wwcharging', m: 0, w: false },
{ v: false, n: 'dhw recharging', id: 'wwrecharging', m: 0, w: false },
{ v: true, n: 'dhw temperature ok', id: 'wwtempok', m: 0, w: false },
{ v: false, n: 'dhw active', id: 'wwactive', m: 0, w: false },
{ v: true, n: 'dhw 3way valve active', id: 'ww3wayvalve', m: 0, w: false },
{ v: 0, n: 'dhw set pump power', id: 'wwsetpumppower', m: 0, w: true },
{ n: 'dhw mixer temperature', id: 'wwmixertemp', m: 2 },
{ n: 'dhw cylinder middle temperature (TS3)', id: 'wwcylmiddletemp', m: 2 },
{ v: 288768, n: 'dhw starts', id: 'wwstarts', m: 0, w: false },
{ v: 102151, n: 'dhw active time', id: 'wwworkm', m: 0, w: false },
]
const emsesp_deviceentities_4 = [
{
v: 16,
id: 'hc2 selected room temperature',
s: 'hc2/seltemp',
n: 'hc2 selected room temperature',
id: 'hc2/seltemp',
m: 8,
w: true,
},
{
v: 18.5,
id: 'hc2 current room temperature',
s: 'hc2/curtemp',
n: 'hc2 current room temperature',
id: 'hc2/curtemp',
m: 2,
w: false,
},
{
v: 'off',
id: 'hc2 mode',
s: 'hc2/mode',
n: 'hc2 mode',
id: 'hc2/mode',
m: 2,
w: true,
},
@@ -911,13 +928,13 @@ rest_server.post(EMSESP_DEVICEENTITIES_ENDPOINT, (req, res) => {
})
function updateMask(entity, de, dd) {
const name = entity.slice(2)
const shortname = entity.slice(2)
const new_mask = parseInt(entity.slice(0, 2), 16)
objIndex = de.findIndex((obj) => obj.s == name)
objIndex = de.findIndex((obj) => obj.id == shortname)
if (objIndex !== -1) {
de[objIndex].m = new_mask
const fullname = de[objIndex].id
const fullname = de[objIndex].n
objIndex = dd.data.findIndex((obj) => obj.id.slice(2) == fullname)
if (objIndex !== -1) {
// see if the mask has changed
@@ -929,7 +946,7 @@ function updateMask(entity, de, dd) {
}
}
} else {
console.log("can't locate record for id " + id)
console.log("can't locate record for name " + shortname)
}
}

View File

@@ -32,5 +32,5 @@ build_type = debug
monitor_filters = esp32_exception_decoder
debug_tool = esp-prog
debug_init_break = tbreak setup
build_flags = ${factory_settings.build_flags} ${common.debug_flags} -DONEWIRE_CRC16=0 -DNO_GLOBAL_ARDUINOOTA -DARDUINOJSON_ENABLE_STD_STRING=1 -DESP32=1 -DARDUINO_ARCH_ESP32=1
build_flags = ${factory_settings.build_flags} -DONEWIRE_CRC16=0 -DNO_GLOBAL_ARDUINOOTA -DARDUINOJSON_ENABLE_STD_STRING=1 -DESP32=1 -DARDUINO_ARCH_ESP32=1
extra_scripts = pre:scripts/build_interface.py

View File

@@ -62,8 +62,7 @@ extra_scripts =
pre:scripts/build_interface.py
scripts/rename_fw.py
board = esp32dev
; platform = espressif32
platform = https://github.com/platformio/platform-espressif32.git ; develop
platform = espressif32
board_build.partitions = esp32_partition_app1984k_spiffs64k.csv
build_flags = ${common.build_flags}
build_unflags = ${common.unbuild_flags}

View File

@@ -68,7 +68,7 @@
{224, DeviceType::CONTROLLER, F("9000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
{229, DeviceType::CONTROLLER, F("8700i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
{230, DeviceType::CONTROLLER, F("BC Base"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
{240, DeviceType::CONTROLLER, F("Rego 3000"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
{240, DeviceType::CONTROLLER, F("Rego 3000"), DeviceFlags::EMS_DEVICE_FLAG_IVT}, // 0x09
{241, DeviceType::CONTROLLER, F("Condens 5000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
// Thermostat - not currently supporting write operations, like the Easy/100 types - 0x18

View File

@@ -25,9 +25,11 @@ REGISTER_FACTORY(Controller, EMSdevice::DeviceType::CONTROLLER);
Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
// IVT broadcasts Thermostat time from controller (0x09) if display is off.
if ((flags & 0x0F) == EMS_DEVICE_FLAG_IVT) {
register_telegram_type(0x06, F("RCTime"), false, MAKE_PF_CB(process_dateTime));
register_device_value(DeviceValueTAG::TAG_NONE, &dateTime_, DeviceValueType::STRING, nullptr, FL_(dateTime), DeviceValueUOM::NONE);
}
}
// process_dateTime - type 0x06 - date and time from a thermostat - 14 bytes long, IVT only
void Controller::process_dateTime(std::shared_ptr<const Telegram> telegram) {
@@ -35,7 +37,7 @@ void Controller::process_dateTime(std::shared_ptr<const Telegram> telegram) {
return;
}
char newdatetime[sizeof(dateTime_)];
// publich as dd.mm.yyyy hh:mmF
// publish as dd.mm.yyyy hh:mm
snprintf(newdatetime,
sizeof(dateTime_),
"%02d.%02d.%04d %02d:%02d",
@@ -47,5 +49,4 @@ void Controller::process_dateTime(std::shared_ptr<const Telegram> telegram) {
has_update(dateTime_, newdatetime, sizeof(dateTime_));
}
} // namespace emsesp

View File

@@ -114,6 +114,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
} else if ((model == EMSdevice::EMS_DEVICE_FLAG_RC300) || (model == EMSdevice::EMS_DEVICE_FLAG_RC100)) {
monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9, 0x02AA, 0x02AB, 0x02AC};
set_typeids = {0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD, 0x02BE, 0x02BF, 0x02C0};
set2_typeids = {0x02CC, 0x02CE, 0x02D0, 0x02D2}; // max. 4 heating circuits supported ny RC310
summer_typeids = {0x02AF, 0x02B0, 0x02B1, 0x02B2, 0x02B3, 0x02B4, 0x02B5, 0x02B6};
curve_typeids = {0x029B, 0x029C, 0x029D, 0x029E, 0x029F, 0x02A0, 0x02A1, 0x02A2};
summer2_typeids = {0x0471, 0x0472, 0x0473, 0x0474, 0x0475, 0x0476, 0x0477, 0x0478};
@@ -124,6 +125,9 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
register_telegram_type(curve_typeids[i], F("RC300Curves"), false, MAKE_PF_CB(process_RC300Curve));
register_telegram_type(summer2_typeids[i], F("RC300Summer2"), false, MAKE_PF_CB(process_RC300Summer2));
}
for (uint8_t i = 0; i < set2_typeids.size(); i++) {
register_telegram_type(set2_typeids[i], F("RC300Set2"), false, MAKE_PF_CB(process_RC300Set2));
}
register_telegram_type(0x2F5, F("RC300WWmode"), true, MAKE_PF_CB(process_RC300WWmode));
register_telegram_type(0x31B, F("RC300WWtemp"), true, MAKE_PF_CB(process_RC300WWtemp));
register_telegram_type(0x31D, F("RC300WWmode2"), false, MAKE_PF_CB(process_RC300WWmode2));
@@ -221,6 +225,16 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
}
}
// not found, search set2 types
if (hc_num == 0) {
for (uint8_t i = 0; i < set2_typeids.size(); i++) {
if (set2_typeids[i] == telegram->type_id) {
hc_num = i + 1;
break;
}
}
}
// not found, search summer message types
if (hc_num == 0) {
for (uint8_t i = 0; i < summer_typeids.size(); i++) {
@@ -328,6 +342,9 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
if (set_typeids.size()) {
toggle_fetch(set_typeids[hc_num - 1], toggle_);
}
if (hc_num <= set2_typeids.size()) {
toggle_fetch(set2_typeids[hc_num - 1], toggle_);
}
if (summer_typeids.size()) {
toggle_fetch(summer_typeids[hc_num - 1], toggle_);
}
@@ -922,6 +939,10 @@ void Thermostat::process_RC300Set(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, hc->manualtemp, 10); // is * 2
has_enumupdate(telegram, hc->program, 11, 1); // timer program 1 or 2
has_enumupdate(telegram, hc->reducemode, 5, 1); // 1-outdoor temp threshold, 2-room temp threshold, 3-reduced mode
has_update(telegram, hc->reducetemp, 9);
has_update(telegram, hc->noreducetemp, 12);
}
// types 0x2AF ff
@@ -967,8 +988,10 @@ void Thermostat::process_RC300Curve(std::shared_ptr<const Telegram> telegram) {
return;
}
has_update(telegram, hc->controlmode, 0); // 1-outdoor, 2-simple, 3-MPC, 4-room, 5-power, 6-const
has_enumupdate(telegram, hc->controlmode, 0, 1); // 1-weather_compensated, 2-outside_footpoint,3-n/a, 4-room -- RC310
has_update(telegram, hc->heatingtype, 1); // 1=radiator, 2=convector, 3=floor
has_update(telegram, hc->switchonoptimization, 4);
has_enumupdate(telegram, hc->nofrostmode, 5, 1); // 1-room, 2-outdoor, 3- room & outdoor
has_update(telegram, hc->nofrosttemp, 6);
if (hc->heatingtype < 3) {
@@ -1022,10 +1045,24 @@ void Thermostat::process_RC300OutdoorTemp(std::shared_ptr<const Telegram> telegr
// 0x240 RC300 parameter
void Thermostat::process_RC300Settings(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, ibaDamping_, 8);
has_enumupdate(telegram, ibaBuildingType_, 9, 1); // 1=light, 2=medium, 3=heavy
has_update(telegram, ibaMinExtTemperature_, 10);
}
// 0x2CC - e.g. wwprio for RC310 hcx parameter
void Thermostat::process_RC300Set2(std::shared_ptr<const Telegram> telegram) {
// typeids are not in a raw. hc:0x2CC, hc2: 0x2CE for RC310
// telegram is either offset 3 with data lenght of 1 and values 0/1 (radiators) - 10 0B FF 03 01 CC 01 F6
// or offset 0 with data lenght of 6 bytes - offset 3 values are 0x00 or 0xFF - 10 0B FF 00 01 CE FF 13 0A FF 1E 00 20
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
if (hc == nullptr) {
return;
}
has_update(telegram, hc->wwprio, 3);
}
// 0x267 RC300 floordrying
void Thermostat::process_RC300Floordry(std::shared_ptr<const Telegram> telegram) {
has_update(telegram, floordrystatus_, 0);
@@ -1597,14 +1634,20 @@ bool Thermostat::set_heatingpid(const char * value, const int8_t id) {
return true;
}
// 0xA5 - Set the damping settings
// 0xA5 and 0x0240- Set the damping settings
bool Thermostat::set_damping(const char * value, const int8_t id) {
bool dmp;
if (model() == EMS_DEVICE_FLAG_RC300) {
if (Helpers::value2bool(value, dmp)) {
write_command(0x240, 8, dmp ? 0xFF : 0, 0x240);
return true;
}
} else {
if (Helpers::value2bool(value, dmp)) {
write_command(EMS_TYPE_IBASettings, 21, dmp ? 0xFF : 0, EMS_TYPE_IBASettings);
return true;
}
}
return false;
}
@@ -1750,12 +1793,16 @@ bool Thermostat::set_wwprio(const char * value, const int8_t id) {
if (!Helpers::value2bool(value, b)) {
return false;
}
if ((model() == EMS_DEVICE_FLAG_RC300)) {
write_command(set2_typeids[hc->hc()], 3, b ? 0xFF : 0x00, set2_typeids[hc->hc()]);
} else {
write_command(set_typeids[hc->hc()], 21, b ? 0xFF : 0x00, set_typeids[hc->hc()]);
}
return true;
}
// sets the thermostat ww circulation working mode, where mode is a string
bool Thermostat::set_wwcircmode(const char * value, const int8_t id) {
uint8_t set = 0xFF;
@@ -2344,7 +2391,25 @@ bool Thermostat::set_fastheatup(const char * value, const int8_t id) {
return true;
}
// sets the thermostat reducemode for RC35
// Set switchonoptimization RC310
bool Thermostat::set_switchonoptimization(const char * value, const int8_t id) {
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(hc_num);
if (hc == nullptr) {
return false;
}
bool b = false;
if (!Helpers::value2bool(value, b)) {
return false;
}
write_command(curve_typeids[hc->hc()], 4, b ? 0xFF : 0x00, curve_typeids[hc->hc()]);
return true;
}
// sets the thermostat reducemode for RC35 and RC310
bool Thermostat::set_reducemode(const char * value, const int8_t id) {
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(hc_num);
@@ -2353,13 +2418,19 @@ bool Thermostat::set_reducemode(const char * value, const int8_t id) {
}
uint8_t set = 0xFF;
if (!Helpers::value2enum(value, set, FL_(enum_reducemode))) {
return false;
if (model() == EMS_DEVICE_FLAG_RC300) {
if (Helpers::value2enum(value, set, FL_(enum_reducemode1))) {
write_command(set_typeids[hc->hc()], 5, set + 1, set_typeids[hc->hc()]);
}
} else {
if (Helpers::value2enum(value, set, FL_(enum_reducemode))) {
write_command(set_typeids[hc->hc()], EMS_OFFSET_RC35Set_reducemode, set, set_typeids[hc->hc()]);
return true;
}
}
return true;
}
// sets the thermostat reducemode for RC35 vacations
bool Thermostat::set_vacreducemode(const char * value, const int8_t id) {
@@ -2378,22 +2449,27 @@ bool Thermostat::set_vacreducemode(const char * value, const int8_t id) {
return true;
}
// sets the thermostat nofrost mode for RC35
// sets the thermostat nofrost mode for RC35, RC300/RC310
bool Thermostat::set_nofrostmode(const char * value, const int8_t id) {
uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id;
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(hc_num);
if (hc == nullptr) {
return false;
}
uint8_t set = 0xFF;
if (!Helpers::value2enum(value, set, FL_(enum_nofrostmode))) {
return false;
if (model() == EMS_DEVICE_FLAG_RC300) {
if (Helpers::value2enum(value, set, FL_(enum_nofrostmode1))) {
write_command(curve_typeids[hc->hc()], 5, set + 1, curve_typeids[hc->hc()]);
return true;
}
} else {
if (Helpers::value2enum(value, set, FL_(enum_nofrostmode))) {
write_command(set_typeids[hc->hc()], EMS_OFFSET_RC35Set_nofrostmode, set, set_typeids[hc->hc()]);
return true;
}
}
return true;
}
// sets the thermostat heatingtype for RC35, RC300
bool Thermostat::set_heatingtype(const char * value, const int8_t id) {
@@ -2429,11 +2505,16 @@ bool Thermostat::set_controlmode(const char * value, const int8_t id) {
}
uint8_t set = 0xFF;
if (model() == EMS_DEVICE_FLAG_RC300 || model() == EMS_DEVICE_FLAG_RC100) {
if (model() == EMS_DEVICE_FLAG_RC100) {
if (Helpers::value2enum(value, set, FL_(enum_controlmode))) {
write_command(curve_typeids[hc->hc()], 0, set, curve_typeids[hc->hc()]);
return true;
}
} else if (model() == EMS_DEVICE_FLAG_RC300) {
if (Helpers::value2enum(value, set, FL_(enum_controlmode1))) {
write_command(curve_typeids[hc->hc()], 0, set + 1, curve_typeids[hc->hc()]);
return true;
}
} else if (model() == EMS_DEVICE_FLAG_RC30) {
if (Helpers::value2enum(value, set, FL_(enum_controlmode2))) {
write_command(curve_typeids[hc->hc()], 1, set, curve_typeids[hc->hc()]);
@@ -2856,6 +2937,16 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co
offset = 0;
factor = 1;
break;
case HeatingCircuit::Mode::NOREDUCE:
validate_typeid = set_typeid;
offset = 12;
factor = 1;
break;
case HeatingCircuit::Mode::REDUCE:
validate_typeid = set_typeid;
offset = 9;
factor = 1;
break;
default:
// HeatingCircuit::Mode::AUTO:
uint8_t mode_ = hc->get_mode();
@@ -3224,6 +3315,8 @@ void Thermostat::register_device_values() {
FL_(ibaMinExtTemperature),
DeviceValueUOM::DEGREES,
MAKE_CF_CB(set_minexttemp));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA, &ibaDamping_, DeviceValueType::BOOL, nullptr, FL_(damping), DeviceValueUOM::NONE, MAKE_CF_CB(set_damping));
register_device_value(
DeviceValueTAG::TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp));
register_device_value(
@@ -3769,6 +3862,8 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
register_device_value(
tag, &hc->roominfl_factor, DeviceValueType::UINT, FL_(div10), FL_(roominfl_factor), DeviceValueUOM::NONE, MAKE_CF_CB(set_roominfl_factor));
register_device_value(tag, &hc->curroominfl, DeviceValueType::SHORT, FL_(div10), FL_(curroominfl), DeviceValueUOM::DEGREES_R);
register_device_value(
tag, &hc->nofrostmode, DeviceValueType::ENUM, FL_(enum_nofrostmode1), FL_(nofrostmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_nofrostmode));
register_device_value(tag, &hc->nofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp));
register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, nullptr, FL_(targetflowtemp), DeviceValueUOM::DEGREES);
register_device_value(
@@ -3784,11 +3879,22 @@ void Thermostat::register_device_values_hc(std::shared_ptr<Thermostat::HeatingCi
MAKE_CF_CB(set_summermode));
register_device_value(tag, &hc->summermode, DeviceValueType::ENUM, FL_(enum_summer), FL_(summermode), DeviceValueUOM::NONE);
register_device_value(
tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode));
tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode1), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode));
register_device_value(tag, &hc->program, DeviceValueType::ENUM, FL_(enum_progMode), FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program));
register_device_value(
tag, &hc->tempautotemp, DeviceValueType::INT, FL_(div2), FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp), -1, 30);
register_device_value(tag, &hc->fastHeatup, DeviceValueType::UINT, nullptr, FL_(fastheatup), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_fastheatup));
register_device_value(tag,
&hc->switchonoptimization,
DeviceValueType::BOOL,
nullptr,
FL_(switchonoptimization),
DeviceValueUOM::NONE,
MAKE_CF_CB(set_switchonoptimization));
register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode1), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode));
register_device_value(tag, &hc->noreducetemp, DeviceValueType::INT, nullptr, FL_(noreducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_noreducetemp));
register_device_value(tag, &hc->reducetemp, DeviceValueType::INT, nullptr, FL_(reducetemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_reducetemp));
register_device_value(tag, &hc->wwprio, DeviceValueType::BOOL, nullptr, FL_(wwprio), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwprio));
break;
case EMS_DEVICE_FLAG_CRF:
register_device_value(tag, &hc->mode, DeviceValueType::ENUM, FL_(enum_mode5), FL_(mode), DeviceValueUOM::NONE);

View File

@@ -80,6 +80,7 @@ class Thermostat : public EMSdevice {
char switchtime1[16];
char switchtime2[16];
uint8_t climate;
uint8_t switchonoptimization;
// RC 10
uint8_t reducehours; // night reduce duration
@@ -160,6 +161,7 @@ class Thermostat : public EMSdevice {
// each thermostat has a list of heating controller type IDs for reading and writing
std::vector<uint16_t> monitor_typeids;
std::vector<uint16_t> set_typeids;
std::vector<uint16_t> set2_typeids;
std::vector<uint16_t> timer_typeids;
std::vector<uint16_t> timer2_typeids;
std::vector<uint16_t> summer_typeids;
@@ -357,6 +359,7 @@ class Thermostat : public EMSdevice {
void process_CRFMonitor(std::shared_ptr<const Telegram> telegram);
void process_RC300Monitor(std::shared_ptr<const Telegram> telegram);
void process_RC300Set(std::shared_ptr<const Telegram> telegram);
void process_RC300Set2(std::shared_ptr<const Telegram> telegram);
void process_RC300Summer(std::shared_ptr<const Telegram> telegram);
void process_RC300Summer2(std::shared_ptr<const Telegram> telegram);
void process_RC300WWmode(std::shared_ptr<const Telegram> telegram);
@@ -412,7 +415,6 @@ class Thermostat : public EMSdevice {
bool set_vacreducetemp(const char * value, const int8_t id);
bool set_vacreducemode(const char * value, const int8_t id);
bool set_nofrostmode(const char * value, const int8_t id);
bool set_remotetemp(const char * value, const int8_t id);
bool set_roominfluence(const char * value, const int8_t id);
bool set_roominfl_factor(const char * value, const int8_t id);
@@ -426,6 +428,7 @@ class Thermostat : public EMSdevice {
bool set_controlmode(const char * value, const int8_t id);
bool set_wwprio(const char * value, const int8_t id);
bool set_fastheatup(const char * value, const int8_t id);
bool set_switchonoptimization(const char * value, const int8_t id);
// set functions - these don't use the id/hc, the parameters are ignored
bool set_wwmode(const char * value, const int8_t id);

View File

@@ -726,11 +726,9 @@ void EMSdevice::generate_values_web(JsonObject & output) {
auto mask = Helpers::hextoa((uint8_t)(dv.state >> 4), false); // create mask to a 2-char string
// add name, prefixing the tag if it exists. This is the id used for the table sorting
// add name, prefixing the tag if it exists. This is the id used in the WebUI table and must be unique
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["id"] = mask + read_flash_string(dv.full_name);
} else if (dv.tag < DeviceValueTAG::TAG_HC1) {
obj["id"] = mask + tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name);
} else {
obj["id"] = mask + tag_to_string(dv.tag) + " " + read_flash_string(dv.full_name);
}
@@ -785,7 +783,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
// as generate_values_web() but stripped down to only show all entities and their state
// this is used only for WebCustomizationService::device_entities()
void EMSdevice::generate_values_web_all(JsonArray & output) {
void EMSdevice::generate_values_web_customization(JsonArray & output) {
for (const auto & dv : devicevalues_) {
// also show commands and entities that have an empty full name
JsonObject obj = output.createNestedObject();
@@ -841,29 +839,29 @@ void EMSdevice::generate_values_web_all(JsonArray & output) {
obj["v"] = (divider > 0) ? time_value / divider : time_value * factor; // sometimes we need to divide by 60
}
}
} else {
// must always have v for sorting to work in web
obj["v"] = "";
}
// add name, prefixing the tag if it exists as the id (key for table sorting)
// id holds the shortname and must always have a value for the WebUI table to work
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
obj["id"] = tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
} else {
obj["id"] = read_flash_string(dv.short_name);
}
// n is the fullname, and can be optional
// don't add the fullname if its a command
if (dv.type != DeviceValueType::CMD) {
if (dv.full_name) {
if ((dv.tag == DeviceValueTAG::TAG_NONE) || tag_to_string(dv.tag).empty()) {
obj["id"] = dv.full_name;
obj["n"] = dv.full_name;
} else {
char name[50];
snprintf(name, sizeof(name), "%s %s", tag_to_string(dv.tag).c_str(), read_flash_string(dv.full_name).c_str());
obj["id"] = name;
obj["n"] = name;
}
}
} else {
obj["id"] = "";
}
// shortname
if (dv.tag >= DeviceValueTAG::TAG_HC1) {
obj["s"] = tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
} else {
obj["s"] = dv.short_name;
obj["n"] = "";
}
obj["m"] = dv.state >> 4; // send back the mask state. We're only interested in the high nibble

View File

@@ -202,7 +202,7 @@ class EMSdevice {
enum OUTPUT_TARGET : uint8_t { API_VERBOSE, API_SHORTNAMES, MQTT, CONSOLE };
bool generate_values(JsonObject & output, const uint8_t tag_filter, const bool nested, const uint8_t output_target);
void generate_values_web(JsonObject & output);
void generate_values_web_all(JsonArray & output);
void generate_values_web_customization(JsonArray & output);
void register_device_value(uint8_t tag,
void * value_p,
@@ -317,6 +317,9 @@ class EMSdevice {
// device flags: The lower 4 bits hold the unique identifier, the upper 4 bits are used for specific flags
static constexpr uint8_t EMS_DEVICE_FLAG_NONE = 0;
// Controller
static constexpr uint8_t EMS_DEVICE_FLAG_IVT = 1;
// Boiler
static constexpr uint8_t EMS_DEVICE_FLAG_EMS = 1;
static constexpr uint8_t EMS_DEVICE_FLAG_EMSPLUS = 2;

View File

@@ -311,6 +311,7 @@ MAKE_PSTR_WORD(winter)
MAKE_PSTR_WORD(outdoor)
MAKE_PSTR_WORD(mpc)
MAKE_PSTR_WORD(room)
MAKE_PSTR_WORD(room_outdoor)
MAKE_PSTR_WORD(power)
MAKE_PSTR_WORD(constant)
MAKE_PSTR_WORD(simple)
@@ -381,9 +382,12 @@ MAKE_PSTR_LIST(enum_modetype4, F_(nofrost), F_(eco), F_(heat))
MAKE_PSTR_LIST(enum_modetype5, F_(off), F_(on))
MAKE_PSTR_LIST(enum_reducemode, F_(nofrost), F_(reduce), F_(room), F_(outdoor))
MAKE_PSTR_LIST(enum_reducemode1, F_(outdoor), F_(room), F_(reduce)) // RC310 values: 1-3
MAKE_PSTR_LIST(enum_nofrostmode, F_(off), F_(room), F_(outdoor))
MAKE_PSTR_LIST(enum_nofrostmode1, F_(room), F_(outdoor), F_(room_outdoor))
MAKE_PSTR_LIST(enum_controlmode, F_(off), F_(optimized), F_(simple), F_(mpc), F_(room), F_(power), F_(constant))
MAKE_PSTR_LIST(enum_controlmode1, F("weather-compensated"), F("outside-basepoint"), F("n/a"), F_(room)) // RC310 1-4
MAKE_PSTR_LIST(enum_controlmode2, F_(outdoor), F_(room))
// MAKE_PSTR_LIST(enum_controlmode3, F_(off), F_(room), F_(outdoor), F("room+outdoor"))
MAKE_PSTR_LIST(enum_control, F_(off), F_(rc20), F_(rc3x))
@@ -614,7 +618,7 @@ MAKE_PSTR_LIST(wwDailyHeating, F("wwdailyheating"), F("daily heating"))
MAKE_PSTR_LIST(wwDailyHeatTime, F("wwdailyheattime"), F("daily heating time"))
MAKE_PSTR_LIST(wwWhenModeOff, F("wwwhenmodeoff"), F("when thermostat mode off"))
// thermostat hc
MAKE_PSTR_LIST(climate, F("climate"))
MAKE_PSTR_LIST(climate, F("HA climate config creation")) // no full-name, hidden, only for creation
MAKE_PSTR_LIST(selRoomTemp, F("seltemp"), F("selected room temperature"))
MAKE_PSTR_LIST(roomTemp, F("currtemp"), F("current room temperature"))
MAKE_PSTR_LIST(mode, F("mode"), F("mode"))
@@ -662,9 +666,11 @@ MAKE_PSTR_LIST(reducetemp, F("reducetemp"), F("off/reduce switch temperature"))
MAKE_PSTR_LIST(vacreducetemp, F("vacreducetemp"), F("vacations off/reduce switch temperature"))
MAKE_PSTR_LIST(vacreducemode, F("vacreducemode"), F("vacations reduce mode"))
MAKE_PSTR_LIST(nofrostmode, F("nofrostmode"), F("nofrost mode"))
MAKE_PSTR_LIST(nofrostmode1, F("nofrostmode1"), F("nofrost mode")) // RC310
MAKE_PSTR_LIST(remotetemp, F("remotetemp"), F("room temperature from remote"))
MAKE_PSTR_LIST(reducehours, F("reducehours"), F("duration for nighttemp"))
MAKE_PSTR_LIST(reduceminutes, F("reduceminutes"), F("remaining time for nightmode"))
MAKE_PSTR_LIST(switchonoptimization, F("switchonoptimization"), F("switch-on optimization"))
// heatpump
MAKE_PSTR_LIST(airHumidity, F("airhumidity"), F("relative air humidity"))

View File

@@ -418,7 +418,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// emsdevice->generate_values_web(root);
JsonArray output = doc.to<JsonArray>();
emsdevice->generate_values_web_all(output);
emsdevice->generate_values_web_customization(output);
Serial.print(COLOR_BRIGHT_MAGENTA);
serializeJson(doc, Serial);

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.4.1b0idf4"
#define EMSESP_APP_VERSION "3.4.2b1"

View File

@@ -132,6 +132,7 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject & input) {
JsonVariant data = output["api_data"];
request->send(200, "text/plain; charset=utf-8", data.as<String>());
api_count_++;
delete response;
return;
}

View File

@@ -196,7 +196,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request, J
if (emsdevice->unique_id() == json["id"]) {
#ifndef EMSESP_STANDALONE
JsonArray output = response->getRoot();
emsdevice->generate_values_web_all(output);
emsdevice->generate_values_web_customization(output);
#endif
response->setLength();
request->send(response);