mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-01-29 01:59:08 +03:00
Merge and change uart timer modes to pause between bytes (5..50)
This commit is contained in:
72
.travis.yml
Normal file
72
.travis.yml
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
os: linux
|
||||||
|
dist: bionic
|
||||||
|
language: python
|
||||||
|
python:
|
||||||
|
- "3.8"
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- ${HOME}/.pio
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- BUILDER_TOTAL_THREADS=1
|
||||||
|
- OWNER=${TRAVIS_REPO_SLUG%/*}
|
||||||
|
- DEV=${OWNER/proddy/v2}
|
||||||
|
- BRANCH=${TRAVIS_BRANCH/v2/}
|
||||||
|
- TAG=${DEV}${BRANCH:+_}${BRANCH}
|
||||||
|
|
||||||
|
install:
|
||||||
|
- env | grep TRAVIS
|
||||||
|
- set -e
|
||||||
|
- pip install -U platformio
|
||||||
|
- pio platform update -p
|
||||||
|
- set +e
|
||||||
|
|
||||||
|
branches:
|
||||||
|
except:
|
||||||
|
- /^travis-.*-build$/
|
||||||
|
|
||||||
|
script:
|
||||||
|
- ./scripts/build.sh
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- name: Release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- stage: Release
|
||||||
|
|
||||||
|
before_deploy:
|
||||||
|
- export FIRMWARE_VERSION=$(grep -E '^#define EMSESP_APP_VERSION' ./src/version.h | awk '{print $3}' | sed 's/"//g')
|
||||||
|
- git tag -f travis-${TAG}-build
|
||||||
|
- git remote add gh
|
||||||
|
https://${OWNER}:${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git
|
||||||
|
- git push gh :travis-${TAG}-build || true
|
||||||
|
- git push -f gh travis-${TAG}-build
|
||||||
|
- git remote remove gh
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
edge:
|
||||||
|
branch: master
|
||||||
|
token: ${GITHUB_TOKEN}
|
||||||
|
file_glob: true
|
||||||
|
file: "*.bin"
|
||||||
|
name: latest v2 development builds
|
||||||
|
release_notes:
|
||||||
|
Version $FIRMWARE_VERSION.
|
||||||
|
Automatic firmware builds of the current EMS-ESP branch built on $(date +'%F %T %Z') from commit $TRAVIS_COMMIT.
|
||||||
|
Warning, this is a development build and not fully tested. Use at your own risk.
|
||||||
|
cleanup: false
|
||||||
|
prerelease: true
|
||||||
|
overwrite: true
|
||||||
|
target_commitish: $TRAVIS_COMMIT
|
||||||
|
on:
|
||||||
|
tags: false
|
||||||
|
branch: v2
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
on_success: change
|
||||||
|
on_failure: change
|
||||||
16
README.md
16
README.md
@@ -35,14 +35,14 @@ Note: Version 2.0 is not backward compatible with v1.0. The File system structur
|
|||||||
|
|
||||||
### Uploading the firmware
|
### Uploading the firmware
|
||||||
|
|
||||||
- If you don't have Python 3.8, install it (https://www.python.org/downloads/)
|
- If you don't have Python 3.8:
|
||||||
#### Using direct to USB:
|
- first install it (https://www.python.org/downloads/)
|
||||||
- install `esptool` using the command `pip install esptool`
|
- install `esptool` using the command `pip install esptool`
|
||||||
- connect an ESP8266 to the USB. Figure out which COM port it's on (e.g. windows device manager)
|
- also for OTA updates later, download `espota` from https://github.com/esp8266/Arduino/blob/master/tools/espota.py
|
||||||
- `esptool.py -p COM6 -b 921600 write_flash 0x00000 <firmware.bin>`
|
|
||||||
#### Using OTA (Over The Air):
|
- Grab the firmware binary from https://github.com/proddy/EMS-ESP/releases/tag/travis-v2-build
|
||||||
- download `espota` from https://github.com/esp8266/Arduino/blob/master/tools/espota.py
|
- Using direct to USB: `esptool.py -p <COM PORT> -b 921600 write_flash 0x00000 <firmware.bin>`
|
||||||
- `espota.py --debug --progress --port 8266 --auth neo -i <ip address> -f <firmware.bin>`
|
- Using OTA (Over The Air): `espota.py --debug --progress --port 8266 --auth neo -i <ip address> -f <firmware.bin>`
|
||||||
|
|
||||||
### Setting up for the first time:
|
### Setting up for the first time:
|
||||||
|
|
||||||
|
|||||||
169
scripts/build.sh
Executable file
169
scripts/build.sh
Executable file
@@ -0,0 +1,169 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
### Functions
|
||||||
|
|
||||||
|
is_git() {
|
||||||
|
command -v git >/dev/null 2>&1 || return 1
|
||||||
|
command git rev-parse >/dev/null 2>&1 || return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_bytes() {
|
||||||
|
filesize=`du -k "$1" | cut -f1;`
|
||||||
|
echo 'size:' $filesize 'bytes'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Available environments
|
||||||
|
list_envs() {
|
||||||
|
grep env: platformio.ini | sed 's/\[env:\(.*\)\]/\1/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
print_available() {
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Available environments:"
|
||||||
|
for environment in $available; do
|
||||||
|
echo "-> $environment"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
print_environments() {
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Current environments:"
|
||||||
|
for environment in $environments; do
|
||||||
|
echo "-> $environment"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
set_default_environments() {
|
||||||
|
# Hook to build in parallel when using travis
|
||||||
|
if [[ "${TRAVIS_BUILD_STAGE_NAME}" = "Release" ]] && ${par_build}; then
|
||||||
|
environments=$(echo ${available} | \
|
||||||
|
awk -v par_thread=${par_thread} -v par_total_threads=${par_total_threads} \
|
||||||
|
'{ for (i = 1; i <= NF; i++) if (++j % par_total_threads == par_thread ) print $i; }')
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Only build travis target
|
||||||
|
if [[ "${TRAVIS_BUILD_STAGE_NAME}" = "Test" ]]; then
|
||||||
|
environments=$travis
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fallback to all available environments
|
||||||
|
environments=$available
|
||||||
|
}
|
||||||
|
|
||||||
|
build_environments() {
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "Building firmware images..."
|
||||||
|
# don't move to firmware folder until Travis fixed (see https://github.com/travis-ci/dpl/issues/846#issuecomment-547157406)
|
||||||
|
# mkdir -p $destination
|
||||||
|
|
||||||
|
for environment in $environments; do
|
||||||
|
echo "* EMS-ESP-$version-$environment.bin"
|
||||||
|
platformio run --silent --environment $environment || exit 1
|
||||||
|
stat_bytes .pio/build/$environment/firmware.bin
|
||||||
|
# mv .pio/build/$environment/firmware.bin $destination/EMS-ESP-$version-$environment.bin
|
||||||
|
# mv .pio/build/$environment/firmware.bin EMS-ESP-$version-$environment.bin
|
||||||
|
mv .pio/build/$environment/firmware.bin EMS-ESP-dev-$environment.bin
|
||||||
|
done
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
####### MAIN
|
||||||
|
|
||||||
|
destination=firmware
|
||||||
|
version_file=./src/version.h
|
||||||
|
version=$(grep -E '^#define EMSESP_APP_VERSION' $version_file | awk '{print $3}' | sed 's/"//g')
|
||||||
|
|
||||||
|
if ${TRAVIS:-false}; then
|
||||||
|
git_revision=${TRAVIS_COMMIT::7}
|
||||||
|
git_tag=${TRAVIS_TAG}
|
||||||
|
elif is_git; then
|
||||||
|
git_revision=$(git rev-parse --short HEAD)
|
||||||
|
git_tag=$(git tag --contains HEAD)
|
||||||
|
else
|
||||||
|
git_revision=unknown
|
||||||
|
git_tag=
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $git_tag
|
||||||
|
|
||||||
|
if [[ -n $git_tag ]]; then
|
||||||
|
new_version=${version/-*}
|
||||||
|
sed -i -e "s@$version@$new_version@" $version_file
|
||||||
|
version=$new_version
|
||||||
|
trap "git checkout -- $version_file" EXIT
|
||||||
|
fi
|
||||||
|
|
||||||
|
par_build=false
|
||||||
|
par_thread=${BUILDER_THREAD:-0}
|
||||||
|
par_total_threads=${BUILDER_TOTAL_THREADS:-4}
|
||||||
|
if [ ${par_thread} -ne ${par_thread} -o \
|
||||||
|
${par_total_threads} -ne ${par_total_threads} ]; then
|
||||||
|
echo "Parallel threads should be a number."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
if [ ${par_thread} -ge ${par_total_threads} ]; then
|
||||||
|
echo "Current thread is greater than total threads. Doesn't make sense"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# travis platformio target is used for nightly Test
|
||||||
|
travis=$(list_envs | grep travis | sort)
|
||||||
|
|
||||||
|
# get all taregts, excluding travis and debug
|
||||||
|
available=$(list_envs | grep -Ev -- 'travis|debug|release' | sort)
|
||||||
|
|
||||||
|
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS}"
|
||||||
|
|
||||||
|
# get command line Parameters
|
||||||
|
# l prints environments
|
||||||
|
# 2 does parallel builds
|
||||||
|
# d uses next arg as destination folder
|
||||||
|
while getopts "lpd:" opt; do
|
||||||
|
case $opt in
|
||||||
|
l)
|
||||||
|
print_available
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
par_build=true
|
||||||
|
;;
|
||||||
|
d)
|
||||||
|
destination=$OPTARG
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
shift $((OPTIND-1))
|
||||||
|
|
||||||
|
# Welcome message
|
||||||
|
echo "--------------------------------------------------------------"
|
||||||
|
echo "EMS-ESP FIRMWARE BUILDER"
|
||||||
|
echo "Building for version ${version}" ${git_revision:+($git_revision)}
|
||||||
|
|
||||||
|
# Environments to build
|
||||||
|
environments=$@
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
set_default_environments
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ${CI:-false}; then
|
||||||
|
print_environments
|
||||||
|
fi
|
||||||
|
|
||||||
|
# for debugging
|
||||||
|
echo "* git_revision = $git_revision"
|
||||||
|
echo "* git_tag = $git_tag"
|
||||||
|
echo "* TRAVIS_COMMIT = $TRAVIS_COMMIT"
|
||||||
|
echo "* TRAVIS_TAG = $TRAVIS_TAG"
|
||||||
|
echo "* TRAVIS_BRANCH = $TRAVIS_BRANCH"
|
||||||
|
echo "* TRAVIS_BUILD_STAGE_NAME = $TRAVIS_BUILD_STAGE_NAME"
|
||||||
|
|
||||||
|
build_environments
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
{207, DeviceType::CONTROLLER, F("Sense II/CS200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x10
|
{207, DeviceType::CONTROLLER, F("Sense II/CS200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x10
|
||||||
{209, DeviceType::CONTROLLER, F("ErP"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
{209, DeviceType::CONTROLLER, F("ErP"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||||
{218, DeviceType::CONTROLLER, F("M200/RFM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50
|
{218, DeviceType::CONTROLLER, F("M200/RFM200"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x50
|
||||||
{224, DeviceType::CONTROLLER, F("Bosch 9000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
{224, DeviceType::CONTROLLER, F("9000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||||
{230, DeviceType::CONTROLLER, F("BC Base"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
{230, DeviceType::CONTROLLER, F("BC Base"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||||
{241, DeviceType::CONTROLLER, F("Condens 5000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
{241, DeviceType::CONTROLLER, F("Condens 5000i"), DeviceFlags::EMS_DEVICE_FLAG_NONE}, // 0x09
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Mixing::Mixing(uint8_t device_type, uint8_t device_id, uint8_t product_id, const
|
|||||||
LOG_DEBUG(F("Registering new Mixing module with device ID 0x%02X"), device_id);
|
LOG_DEBUG(F("Registering new Mixing module with device ID 0x%02X"), device_id);
|
||||||
|
|
||||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||||
if (device_id < 0x28) {
|
if (device_id <= 0x27) {
|
||||||
// telegram handlers 0x20 - 0x27 for HC
|
// telegram handlers 0x20 - 0x27 for HC
|
||||||
register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), true, std::bind(&Mixing::process_MMPLUSStatusMessage_HC, this, _1));
|
register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), true, std::bind(&Mixing::process_MMPLUSStatusMessage_HC, this, _1));
|
||||||
} else {
|
} else {
|
||||||
@@ -126,7 +126,9 @@ void Mixing::publish_values() {
|
|||||||
Mqtt::publish(topic, doc);
|
Mqtt::publish(topic, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// heating circuits 0x02D7, 0x02D8 etc...
|
// heating circuits 0x02D7, 0x02D8 etc...
|
||||||
|
// e.g. A0 00 FF 00 01 D7 00 00 00 80 00 00 00 00 03 C5
|
||||||
|
// A0 0B FF 00 01 D7 00 00 00 80 00 00 00 00 03 80
|
||||||
void Mixing::process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram) {
|
void Mixing::process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram) {
|
||||||
type_ = Type::HC;
|
type_ = Type::HC;
|
||||||
hc_ = telegram->type_id - 0x02D7 + 1; // determine which circuit this is
|
hc_ = telegram->type_id - 0x02D7 + 1; // determine which circuit this is
|
||||||
@@ -172,6 +174,7 @@ void Mixing::process_MMConfigMessage(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// pos 0: active FF = on
|
// pos 0: active FF = on
|
||||||
// pos 1: valve runtime 0C = 120 sec in units of 10 sec
|
// pos 1: valve runtime 0C = 120 sec in units of 10 sec
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mixing on a MM10 - 0xAC
|
// Mixing on a MM10 - 0xAC
|
||||||
// e.g. Thermostat -> Mixing Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB
|
// e.g. Thermostat -> Mixing Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB
|
||||||
void Mixing::process_MMSetMessage(std::shared_ptr<const Telegram> telegram) {
|
void Mixing::process_MMSetMessage(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
|||||||
// telegram handlers
|
// telegram handlers
|
||||||
register_telegram_type(0x0097, F("SM10Monitor"), true, std::bind(&Solar::process_SM10Monitor, this, _1));
|
register_telegram_type(0x0097, F("SM10Monitor"), true, std::bind(&Solar::process_SM10Monitor, this, _1));
|
||||||
register_telegram_type(0x0362, F("SM100Monitor"), true, std::bind(&Solar::process_SM100Monitor, this, _1));
|
register_telegram_type(0x0362, F("SM100Monitor"), true, std::bind(&Solar::process_SM100Monitor, this, _1));
|
||||||
|
register_telegram_type(0x0363, F("SM100Monitor2"), true, std::bind(&Solar::process_SM100Monitor2, this, _1));
|
||||||
|
register_telegram_type(0x0366, F("SM100Config"), true, std::bind(&Solar::process_SM100Config, this, _1));
|
||||||
|
|
||||||
register_telegram_type(0x0364, F("SM100Status"), false, std::bind(&Solar::process_SM100Status, this, _1));
|
register_telegram_type(0x0364, F("SM100Status"), false, std::bind(&Solar::process_SM100Status, this, _1));
|
||||||
register_telegram_type(0x036A, F("SM100Status2"), false, std::bind(&Solar::process_SM100Status2, this, _1));
|
register_telegram_type(0x036A, F("SM100Status2"), false, std::bind(&Solar::process_SM100Status2, this, _1));
|
||||||
register_telegram_type(0x038E, F("SM100Energy"), true, std::bind(&Solar::process_SM100Energy, this, _1));
|
register_telegram_type(0x038E, F("SM100Energy"), true, std::bind(&Solar::process_SM100Energy, this, _1));
|
||||||
@@ -134,7 +137,7 @@ void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SM100Monitor - type 0x0262 EMS+ - for SM100 and SM200
|
* SM100Monitor - type 0x0362 EMS+ - for SM100 and SM200
|
||||||
* e.g. B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80
|
* e.g. B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80
|
||||||
* e.g, 30 00 FF 00 02 62 01 AC
|
* e.g, 30 00 FF 00 02 62 01 AC
|
||||||
* 30 00 FF 18 02 62 80 00
|
* 30 00 FF 18 02 62 80 00
|
||||||
@@ -149,8 +152,27 @@ void Solar::process_SM100Monitor(std::shared_ptr<const Telegram> telegram) {
|
|||||||
telegram->read_value(bottomTemp2_, 16); // is *10
|
telegram->read_value(bottomTemp2_, 16); // is *10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
|
||||||
|
// SM100Monitor2 - 0x0363
|
||||||
|
// e.g. B0 00 FF 00 02 63 80 00 80 00 00 00 80 00 80 00 80 00 00 80 00 5A
|
||||||
|
void Solar::process_SM100Monitor2(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) {
|
||||||
|
telegram->read_value(availabilityFlag_, 0);
|
||||||
|
telegram->read_value(configFlag_, 1);
|
||||||
|
telegram->read_value(userFlag_, 2);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SM100Status - type 0x0264 EMS+ for pump modulation - for SM100 and SM200
|
* SM100Status - type 0x0364 EMS+ for pump modulation - for SM100 and SM200
|
||||||
* e.g. 30 00 FF 09 02 64 64 = 100%
|
* e.g. 30 00 FF 09 02 64 64 = 100%
|
||||||
* 30 00 FF 09 02 64 1E = 30%
|
* 30 00 FF 09 02 64 1E = 30%
|
||||||
*/
|
*/
|
||||||
@@ -159,7 +181,7 @@ void Solar::process_SM100Status(std::shared_ptr<const Telegram> telegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SM100Status2 - type 0x026A EMS+ for pump on/off at offset 0x0A - for SM100 and SM200
|
* SM100Status2 - type 0x036A EMS+ for pump on/off at offset 0x0A - for SM100 and SM200
|
||||||
* e.g. B0 00 FF 00 02 6A 03 03 03 03 01 03 03 03 03 03 01 03
|
* e.g. B0 00 FF 00 02 6A 03 03 03 03 01 03 03 03 03 03 01 03
|
||||||
* byte 4 = VS2 3-way valve for cylinder 2 : test=01, on=04 and off=03
|
* byte 4 = VS2 3-way valve for cylinder 2 : test=01, on=04 and off=03
|
||||||
* byte 10 = PS1 Solar circuit pump for collector array 1: test=01, on=04 and off=03
|
* byte 10 = PS1 Solar circuit pump for collector array 1: test=01, on=04 and off=03
|
||||||
@@ -170,7 +192,7 @@ void Solar::process_SM100Status2(std::shared_ptr<const Telegram> telegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SM100Energy - type 0x028E EMS+ for energy readings
|
* SM100Energy - type 0x038E EMS+ for energy readings
|
||||||
* e.g. 30 00 FF 00 02 8E 00 00 00 00 00 00 06 C5 00 00 76 35
|
* e.g. 30 00 FF 00 02 8E 00 00 00 00 00 00 06 C5 00 00 76 35
|
||||||
*/
|
*/
|
||||||
void Solar::process_SM100Energy(std::shared_ptr<const Telegram> telegram) {
|
void Solar::process_SM100Energy(std::shared_ptr<const Telegram> telegram) {
|
||||||
@@ -180,7 +202,7 @@ void Solar::process_SM100Energy(std::shared_ptr<const Telegram> telegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Junkers ISM1 Solar Module - type 0x0003 EMS+ for energy readings
|
* Junkers ISM1 Solar Module - type 0x0103 EMS+ for energy readings
|
||||||
* e.g. B0 00 FF 00 00 03 32 00 00 00 00 13 00 D6 00 00 00 FB D0 F0
|
* e.g. B0 00 FF 00 00 03 32 00 00 00 00 13 00 D6 00 00 00 FB D0 F0
|
||||||
*/
|
*/
|
||||||
void Solar::process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram) {
|
void Solar::process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||||
@@ -192,11 +214,11 @@ void Solar::process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Junkers ISM1 Solar Module - type 0x0001 EMS+ for setting values
|
* Junkers ISM1 Solar Module - type 0x0101 EMS+ for setting values
|
||||||
* e.g. 90 30 FF 06 00 01 50
|
* e.g. 90 30 FF 06 00 01 50
|
||||||
*/
|
*/
|
||||||
void Solar::process_ISM1Set(std::shared_ptr<const Telegram> telegram) {
|
void Solar::process_ISM1Set(std::shared_ptr<const Telegram> telegram) {
|
||||||
telegram->read_value(setpoint_maxBottomTemp_, 6);
|
telegram->read_value(setpoint_maxBottomTemp_, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -58,11 +58,20 @@ class Solar : public EMSdevice {
|
|||||||
uint32_t energyTotal_ = EMS_VALUE_ULONG_NOTSET;
|
uint32_t energyTotal_ = EMS_VALUE_ULONG_NOTSET;
|
||||||
uint32_t pumpWorkMin_ = EMS_VALUE_ULONG_NOTSET; // Total solar pump operating time
|
uint32_t pumpWorkMin_ = EMS_VALUE_ULONG_NOTSET; // Total solar pump operating time
|
||||||
|
|
||||||
|
uint8_t availabilityFlag_ = EMS_VALUE_BOOL_NOTSET;
|
||||||
|
uint8_t configFlag_ = EMS_VALUE_BOOL_NOTSET;
|
||||||
|
uint8_t userFlag_ = EMS_VALUE_BOOL_NOTSET;
|
||||||
|
|
||||||
void process_SM10Monitor(std::shared_ptr<const Telegram> telegram);
|
void process_SM10Monitor(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_SM100Monitor(std::shared_ptr<const Telegram> telegram);
|
void process_SM100Monitor(std::shared_ptr<const Telegram> telegram);
|
||||||
|
void process_SM100Monitor2(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
|
void process_SM100Config(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
void process_SM100Status(std::shared_ptr<const Telegram> telegram);
|
void process_SM100Status(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_SM100Status2(std::shared_ptr<const Telegram> telegram);
|
void process_SM100Status2(std::shared_ptr<const Telegram> telegram);
|
||||||
void process_SM100Energy(std::shared_ptr<const Telegram> telegram);
|
void process_SM100Energy(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
void process_ISM1StatusMessage(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_ISM1Set(std::shared_ptr<const Telegram> telegram);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i
|
|||||||
register_telegram_type(monitor_typeids[i], F("RC300Monitor"), false, std::bind(&Thermostat::process_RC300Monitor, this, _1));
|
register_telegram_type(monitor_typeids[i], F("RC300Monitor"), false, std::bind(&Thermostat::process_RC300Monitor, this, _1));
|
||||||
register_telegram_type(set_typeids[i], F("RC300Set"), false, std::bind(&Thermostat::process_RC300Set, this, _1));
|
register_telegram_type(set_typeids[i], F("RC300Set"), false, std::bind(&Thermostat::process_RC300Set, this, _1));
|
||||||
}
|
}
|
||||||
|
register_telegram_type(0x31D, F("RC300WWmode"), false, std::bind(&Thermostat::process_RC300WWmode, this, _1));
|
||||||
|
register_telegram_type(0x31E, F("RC300WWmode"), false, std::bind(&Thermostat::process_RC300WWmode, this, _1));
|
||||||
|
|
||||||
// JUNKERS/HT3
|
// JUNKERS/HT3
|
||||||
} else if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
} else if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||||
@@ -462,27 +464,27 @@ void Thermostat::publish_values() {
|
|||||||
if (datetime_.size()) {
|
if (datetime_.size()) {
|
||||||
rootThermostat["time"] = datetime_.c_str();
|
rootThermostat["time"] = datetime_.c_str();
|
||||||
}
|
}
|
||||||
if (dampedoutdoortemp != EMS_VALUE_INT_NOTSET) {
|
if (dampedoutdoortemp_ != EMS_VALUE_INT_NOTSET) {
|
||||||
rootThermostat["dampedtemp"] = dampedoutdoortemp;
|
rootThermostat["dampedtemp"] = dampedoutdoortemp_;
|
||||||
}
|
}
|
||||||
if (tempsensor1 != EMS_VALUE_USHORT_NOTSET) {
|
if (tempsensor1_ != EMS_VALUE_USHORT_NOTSET) {
|
||||||
rootThermostat["inttemp1"] = (float)tempsensor1 / 10;
|
rootThermostat["inttemp1"] = (float)tempsensor1_ / 10;
|
||||||
}
|
}
|
||||||
if (tempsensor2 != EMS_VALUE_USHORT_NOTSET) {
|
if (tempsensor2_ != EMS_VALUE_USHORT_NOTSET) {
|
||||||
rootThermostat["inttemp2"] = (float)tempsensor2 / 10;
|
rootThermostat["inttemp2"] = (float)tempsensor2_ / 10;
|
||||||
}
|
}
|
||||||
if (ibaCalIntTemperature != EMS_VALUE_INT_NOTSET) {
|
if (ibaCalIntTemperature_ != EMS_VALUE_INT_NOTSET) {
|
||||||
rootThermostat["intoffset"] = (float)ibaCalIntTemperature / 2;
|
rootThermostat["intoffset"] = (float)ibaCalIntTemperature_ / 2;
|
||||||
}
|
}
|
||||||
if (ibaMinExtTemperature != EMS_VALUE_INT_NOTSET) {
|
if (ibaMinExtTemperature_ != EMS_VALUE_INT_NOTSET) {
|
||||||
rootThermostat["minexttemp"] = (float)ibaMinExtTemperature; // min ext temp for heating curve, in deg.
|
rootThermostat["minexttemp"] = (float)ibaMinExtTemperature_; // min ext temp for heating curve, in deg.
|
||||||
}
|
}
|
||||||
if (ibaBuildingType != EMS_VALUE_UINT_NOTSET) {
|
if (ibaBuildingType_ != EMS_VALUE_UINT_NOTSET) {
|
||||||
if (ibaBuildingType == 0) {
|
if (ibaBuildingType_ == 0) {
|
||||||
rootThermostat["building"] = "light";
|
rootThermostat["building"] = "light";
|
||||||
} else if (ibaBuildingType == 1) {
|
} else if (ibaBuildingType_ == 1) {
|
||||||
rootThermostat["building"] = "medium";
|
rootThermostat["building"] = "medium";
|
||||||
} else if (ibaBuildingType == 2) {
|
} else if (ibaBuildingType_ == 2) {
|
||||||
rootThermostat["building"] = "heavy";
|
rootThermostat["building"] = "heavy";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -809,67 +811,67 @@ void Thermostat::show_values(uuid::console::Shell & shell) {
|
|||||||
|
|
||||||
if (datetime_.size()) {
|
if (datetime_.size()) {
|
||||||
shell.printfln(F(" Clock: %s"), datetime_.c_str());
|
shell.printfln(F(" Clock: %s"), datetime_.c_str());
|
||||||
if (ibaClockOffset != EMS_VALUE_UINT_NOTSET && flags == EMS_DEVICE_FLAG_RC30_1) {
|
if (ibaClockOffset_ != EMS_VALUE_UINT_NOTSET && flags == EMS_DEVICE_FLAG_RC30_1) {
|
||||||
print_value(shell, 2, F("Offset clock"), Helpers::render_value(buffer, ibaClockOffset, 1)); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
print_value(shell, 2, F("Offset clock"), Helpers::render_value(buffer, ibaClockOffset_, 1)); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags == EMS_DEVICE_FLAG_RC35) {
|
if (flags == EMS_DEVICE_FLAG_RC35) {
|
||||||
print_value(shell, 2, F("Damped Outdoor temperature"), F_(degrees), Helpers::render_value(buffer, dampedoutdoortemp, 1));
|
print_value(shell, 2, F("Damped Outdoor temperature"), F_(degrees), Helpers::render_value(buffer, dampedoutdoortemp_, 1));
|
||||||
print_value(shell, 2, F("Temp sensor 1"), F_(degrees), Helpers::render_value(buffer, tempsensor1, 10));
|
print_value(shell, 2, F("Temp sensor 1"), F_(degrees), Helpers::render_value(buffer, tempsensor1_, 10));
|
||||||
print_value(shell, 2, F("Temp sensor 2"), F_(degrees), Helpers::render_value(buffer, tempsensor2, 10));
|
print_value(shell, 2, F("Temp sensor 2"), F_(degrees), Helpers::render_value(buffer, tempsensor2_, 10));
|
||||||
}
|
}
|
||||||
if (flags == EMS_DEVICE_FLAG_RC30_1) {
|
if (flags == EMS_DEVICE_FLAG_RC30_1) {
|
||||||
// settings parameters
|
// settings parameters
|
||||||
if (ibaMainDisplay != EMS_VALUE_UINT_NOTSET) {
|
if (ibaMainDisplay_ != EMS_VALUE_UINT_NOTSET) {
|
||||||
if (ibaMainDisplay == 0) {
|
if (ibaMainDisplay_ == 0) {
|
||||||
shell.printfln(F(" Display: internal temperature"));
|
shell.printfln(F(" Display: internal temperature"));
|
||||||
} else if (ibaMainDisplay == 1) {
|
} else if (ibaMainDisplay_ == 1) {
|
||||||
shell.printfln(F(" Display: internal setpoint"));
|
shell.printfln(F(" Display: internal setpoint"));
|
||||||
} else if (ibaMainDisplay == 2) {
|
} else if (ibaMainDisplay_ == 2) {
|
||||||
shell.printfln(F(" Display: external temperature"));
|
shell.printfln(F(" Display: external temperature"));
|
||||||
} else if (ibaMainDisplay == 3) {
|
} else if (ibaMainDisplay_ == 3) {
|
||||||
shell.printfln(F(" Display: burner temperature"));
|
shell.printfln(F(" Display: burner temperature"));
|
||||||
} else if (ibaMainDisplay == 4) {
|
} else if (ibaMainDisplay_ == 4) {
|
||||||
shell.printfln(F(" Display: WW temperature"));
|
shell.printfln(F(" Display: WW temperature"));
|
||||||
} else if (ibaMainDisplay == 5) {
|
} else if (ibaMainDisplay_ == 5) {
|
||||||
shell.printfln(F(" Display: functioning mode"));
|
shell.printfln(F(" Display: functioning mode"));
|
||||||
} else if (ibaMainDisplay == 6) {
|
} else if (ibaMainDisplay_ == 6) {
|
||||||
shell.printfln(F(" Display: time"));
|
shell.printfln(F(" Display: time"));
|
||||||
} else if (ibaMainDisplay == 7) {
|
} else if (ibaMainDisplay_ == 7) {
|
||||||
shell.printfln(F(" Display: date"));
|
shell.printfln(F(" Display: date"));
|
||||||
} else if (ibaMainDisplay == 9) {
|
} else if (ibaMainDisplay_ == 9) {
|
||||||
shell.printfln(F(" Display: smoke temperature"));
|
shell.printfln(F(" Display: smoke temperature"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibaLanguage != EMS_VALUE_UINT_NOTSET) {
|
if (ibaLanguage_ != EMS_VALUE_UINT_NOTSET) {
|
||||||
if (ibaLanguage == 0) {
|
if (ibaLanguage_ == 0) {
|
||||||
shell.printfln(F(" Language: German"));
|
shell.printfln(F(" Language: German"));
|
||||||
} else if (ibaLanguage == 1) {
|
} else if (ibaLanguage_ == 1) {
|
||||||
shell.printfln(F(" Language: Dutch"));
|
shell.printfln(F(" Language: Dutch"));
|
||||||
} else if (ibaLanguage == 2) {
|
} else if (ibaLanguage_ == 2) {
|
||||||
shell.printfln(F(" Language: French"));
|
shell.printfln(F(" Language: French"));
|
||||||
} else if (ibaLanguage == 3) {
|
} else if (ibaLanguage_ == 3) {
|
||||||
shell.printfln(F(" Language: Italian"));
|
shell.printfln(F(" Language: Italian"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) {
|
if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) {
|
||||||
if (ibaCalIntTemperature != EMS_VALUE_INT_NOTSET) {
|
if (ibaCalIntTemperature_ != EMS_VALUE_INT_NOTSET) {
|
||||||
print_value(shell, 2, F("Offset int. temperature"), F_(degrees), Helpers::render_value(buffer, ibaCalIntTemperature, 2));
|
print_value(shell, 2, F("Offset int. temperature"), F_(degrees), Helpers::render_value(buffer, ibaCalIntTemperature_, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibaMinExtTemperature != EMS_VALUE_INT_NOTSET) {
|
if (ibaMinExtTemperature_ != EMS_VALUE_INT_NOTSET) {
|
||||||
print_value(shell, 2, F("Min ext. temperature"), F_(degrees), Helpers::render_value(buffer, ibaMinExtTemperature, 0)); // min ext temp for heating curve, in deg.
|
print_value(shell, 2, F("Min ext. temperature"), F_(degrees), Helpers::render_value(buffer, ibaMinExtTemperature_, 0)); // min ext temp for heating curve, in deg.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibaBuildingType != EMS_VALUE_UINT_NOTSET) {
|
if (ibaBuildingType_ != EMS_VALUE_UINT_NOTSET) {
|
||||||
if (ibaBuildingType == 0) {
|
if (ibaBuildingType_ == 0) {
|
||||||
shell.printfln(F(" Building: light"));
|
shell.printfln(F(" Building: light"));
|
||||||
} else if (ibaBuildingType == 1) {
|
} else if (ibaBuildingType_ == 1) {
|
||||||
shell.printfln(F(" Building: medium"));
|
shell.printfln(F(" Building: medium"));
|
||||||
} else if (ibaBuildingType == 2) {
|
} else if (ibaBuildingType_ == 2) {
|
||||||
shell.printfln(F(" Building: heavy"));
|
shell.printfln(F(" Building: heavy"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -976,9 +978,9 @@ void Thermostat::process_JunkersSet(std::shared_ptr<const Telegram> telegram) {
|
|||||||
|
|
||||||
// type 0xA3 - for external temp settings from the the RC* thermostats (e.g. RC35)
|
// type 0xA3 - for external temp settings from the the RC* thermostats (e.g. RC35)
|
||||||
void Thermostat::process_RCOutdoorTemp(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RCOutdoorTemp(std::shared_ptr<const Telegram> telegram) {
|
||||||
telegram->read_value(dampedoutdoortemp, 0);
|
telegram->read_value(dampedoutdoortemp_, 0);
|
||||||
telegram->read_value(tempsensor1, 3); // sensor 1 - is * 10
|
telegram->read_value(tempsensor1_, 3); // sensor 1 - is * 10
|
||||||
telegram->read_value(tempsensor2, 5); // sensor 2 - is * 10
|
telegram->read_value(tempsensor2_, 5); // sensor 2 - is * 10
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x91 - data from the RC20 thermostat (0x17) - 15 bytes long
|
// 0x91 - data from the RC20 thermostat (0x17) - 15 bytes long
|
||||||
@@ -1000,13 +1002,13 @@ void Thermostat::process_EasyMonitor(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// Settings Parameters - 0xA5 - RC30_1
|
// Settings Parameters - 0xA5 - RC30_1
|
||||||
void Thermostat::process_IBASettings(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_IBASettings(std::shared_ptr<const Telegram> telegram) {
|
||||||
// 22 - display line on RC35
|
// 22 - display line on RC35
|
||||||
telegram->read_value(ibaMainDisplay,
|
telegram->read_value(ibaMainDisplay_,
|
||||||
0); // display on Thermostat: 0 int. temp, 1 int. setpoint, 2 ext. temp., 3 burner temp., 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
0); // display on Thermostat: 0 int. temp, 1 int. setpoint, 2 ext. temp., 3 burner temp., 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
||||||
telegram->read_value(ibaLanguage, 1); // language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian
|
telegram->read_value(ibaLanguage_, 1); // language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian
|
||||||
telegram->read_value(ibaCalIntTemperature, 2); // offset int. temperature sensor, by * 0.1 Kelvin
|
telegram->read_value(ibaCalIntTemperature_, 2); // offset int. temperature sensor, by * 0.1 Kelvin
|
||||||
telegram->read_value(ibaBuildingType, 6); // building type: 0 = light, 1 = medium, 2 = heavy
|
telegram->read_value(ibaBuildingType_, 6); // building type: 0 = light, 1 = medium, 2 = heavy
|
||||||
telegram->read_value(ibaMinExtTemperature, 5); // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1
|
telegram->read_value(ibaMinExtTemperature_, 5); // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1
|
||||||
telegram->read_value(ibaClockOffset, 12); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
telegram->read_value(ibaClockOffset_, 12); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||||
}
|
}
|
||||||
|
|
||||||
// type 0x6F - FR10/FR50/FR100 Junkers
|
// type 0x6F - FR10/FR50/FR100 Junkers
|
||||||
@@ -1053,6 +1055,16 @@ void Thermostat::process_RC300Set(std::shared_ptr<const Telegram> telegram) {
|
|||||||
telegram->read_value(hc->nighttemp, 4); // is * 2
|
telegram->read_value(hc->nighttemp, 4); // is * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// types 0x31D and 0x31E
|
||||||
|
void Thermostat::process_RC300WWmode(std::shared_ptr<const Telegram> telegram) {
|
||||||
|
// 0x31D for WW system 1, 0x31E for WW system 2
|
||||||
|
wwSystem_ = telegram->type_id - 0x31D + 1;
|
||||||
|
telegram->read_value(wwExtra_, 0); // 0=no, 1=yes
|
||||||
|
// pos 1 = holiday mode
|
||||||
|
// pos 2 = current status of DHW setpoint
|
||||||
|
// pos 3 = current status of DHW circulation pump
|
||||||
|
}
|
||||||
|
|
||||||
// type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long
|
// type 0x41 - data from the RC30 thermostat(0x10) - 14 bytes long
|
||||||
void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RC30Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||||
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
|
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
|
||||||
|
|||||||
@@ -113,17 +113,20 @@ class Thermostat : public EMSdevice {
|
|||||||
uint8_t mqtt_format_; // single, nested or ha
|
uint8_t mqtt_format_; // single, nested or ha
|
||||||
|
|
||||||
// Installation parameters
|
// Installation parameters
|
||||||
uint8_t ibaMainDisplay =
|
uint8_t ibaMainDisplay_ =
|
||||||
EMS_VALUE_UINT_NOTSET; // display on Thermostat: 0 int. temp, 1 int. setpoint, 2 ext. temp., 3 burner temp., 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
EMS_VALUE_UINT_NOTSET; // display on Thermostat: 0 int. temp, 1 int. setpoint, 2 ext. temp., 3 burner temp., 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
||||||
uint8_t ibaLanguage = EMS_VALUE_UINT_NOTSET; // language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian
|
uint8_t ibaLanguage_ = EMS_VALUE_UINT_NOTSET; // language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian
|
||||||
int8_t ibaCalIntTemperature = EMS_VALUE_INT_NOTSET; // offset int. temperature sensor, by * 0.1 Kelvin (-5.0 to 5.0K)
|
int8_t ibaCalIntTemperature_ = EMS_VALUE_INT_NOTSET; // offset int. temperature sensor, by * 0.1 Kelvin (-5.0 to 5.0K)
|
||||||
int8_t ibaMinExtTemperature = EMS_VALUE_INT_NOTSET; // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1
|
int8_t ibaMinExtTemperature_ = EMS_VALUE_INT_NOTSET; // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1
|
||||||
uint8_t ibaBuildingType = EMS_VALUE_UINT_NOTSET; // building type: 0 = light, 1 = medium, 2 = heavy
|
uint8_t ibaBuildingType_ = EMS_VALUE_UINT_NOTSET; // building type: 0 = light, 1 = medium, 2 = heavy
|
||||||
uint8_t ibaClockOffset = EMS_VALUE_UINT_NOTSET; // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
uint8_t ibaClockOffset_ = EMS_VALUE_UINT_NOTSET; // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
||||||
|
|
||||||
int8_t dampedoutdoortemp = EMS_VALUE_INT_NOTSET;
|
int8_t dampedoutdoortemp_ = EMS_VALUE_INT_NOTSET;
|
||||||
uint16_t tempsensor1 = EMS_VALUE_USHORT_NOTSET;
|
uint16_t tempsensor1_ = EMS_VALUE_USHORT_NOTSET;
|
||||||
uint16_t tempsensor2 = EMS_VALUE_USHORT_NOTSET;
|
uint16_t tempsensor2_ = EMS_VALUE_USHORT_NOTSET;
|
||||||
|
|
||||||
|
uint8_t wwSystem_ = EMS_VALUE_UINT_NOTSET;
|
||||||
|
uint8_t wwExtra_ = EMS_VALUE_UINT_NOTSET;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<HeatingCircuit>> heating_circuits_; // each thermostat can have multiple heating circuits
|
std::vector<std::shared_ptr<HeatingCircuit>> heating_circuits_; // each thermostat can have multiple heating circuits
|
||||||
|
|
||||||
@@ -193,7 +196,6 @@ class Thermostat : public EMSdevice {
|
|||||||
static constexpr uint8_t EMS_OFFSET_JunkersSetMessage2_eco_temp = 6;
|
static constexpr uint8_t EMS_OFFSET_JunkersSetMessage2_eco_temp = 6;
|
||||||
static constexpr uint8_t EMS_OFFSET_JunkersSetMessage3_heat = 7;
|
static constexpr uint8_t EMS_OFFSET_JunkersSetMessage3_heat = 7;
|
||||||
|
|
||||||
// static constexpr uint8_t DEFAULT_HEATING_CIRCUIT = 1; // default heating circuit is always 1
|
|
||||||
#define DEFAULT_HEATING_CIRCUIT 1
|
#define DEFAULT_HEATING_CIRCUIT 1
|
||||||
|
|
||||||
// Installation settings
|
// Installation settings
|
||||||
@@ -229,6 +231,8 @@ class Thermostat : public EMSdevice {
|
|||||||
|
|
||||||
void process_EasyMonitor(std::shared_ptr<const Telegram> telegram);
|
void process_EasyMonitor(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
|
void process_RC300WWmode(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|
||||||
// set functions
|
// set functions
|
||||||
void set_settings_minexttemp(const int8_t mt);
|
void set_settings_minexttemp(const int8_t mt);
|
||||||
void set_settings_calinttemp(const int8_t ct);
|
void set_settings_calinttemp(const int8_t ct);
|
||||||
|
|||||||
@@ -568,14 +568,15 @@ void EMSESP::send_write_request(const uint16_t type_id,
|
|||||||
// this is main entry point when data is received on the Rx line, via emsuart library
|
// this is main entry point when data is received on the Rx line, via emsuart library
|
||||||
// we check if its a complete telegram or just a single byte (which could be a poll or a return status)
|
// we check if its a complete telegram or just a single byte (which could be a poll or a return status)
|
||||||
void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
||||||
// LOG_DEBUG(F("Rx: %s"), Helpers::data_to_hex(data, length).c_str());
|
static uint32_t tx_time_ = 0;
|
||||||
// check first for echo
|
// check first for echo
|
||||||
uint8_t first_value = data[0];
|
uint8_t first_value = data[0];
|
||||||
if (((first_value & 0x7F) == txservice_.ems_bus_id()) && (length > 1)) {
|
if (((first_value & 0x7F) == txservice_.ems_bus_id()) && (length > 1)) {
|
||||||
// if we ask ourself at roomcontrol for version e.g. 0B 98 02 00 20
|
// if we ask ourself at roomcontrol for version e.g. 0B 98 02 00 20
|
||||||
Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data);
|
Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data);
|
||||||
#ifdef EMSESP_DEBUG
|
#ifdef EMSESP_DEBUG
|
||||||
LOG_DEBUG(F("[DEBUG] Echo: %s"), Helpers::data_to_hex(data, length).c_str());
|
// get_uptime is only updated once per loop, does not give the right time
|
||||||
|
LOG_DEBUG(F("[DEBUG] Echo after %d ms: %s"), ::millis() - tx_time_, Helpers::data_to_hex(data, length).c_str());
|
||||||
#endif
|
#endif
|
||||||
return; // it's an echo
|
return; // it's an echo
|
||||||
}
|
}
|
||||||
@@ -638,6 +639,7 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
|
|||||||
// if ht3 poll must be ems_bus_id else if Buderus poll must be (ems_bus_id | 0x80)
|
// if ht3 poll must be ems_bus_id else if Buderus poll must be (ems_bus_id | 0x80)
|
||||||
if ((first_value ^ 0x80 ^ rxservice_.ems_mask()) == txservice_.ems_bus_id()) {
|
if ((first_value ^ 0x80 ^ rxservice_.ems_mask()) == txservice_.ems_bus_id()) {
|
||||||
EMSbus::last_bus_activity(uuid::get_uptime()); // set the flag indication the EMS bus is active
|
EMSbus::last_bus_activity(uuid::get_uptime()); // set the flag indication the EMS bus is active
|
||||||
|
tx_time_ = ::millis(); // get_uptime is only updated once per loop, does not give the right time
|
||||||
txservice_.send();
|
txservice_.send();
|
||||||
}
|
}
|
||||||
// send remote room temperature if active
|
// send remote room temperature if active
|
||||||
@@ -731,7 +733,7 @@ void EMSESP::console_commands(Shell & shell, unsigned int context) {
|
|||||||
flash_string_vector{F_(n_mandatory)},
|
flash_string_vector{F_(n_mandatory)},
|
||||||
[](Shell & shell, const std::vector<std::string> & arguments) {
|
[](Shell & shell, const std::vector<std::string> & arguments) {
|
||||||
uint8_t tx_mode = std::strtol(arguments[0].c_str(), nullptr, 10);
|
uint8_t tx_mode = std::strtol(arguments[0].c_str(), nullptr, 10);
|
||||||
if ((tx_mode > 0) && (tx_mode <= 30)) {
|
if ((tx_mode > 0) && (tx_mode <= 50)) {
|
||||||
Settings settings;
|
Settings settings;
|
||||||
settings.ems_tx_mode(tx_mode);
|
settings.ems_tx_mode(tx_mode);
|
||||||
settings.commit();
|
settings.commit();
|
||||||
|
|||||||
@@ -206,7 +206,11 @@ void System::start() {
|
|||||||
settings.app_version(EMSESP_APP_VERSION);
|
settings.app_version(EMSESP_APP_VERSION);
|
||||||
settings.commit();
|
settings.commit();
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
|
LOG_INFO(F("System booted (EMS-ESP version %s ESP32)"), settings.app_version().c_str());
|
||||||
|
#else
|
||||||
LOG_INFO(F("System booted (EMS-ESP version %s)"), settings.app_version().c_str());
|
LOG_INFO(F("System booted (EMS-ESP version %s)"), settings.app_version().c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
if (LED_GPIO) {
|
if (LED_GPIO) {
|
||||||
pinMode(LED_GPIO, OUTPUT); // LED pin, 0 is disabled
|
pinMode(LED_GPIO, OUTPUT); // LED pin, 0 is disabled
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) {
|
|||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
Settings settings;
|
Settings settings;
|
||||||
if (settings.ems_tx_mode() <= 5) {
|
if (settings.ems_tx_mode() <= 4) {
|
||||||
#endif
|
#endif
|
||||||
// This logging causes errors with timer based tx-modes on esp8266!
|
// This logging causes errors with timer based tx-modes on esp8266!
|
||||||
LOG_DEBUG(F("Sending %s Tx [#%d], telegram: %s"),
|
LOG_DEBUG(F("Sending %s Tx [#%d], telegram: %s"),
|
||||||
|
|||||||
@@ -358,6 +358,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
EMSESP::add_device(0x28, 160, version, EMSdevice::Brand::BUDERUS); // MM100, WWC
|
EMSESP::add_device(0x28, 160, version, EMSdevice::Brand::BUDERUS); // MM100, WWC
|
||||||
EMSESP::add_device(0x29, 161, version, EMSdevice::Brand::BUDERUS); // MM200, WWC
|
EMSESP::add_device(0x29, 161, version, EMSdevice::Brand::BUDERUS); // MM200, WWC
|
||||||
|
|
||||||
|
EMSESP::add_device(0x20, 160, version, EMSdevice::Brand::BOSCH); // MM100
|
||||||
|
|
||||||
EMSESP::rxservice_.loop();
|
EMSESP::rxservice_.loop();
|
||||||
|
|
||||||
// WWC1 on 0x29
|
// WWC1 on 0x29
|
||||||
@@ -365,6 +367,9 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) {
|
|||||||
|
|
||||||
// WWC2 on 0x28
|
// WWC2 on 0x28
|
||||||
rx_telegram({0xA8, 0x00, 0xFF, 0x00, 0x02, 0x31, 0x02, 0x35, 0x00, 0x3C, 0x00, 0x3C, 0x3C, 0x46, 0x02, 0x03, 0x03, 0x00, 0x3C});
|
rx_telegram({0xA8, 0x00, 0xFF, 0x00, 0x02, 0x31, 0x02, 0x35, 0x00, 0x3C, 0x00, 0x3C, 0x3C, 0x46, 0x02, 0x03, 0x03, 0x00, 0x3C});
|
||||||
|
|
||||||
|
// check for error "[emsesp] No telegram type handler found for ID 0x255 (src 0x20, dest 0x00)"
|
||||||
|
rx_telegram({0xA0, 0x00, 0xFF, 0x00, 0x01, 0x55, 0x00, 0x1A});
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally dump to console
|
// finally dump to console
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
|
|||||||
|
|
||||||
if (EMS_UART.int_st.brk_det) {
|
if (EMS_UART.int_st.brk_det) {
|
||||||
EMS_UART.int_clr.brk_det = 1; // clear flag
|
EMS_UART.int_clr.brk_det = 1; // clear flag
|
||||||
|
if (emsTxBufIdx < emsTxBufLen) { // timer tx_mode is interrupted by <brk>
|
||||||
|
emsTxBufIdx = emsTxBufLen; // stop timer mode
|
||||||
|
drop_next_rx = true; // we have trash in buffer
|
||||||
|
}
|
||||||
length = 0;
|
length = 0;
|
||||||
while (EMS_UART.status.rxfifo_cnt) {
|
while (EMS_UART.status.rxfifo_cnt) {
|
||||||
uint8_t rx = EMS_UART.fifo.rw_byte; // read all bytes from fifo
|
uint8_t rx = EMS_UART.fifo.rw_byte; // read all bytes from fifo
|
||||||
@@ -81,10 +85,12 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
|
|||||||
|
|
||||||
|
|
||||||
void IRAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
void IRAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
||||||
if (emsTxBufIdx > 32) {
|
if (emsTxBufIdx > EMS_MAXBUFFERSIZE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emsTxBufIdx++;
|
emsTxBufIdx++;
|
||||||
|
|
||||||
if (emsTxBufIdx < emsTxBufLen) {
|
if (emsTxBufIdx < emsTxBufLen) {
|
||||||
EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx];
|
EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx];
|
||||||
timerAlarmWrite(timer, emsTxWait, false);
|
timerAlarmWrite(timer, emsTxWait, false);
|
||||||
@@ -98,23 +104,14 @@ void IRAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
|||||||
* init UART driver
|
* init UART driver
|
||||||
*/
|
*/
|
||||||
void EMSuart::start(uint8_t tx_mode) {
|
void EMSuart::start(uint8_t tx_mode) {
|
||||||
if(tx_mode > 10 ) {
|
emsTxWait = EMSUART_TX_BIT_TIME * (tx_mode + 10);
|
||||||
emsTxWait = EMSUART_BIT_TIME * tx_mode;
|
|
||||||
} else if(tx_mode > 5 ) {
|
|
||||||
emsTxWait = EMSUART_BIT_TIME * tx_mode * 2;
|
|
||||||
} else if(tx_mode == 3) {
|
|
||||||
emsTxWait = EMSUART_BIT_TIME * 17;
|
|
||||||
} else if(tx_mode == 2) {
|
|
||||||
emsTxWait = EMSUART_BIT_TIME * 20;
|
|
||||||
} else if(tx_mode == 1) {
|
|
||||||
emsTxWait = EMSUART_BIT_TIME * 11;
|
|
||||||
}
|
|
||||||
if (tx_mode_ != 0xFF) { // uart already initialized
|
if (tx_mode_ != 0xFF) { // uart already initialized
|
||||||
tx_mode_ = tx_mode;
|
tx_mode_ = tx_mode;
|
||||||
restart();
|
restart();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tx_mode_ = tx_mode;
|
tx_mode_ = tx_mode;
|
||||||
|
|
||||||
uart_config_t uart_config = {
|
uart_config_t uart_config = {
|
||||||
.baud_rate = EMSUART_BAUD,
|
.baud_rate = EMSUART_BAUD,
|
||||||
.data_bits = UART_DATA_8_BITS,
|
.data_bits = UART_DATA_8_BITS,
|
||||||
@@ -123,9 +120,6 @@ void EMSuart::start(uint8_t tx_mode) {
|
|||||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||||
};
|
};
|
||||||
uart_param_config(EMSUART_UART, &uart_config);
|
uart_param_config(EMSUART_UART, &uart_config);
|
||||||
if (tx_mode_ == 5) {
|
|
||||||
EMS_UART.conf0.stop_bit_num = UART_STOP_BITS_1_5;
|
|
||||||
}
|
|
||||||
uart_set_pin(EMSUART_UART, EMSUART_TXPIN, EMSUART_RXPIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
uart_set_pin(EMSUART_UART, EMSUART_TXPIN, EMSUART_RXPIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||||
EMS_UART.int_ena.val = 0; // disable all intr.
|
EMS_UART.int_ena.val = 0; // disable all intr.
|
||||||
EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags
|
EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags
|
||||||
@@ -160,27 +154,22 @@ void EMSuart::restart() {
|
|||||||
drop_next_rx = true; // and drop first frame
|
drop_next_rx = true; // and drop first frame
|
||||||
}
|
}
|
||||||
EMS_UART.int_ena.brk_det = 1; // activate only break
|
EMS_UART.int_ena.brk_det = 1; // activate only break
|
||||||
emsTxBufIdx = 0;
|
emsTxBufIdx = 0;
|
||||||
emsTxBufLen = 0;
|
emsTxBufLen = 0;
|
||||||
if (tx_mode_ == 5) {
|
|
||||||
EMS_UART.conf0.stop_bit_num = UART_STOP_BITS_1_5;
|
|
||||||
} else {
|
|
||||||
EMS_UART.conf0.stop_bit_num = UART_STOP_BITS_1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sends a 1-byte poll, ending with a <BRK>
|
* Sends a 1-byte poll, ending with a <BRK>
|
||||||
*/
|
*/
|
||||||
void EMSuart::send_poll(uint8_t data) {
|
void EMSuart::send_poll(uint8_t data) {
|
||||||
if (tx_mode_ > 5 || tx_mode_ < 4) { // modes 1, 2, 3 also here
|
// if (tx_mode_ >= 6 || tx_mode_ < 4) { // modes 1, 2, 3 also here
|
||||||
// if (tx_mode_ > 5) {
|
if (tx_mode_ >= 5) {
|
||||||
EMS_UART.fifo.rw_byte = data;
|
EMS_UART.fifo.rw_byte = data;
|
||||||
emsTxBufIdx = 0;
|
emsTxBufIdx = 0;
|
||||||
emsTxBufLen = 1;
|
emsTxBufLen = 1;
|
||||||
timerAlarmWrite(timer, emsTxWait, false);
|
timerAlarmWrite(timer, emsTxWait, false);
|
||||||
timerAlarmEnable(timer);
|
timerAlarmEnable(timer);
|
||||||
} else if (tx_mode_ >= EMS_TXMODE_NEW) {
|
} else if (tx_mode_ == EMS_TXMODE_NEW) {
|
||||||
EMS_UART.fifo.rw_byte = data;
|
EMS_UART.fifo.rw_byte = data;
|
||||||
EMS_UART.conf0.txd_brk = 1; // <brk> after send
|
EMS_UART.conf0.txd_brk = 1; // <brk> after send
|
||||||
} else if (tx_mode_ == EMS_TXMODE_HT3) {
|
} else if (tx_mode_ == EMS_TXMODE_HT3) {
|
||||||
@@ -198,7 +187,9 @@ void EMSuart::send_poll(uint8_t data) {
|
|||||||
} else {
|
} else {
|
||||||
volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt;
|
volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt;
|
||||||
EMS_UART.fifo.rw_byte = data;
|
EMS_UART.fifo.rw_byte = data;
|
||||||
while (EMS_UART.status.rxfifo_cnt == _usrxc) {
|
uint8_t timeoutcnt = EMSUART_TX_TIMEOUT;
|
||||||
|
while ((EMS_UART.status.rxfifo_cnt == _usrxc) && (--timeoutcnt > 0)) {
|
||||||
|
delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles...
|
||||||
}
|
}
|
||||||
EMS_UART.conf0.txd_brk = 1; // <brk>
|
EMS_UART.conf0.txd_brk = 1; // <brk>
|
||||||
}
|
}
|
||||||
@@ -213,19 +204,19 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
if (len == 0 || len >= EMS_MAXBUFFERSIZE) {
|
if (len == 0 || len >= EMS_MAXBUFFERSIZE) {
|
||||||
return EMS_TX_STATUS_ERR;
|
return EMS_TX_STATUS_ERR;
|
||||||
}
|
}
|
||||||
if (tx_mode_ > 5 || tx_mode_ < 4) { // timer controlled modes, also modes 1, 2, 3 because delays not working
|
// if (tx_mode_ >= 6 || tx_mode_ < 4) { // timer controlled modes, also modes 1, 2, 3 because delays not working
|
||||||
// if (tx_mode_ > 5) { // timer controlled modes
|
if (tx_mode_ >= 5) { // timer controlled modes
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
emsTxBuf[i] = buf[i];
|
emsTxBuf[i] = buf[i];
|
||||||
}
|
}
|
||||||
EMS_UART.fifo.rw_byte = buf[0];
|
EMS_UART.fifo.rw_byte = buf[0];
|
||||||
emsTxBufIdx = 0;
|
emsTxBufIdx = 0;
|
||||||
emsTxBufLen = len;
|
emsTxBufLen = len;
|
||||||
timerAlarmWrite(timer, emsTxWait, false);
|
timerAlarmWrite(timer, emsTxWait, false);
|
||||||
timerAlarmEnable(timer);
|
timerAlarmEnable(timer);
|
||||||
return EMS_TX_STATUS_OK;
|
return EMS_TX_STATUS_OK;
|
||||||
}
|
}
|
||||||
if (tx_mode_ >= EMS_TXMODE_NEW) { // hardware controlled modes
|
if (tx_mode_ == EMS_TXMODE_NEW) { // hardware controlled modes
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
EMS_UART.fifo.rw_byte = buf[i];
|
EMS_UART.fifo.rw_byte = buf[i];
|
||||||
}
|
}
|
||||||
@@ -258,10 +249,10 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
// EMS_UART.conf0.txfifo_rst = 1;
|
// EMS_UART.conf0.txfifo_rst = 1;
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt;
|
volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt;
|
||||||
EMS_UART.fifo.rw_byte = buf[i]; // send each Tx byte
|
EMS_UART.fifo.rw_byte = buf[i]; // send each Tx byte
|
||||||
// wait for echo
|
uint8_t timeoutcnt = EMSUART_TX_TIMEOUT;
|
||||||
while (EMS_UART.status.rxfifo_cnt == _usrxc) {
|
while ((EMS_UART.status.rxfifo_cnt == _usrxc) && (--timeoutcnt > 0)) {
|
||||||
// delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles...
|
delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EMS_UART.conf0.txd_brk = 1; // <brk> after send, cleard by hardware after send
|
EMS_UART.conf0.txd_brk = 1; // <brk> after send, cleard by hardware after send
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
#define EMSUART_UART UART_NUM_2 // on the ESP32 we're using UART2
|
#define EMSUART_UART UART_NUM_2 // on the ESP32 we're using UART2
|
||||||
#define EMS_UART UART2 // for intr setting
|
#define EMS_UART UART2 // for intr setting
|
||||||
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
|
||||||
#define EMSUART_BIT_TIME 104 // bit time @9600 baud
|
|
||||||
|
|
||||||
#define EMS_TXMODE_DEFAULT 1
|
#define EMS_TXMODE_DEFAULT 1
|
||||||
#define EMS_TXMODE_EMSPLUS 2
|
#define EMS_TXMODE_EMSPLUS 2
|
||||||
@@ -51,12 +50,14 @@
|
|||||||
|
|
||||||
// EMS 1.0
|
// EMS 1.0
|
||||||
#define EMSUART_TX_BUSY_WAIT (EMSUART_TX_BIT_TIME / 8) // 13
|
#define EMSUART_TX_BUSY_WAIT (EMSUART_TX_BIT_TIME / 8) // 13
|
||||||
|
#define EMSUART_TX_TIMEOUT (22 * EMSUART_TX_BIT_TIME / EMSUART_TX_BUSY_WAIT) // 176
|
||||||
|
|
||||||
// HT3/Junkers - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) plus 7 bit delay. The -8 is for lag compensation.
|
// HT3/Junkers - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) plus 7 bit delay. The -8 is for lag compensation.
|
||||||
#define EMSUART_TX_WAIT_HT3 (EMSUART_TX_BIT_TIME * 17) - 8 // 1760
|
// since we use a faster processor the lag is negligible
|
||||||
|
#define EMSUART_TX_WAIT_HT3 (EMSUART_TX_BIT_TIME * 17) // 1768
|
||||||
|
|
||||||
// EMS+ - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) and delay of another Bytetime.
|
// EMS+ - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) and delay of another Bytetime.
|
||||||
#define EMSUART_TX_WAIT_PLUS 2070
|
#define EMSUART_TX_WAIT_PLUS (EMSUART_TX_BIT_TIME * 20) // 2080
|
||||||
|
|
||||||
|
|
||||||
// customize the GPIO pins for RX and TX here
|
// customize the GPIO pins for RX and TX here
|
||||||
|
|||||||
@@ -46,8 +46,10 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
|
|||||||
|
|
||||||
if (USIS(EMSUART_UART) & ((1 << UIBD))) { // BREAK detection = End of EMS data block
|
if (USIS(EMSUART_UART) & ((1 << UIBD))) { // BREAK detection = End of EMS data block
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk
|
USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk
|
||||||
// just for testing if break isn't finished yet
|
if (emsTxBufIdx < emsTxBufLen) { // timer tx_mode is interrupted by <brk>
|
||||||
// while((USS(EMSUART_UART) >> USRXD) == 0); // wait for idle state of pin
|
emsTxBufIdx = emsTxBufLen; // stop timer mode
|
||||||
|
drop_next_rx = true; // we have trash in buffer
|
||||||
|
}
|
||||||
USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt
|
USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt
|
||||||
length = 0;
|
length = 0;
|
||||||
while ((USS(EMSUART_UART) >> USRXC) & 0x0FF) { // read fifo into buffer
|
while ((USS(EMSUART_UART) >> USRXC) & 0x0FF) { // read fifo into buffer
|
||||||
@@ -94,7 +96,7 @@ void ICACHE_FLASH_ATTR EMSuart::emsuart_flush_fifos() {
|
|||||||
|
|
||||||
// ISR to Fire when Timer is triggered
|
// ISR to Fire when Timer is triggered
|
||||||
void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
||||||
if (emsTxBufIdx > 32) {
|
if (emsTxBufIdx > EMS_MAXBUFFERSIZE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emsTxBufIdx++;
|
emsTxBufIdx++;
|
||||||
@@ -103,30 +105,15 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() {
|
|||||||
timer1_write(emsTxWait);
|
timer1_write(emsTxWait);
|
||||||
} else if (emsTxBufIdx == emsTxBufLen) {
|
} else if (emsTxBufIdx == emsTxBufLen) {
|
||||||
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
|
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
|
||||||
if (tx_mode_ > 5 || tx_mode_ < 11) {
|
|
||||||
timer1_write(5 * EMSUART_TX_BIT_TIME * 11);
|
|
||||||
USIE(EMSUART_UART) &= ~(1 << UIBD); // disable break interrupt
|
|
||||||
}
|
|
||||||
} else if (USC0(EMSUART_UART) & (1 << UCBRK)) {
|
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear <BRK>
|
|
||||||
USIE(EMSUART_UART) |= (1 << UIBD); // enable break interrupt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* init UART0 driver
|
* init UART0 driver
|
||||||
*/
|
*/
|
||||||
void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
||||||
if (tx_mode > 10) {
|
if (tx_mode >= 5) {
|
||||||
emsTxWait = 5 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode
|
emsTxWait = 5 * EMSUART_TX_BIT_TIME * (tx_mode + 10); // bittimes for tx_mode
|
||||||
} else if (tx_mode > 5) {
|
|
||||||
emsTxWait = 10 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode
|
|
||||||
}
|
}
|
||||||
if (tx_mode == 5) {
|
|
||||||
USC0(EMSUART_UART) = 0x2C; // 8N1,5
|
|
||||||
} else {
|
|
||||||
USC0(EMSUART_UART) = EMSUART_CONFIG; // 8N1
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx_mode_ != 0xFF) { // it's a restart no need to configure uart
|
if (tx_mode_ != 0xFF) { // it's a restart no need to configure uart
|
||||||
tx_mode_ = tx_mode;
|
tx_mode_ = tx_mode;
|
||||||
restart();
|
restart();
|
||||||
@@ -152,6 +139,7 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
|||||||
|
|
||||||
// set 9600, 8 bits, no parity check, 1 stop bit
|
// set 9600, 8 bits, no parity check, 1 stop bit
|
||||||
USD(EMSUART_UART) = (UART_CLK_FREQ / EMSUART_BAUD);
|
USD(EMSUART_UART) = (UART_CLK_FREQ / EMSUART_BAUD);
|
||||||
|
USC0(EMSUART_UART) = EMSUART_CONFIG; // 8N1
|
||||||
|
|
||||||
emsuart_flush_fifos();
|
emsuart_flush_fifos();
|
||||||
|
|
||||||
@@ -165,7 +153,7 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) {
|
|||||||
// Otherwise, we're only noticed by UCTOT or RxBRK!
|
// Otherwise, we're only noticed by UCTOT or RxBRK!
|
||||||
// change: don't care, we do not use these interrupts
|
// change: don't care, we do not use these interrupts
|
||||||
USC1(EMSUART_UART) = 0; // reset config first
|
USC1(EMSUART_UART) = 0; // reset config first
|
||||||
// USC1(EMSUART_UART) = (0x7F << UCFFT) | (0x04 << UCTOT) | (1 << UCTOE); // enable interupts
|
// USC1(EMSUART_UART) = (0x7F << UCFFT) | (0x01 << UCTOT) | (1 << UCTOE); // enable interupts
|
||||||
|
|
||||||
// set interrupts for triggers
|
// set interrupts for triggers
|
||||||
USIC(EMSUART_UART) = 0xFFFF; // clear all interupts
|
USIC(EMSUART_UART) = 0xFFFF; // clear all interupts
|
||||||
@@ -234,14 +222,8 @@ void ICACHE_FLASH_ATTR EMSuart::tx_brk() {
|
|||||||
ETS_UART_INTR_DISABLE();
|
ETS_UART_INTR_DISABLE();
|
||||||
USC0(EMSUART_UART) |= (1 << UCBRK); // set bit
|
USC0(EMSUART_UART) |= (1 << UCBRK); // set bit
|
||||||
|
|
||||||
if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ mode
|
// also for EMS+ there is no need to wait longer, we are finished and can free the bus.
|
||||||
delayMicroseconds(EMSUART_TX_WAIT_PLUS); // 2070
|
delayMicroseconds(EMSUART_TX_WAIT_BRK); // 1144
|
||||||
} else if (tx_mode_ == EMS_TXMODE_HT3) { // junkers
|
|
||||||
delayMicroseconds(EMSUART_TX_WAIT_BRK); // 1144
|
|
||||||
} else { // EMS1.0
|
|
||||||
while (!(USIR(EMSUART_UART) & (1 << UIBD))) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear BRK bit
|
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear BRK bit
|
||||||
ETS_UART_INTR_ENABLE();
|
ETS_UART_INTR_ENABLE();
|
||||||
@@ -252,15 +234,15 @@ void ICACHE_FLASH_ATTR EMSuart::tx_brk() {
|
|||||||
* It's a bit dirty. there is no special wait logic per tx_mode type, fifo flushes or error checking
|
* It's a bit dirty. there is no special wait logic per tx_mode type, fifo flushes or error checking
|
||||||
*/
|
*/
|
||||||
void EMSuart::send_poll(uint8_t data) {
|
void EMSuart::send_poll(uint8_t data) {
|
||||||
// reset tx-brk, just in case it is accidently set
|
// reset tx-brk, just in case it is accidentally set
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK);
|
USC0(EMSUART_UART) &= ~(1 << UCBRK);
|
||||||
|
|
||||||
if (tx_mode_ > 5) { // timer controlled modes
|
if (tx_mode_ >= 5) { // timer controlled modes
|
||||||
USF(EMSUART_UART) = data;
|
USF(EMSUART_UART) = data;
|
||||||
emsTxBufIdx = 0;
|
emsTxBufIdx = 0;
|
||||||
emsTxBufLen = 1;
|
emsTxBufLen = 1;
|
||||||
timer1_write(emsTxWait);
|
timer1_write(emsTxWait);
|
||||||
} else if (tx_mode_ >= EMS_TXMODE_NEW) { // hardware controlled modes
|
} else if (tx_mode_ == EMS_TXMODE_NEW) { // hardware controlled modes
|
||||||
USF(EMSUART_UART) = data;
|
USF(EMSUART_UART) = data;
|
||||||
USC0(EMSUART_UART) |= (1 << UCBRK); // brk after sendout
|
USC0(EMSUART_UART) |= (1 << UCBRK); // brk after sendout
|
||||||
} else if (tx_mode_ == EMS_TXMODE_HT3) {
|
} else if (tx_mode_ == EMS_TXMODE_HT3) {
|
||||||
@@ -271,7 +253,7 @@ void EMSuart::send_poll(uint8_t data) {
|
|||||||
USF(EMSUART_UART) = data;
|
USF(EMSUART_UART) = data;
|
||||||
delayMicroseconds(EMSUART_TX_WAIT_PLUS);
|
delayMicroseconds(EMSUART_TX_WAIT_PLUS);
|
||||||
tx_brk(); // send <BRK>
|
tx_brk(); // send <BRK>
|
||||||
} else { // EMS1.0
|
} else { // EMS1.0, same logic as in transmit
|
||||||
ETS_UART_INTR_DISABLE();
|
ETS_UART_INTR_DISABLE();
|
||||||
volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF;
|
volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF;
|
||||||
USF(EMSUART_UART) = data;
|
USF(EMSUART_UART) = data;
|
||||||
@@ -299,11 +281,11 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
return EMS_TX_STATUS_ERR; // nothing or to much to send
|
return EMS_TX_STATUS_ERR; // nothing or to much to send
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset tx-brk, just in case it is accidently set
|
// reset tx-brk, just in case it is accidentally set
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK);
|
USC0(EMSUART_UART) &= ~(1 << UCBRK);
|
||||||
|
|
||||||
// timer controlled modes with extra delay
|
// timer controlled modes with extra delay
|
||||||
if (tx_mode_ > 5) {
|
if (tx_mode_ >= 5) {
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
emsTxBuf[i] = buf[i];
|
emsTxBuf[i] = buf[i];
|
||||||
}
|
}
|
||||||
@@ -314,8 +296,8 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
|
|||||||
return EMS_TX_STATUS_OK;
|
return EMS_TX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hardware controlled modes with 1 and 1,5 stopbits
|
// new code from Michael. See https://github.com/proddy/EMS-ESP/issues/380
|
||||||
if (tx_mode_ >= EMS_TXMODE_NEW) {
|
if (tx_mode_ == EMS_TXMODE_NEW) { // tx_mode 4
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
USF(EMSUART_UART) = buf[i];
|
USF(EMSUART_UART) = buf[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,11 @@
|
|||||||
#define EMSUART_TX_TIMEOUT (22 * EMSUART_TX_BIT_TIME / EMSUART_TX_BUSY_WAIT) // 176
|
#define EMSUART_TX_TIMEOUT (22 * EMSUART_TX_BIT_TIME / EMSUART_TX_BUSY_WAIT) // 176
|
||||||
|
|
||||||
// HT3/Junkers - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) plus 7 bit delay. The -8 is for lag compensation.
|
// HT3/Junkers - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) plus 7 bit delay. The -8 is for lag compensation.
|
||||||
#define EMSUART_TX_WAIT_HT3 (EMSUART_TX_BIT_TIME * 17) - 8 // 1760
|
// since we use a faster processor the lag is negligible
|
||||||
|
#define EMSUART_TX_WAIT_HT3 (EMSUART_TX_BIT_TIME * 17) // 1768
|
||||||
|
|
||||||
// EMS+ - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) and delay of another Bytetime.
|
// EMS+ - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) and delay of another Bytetime.
|
||||||
#define EMSUART_TX_WAIT_PLUS 2070
|
#define EMSUART_TX_WAIT_PLUS (EMSUART_TX_BIT_TIME * 20) // 2080
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user