diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..0a066d868 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,86 @@ +os: linux +language: python +python: + - "2.7" + +cache: + directories: + - ${HOME}/.pio + +env: + global: + # - BUILDER_TOTAL_THREADS=4 + - BUILDER_TOTAL_THREADS=1 + - OWNER=${TRAVIS_REPO_SLUG%/*} + - DEV=${OWNER/proddy/dev} + - BRANCH=${TRAVIS_BRANCH/dev/} + - 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 +# - ./scripts/build.sh -p + +stages: + - name: Release +# if: type IN (cron, api) + +jobs: + include: + - stage: Release +# env: BUILDER_THREAD=0 +# - env: BUILDER_THREAD=1 +# - env: BUILDER_THREAD=2 +# - env: BUILDER_THREAD=3 + +before_deploy: + - export FIRMWARE_VERSION=$(grep -E '^#define 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: "firmware/*.bin" + file: "*.bin" + name: latest development build + 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: dev + +notifications: + email: + on_success: change + on_failure: change + +webhooks: + urls: + - https://webhooks.gitter.im/e/57e15f7798656d888194 + on_success: change # options: [always|never|change] default: always + on_failure: never # options: [always|never|change] default: always + on_start: false # default: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 381396edc..bed58e5eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added `publish_always` forcing MQTT topics to be always sent regardless if the data hasn't changed +- Support for DHW once (OneTime water) heating command via MQTT [issue 195](https://github.com/proddy/EMS-ESP/issues/195) +- Added scripts to automatically build firmware images on every Commit/Pull and nightly builds using TravisCI +- Added option to WebUI to also download the latest development build ### Fixed diff --git a/README.md b/README.md index c80759829..3d58fb72c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![release-date](https://img.shields.io/github/release-date/proddy/EMS-ESP.svg?label=Released)](https://github.com/proddy/EMS-ESP/commits/master)
[![license](https://img.shields.io/github/license/proddy/EMS-ESP.svg)](LICENSE) -[![travis](https://travis-ci.com/proddy/EMS-ESP.svg?branch=master)](https://travis-ci.com/proddy/EMS-ESP) +[![travis](https://travis-ci.com/proddy/EMS-ESP.svg?branch=dev)](https://travis-ci.com/proddy/EMS-ESP) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b8880625bdf841d4adb2829732030887)](https://app.codacy.com/app/proddy/EMS-ESP?utm_source=github.com&utm_medium=referral&utm_content=proddy/EMS-ESP&utm_campaign=Badge_Grade_Settings) [![downloads](https://img.shields.io/github/downloads/proddy/EMS-ESP/total.svg)](https://github.com/proddy/EMS-ESP/releases)
@@ -50,4 +50,4 @@ Follow [these instructions](https://github.com/proddy/EMS-ESP/wiki/Building-and- The firmware fully supports BBQKees' [EMS Gateway](https://shop.hotgoodies.nl/ems/) board with integrated Wemos D1 ESP8266. | ![on boiler](https://github.com/proddy/EMS-ESP/raw/master/doc/ems%20gateway/on-boiler.jpg) | ![kit](https://github.com/proddy/EMS-ESP/raw/master/doc/ems%20gateway/ems-kit-2.jpg) | ![basic circuit](https://github.com/proddy/EMS-ESP/raw/master/doc/ems%20gateway/ems-board-white.jpg) | -| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | \ No newline at end of file +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | diff --git a/scripts/build.sh b/scripts/build.sh old mode 100644 new mode 100755 index 750ad6113..e0a868710 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -76,13 +76,16 @@ build_webui() { build_environments() { echo "--------------------------------------------------------------" echo "Building firmware images..." - mkdir -p $destination/EMS-ESP-$version + # 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/EMS-ESP-$version-$environment.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 "--------------------------------------------------------------" } diff --git a/src/MyESP.cpp b/src/MyESP.cpp index c75ccee53..f39406874 100644 --- a/src/MyESP.cpp +++ b/src/MyESP.cpp @@ -2531,11 +2531,12 @@ void MyESP::_sendCustomStatus() { JsonObject root = doc.to(); - root["command"] = "custom_status"; - root["version"] = _app_version; - root["customname"] = _app_name; - root["appurl"] = _app_url; - root["updateurl"] = _app_updateurl; + root["command"] = "custom_status"; + root["version"] = _app_version; + root["customname"] = _app_name; + root["appurl"] = _app_url; + root["updateurl"] = _app_updateurl; + root["updateurl_dev"] = _app_updateurl_dev; // add specific custom stuff if (_web_callback_f) { @@ -2914,12 +2915,20 @@ void MyESP::_bootupSequence() { } // setup MyESP -void MyESP::begin(const char * app_hostname, const char * app_name, const char * app_version, const char * app_url, const char * app_updateurl) { +void MyESP::begin(const char * app_hostname, const char * app_name, const char * app_version, const char * app_url, const char * app_url_api) { _general_hostname = strdup(app_hostname); _app_name = strdup(app_name); _app_version = strdup(app_version); _app_url = strdup(app_url); - _app_updateurl = strdup(app_updateurl); + + char s[100]; + strlcpy(s, app_url_api, sizeof(s)); + strlcat(s, "/releases/latest", sizeof(s)); // append "/releases/latest" + _app_updateurl = strdup(s); + + strlcpy(s, app_url_api, sizeof(s)); + strlcat(s, "/releases/tags/travis-dev-build", sizeof(s)); // append "/releases/tags/travis-dev-build" + _app_updateurl_dev = strdup(s); _telnet_setup(); // Telnet setup, called first to set Serial diff --git a/src/MyESP.h b/src/MyESP.h index 8e7456627..fbebf7a32 100644 --- a/src/MyESP.h +++ b/src/MyESP.h @@ -9,7 +9,7 @@ #ifndef MyESP_h #define MyESP_h -#define MYESP_VERSION "1.2.12" +#define MYESP_VERSION "1.2.13" #include #include @@ -308,7 +308,7 @@ class MyESP { // general void end(); void loop(); - void begin(const char * app_hostname, const char * app_name, const char * app_version, const char * app_url, const char * app_updateurl); + void begin(const char * app_hostname, const char * app_name, const char * app_version, const char * app_url, const char * app_url_api); void resetESP(); int getWifiQuality(); void showSystemStats(); @@ -407,6 +407,7 @@ class MyESP { char * _app_version; char * _app_url; char * _app_updateurl; + char * _app_updateurl_dev; bool _suspendOutput; bool _general_serial; bool _general_log_events; diff --git a/src/ems-esp.cpp b/src/ems-esp.cpp index 44ffee0de..9db85400d 100644 --- a/src/ems-esp.cpp +++ b/src/ems-esp.cpp @@ -31,7 +31,7 @@ DS18 ds18; #define APP_NAME "EMS-ESP" #define APP_HOSTNAME "ems-esp" #define APP_URL "https://github.com/proddy/EMS-ESP" -#define APP_UPDATEURL "https://api.github.com/repos/proddy/EMS-ESP/releases/latest" +#define APP_URL_API "https://api.github.com/repos/proddy/EMS-ESP" // set to value >0 if the ESP is overheating or there are timing issues. Recommend a value of 1. #define EMSESP_DELAY 0 // initially set to 0 for no delay. Change to 1 if getting WDT resets from wifi @@ -116,7 +116,7 @@ static const command_t project_cmds[] PROGMEM = { {true, "publish_time ", "set frequency for publishing data to MQTT (0=off)"}, {true, "publish_always ", "set to on to skip payload comparison since last publish"}, - {true, "tx_mode ", "changes Tx logic. 1=ems generic, 2=ems+, 3=Junkers HT3"}, + {true, "tx_mode ", "changes Tx logic. 1=EMS generic, 2=EMS+, 3=HT3"}, {false, "info", "show current captured on the devices"}, {false, "log ", "set logging mode to none, basic, thermostat only, solar module only, raw, jabber or verbose"}, @@ -237,7 +237,7 @@ void showInfo() { myDebug_P(PSTR("\n%sEMS Bus stats:%s"), COLOR_BOLD_ON, COLOR_BOLD_OFF); if (ems_getBusConnected()) { - myDebug_P(PSTR(" Bus is connected, protocol: %s"), ((EMS_Sys_Status.emsIDMask == 0x80) ? "Junkers HT3" : "Buderus")); + myDebug_P(PSTR(" Bus is connected, protocol: %s"), ((EMS_Sys_Status.emsIDMask == 0x80) ? "HT3" : "Buderus")); myDebug_P(PSTR(" Rx: # successful read requests=%d, # CRC errors=%d"), EMS_Sys_Status.emsRxPgks, EMS_Sys_Status.emxCrcErr); if (ems_getTxCapable()) { @@ -592,7 +592,7 @@ void publishValues(bool force) { if (EMS_Boiler.wWActivated != EMS_VALUE_INT_NOTSET) rootBoiler["wWActivated"] = _bool_to_char(s, EMS_Boiler.wWActivated); - + if (EMS_Boiler.wWActivated != EMS_VALUE_INT_NOTSET) rootBoiler["wWOnetime"] = _bool_to_char(s, EMS_Boiler.wWOneTime); @@ -1492,11 +1492,11 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) { char topic_s[50]; char buffer[4]; for (uint8_t hc = 1; hc <= EMS_THERMOSTAT_MAXHC; hc++) { - strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_TEMP, sizeof(topic_s)); + strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_TEMP_HA, sizeof(topic_s)); strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s)); myESP.mqttSubscribe(topic_s); - strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_MODE, sizeof(topic_s)); + strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_MODE_HA, sizeof(topic_s)); strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s)); myESP.mqttSubscribe(topic_s); } @@ -2016,7 +2016,7 @@ void setup() { myESP.setSettings(LoadSaveCallback, SetListCallback, false); // default is Serial off myESP.setWeb(WebCallback); // web custom settings myESP.setOTA(OTACallback_pre, OTACallback_post); // OTA callback which is called when OTA is starting and stopping - myESP.begin(APP_HOSTNAME, APP_NAME, APP_VERSION, APP_URL, APP_UPDATEURL); + myESP.begin(APP_HOSTNAME, APP_NAME, APP_VERSION, APP_URL, APP_URL_API); // at this point we have all the settings from our internall SPIFFS config file // fire up the UART now diff --git a/src/ems.cpp b/src/ems.cpp index 8dc5771c3..285c8c6ce 100644 --- a/src/ems.cpp +++ b/src/ems.cpp @@ -187,8 +187,8 @@ const _EMS_Type EMS_Types[] = { {EMS_MODEL_ALL, EMS_TYPE_JunkersStatusMessage, "JunkersStatusMessage", _process_JunkersStatusMessage}, // Mixing devices - {EMS_MODEL_MM100, EMS_TYPE_MMPLUSStatusMessage_HC1, "MMPLUSStatusMessage_HC1", _process_MMPLUSStatusMessage}, - {EMS_MODEL_MM100, EMS_TYPE_MMPLUSStatusMessage_HC2, "MMPLUSStatusMessage_HC2", _process_MMPLUSStatusMessage}, + {EMS_MODEL_MM, EMS_TYPE_MMPLUSStatusMessage_HC1, "MMPLUSStatusMessage_HC1", _process_MMPLUSStatusMessage}, + {EMS_MODEL_MM, EMS_TYPE_MMPLUSStatusMessage_HC2, "MMPLUSStatusMessage_HC2", _process_MMPLUSStatusMessage}, }; @@ -589,11 +589,13 @@ void _ems_sendTelegram() { // we don't remove from the queue yet _EMS_TxTelegram EMS_TxTelegram = EMS_TxQueue.first(); + /* // if there is no destination, also delete it from the queue if (EMS_TxTelegram.dest == EMS_ID_NONE) { EMS_TxQueue.shift(); // remove from queue return; } + */ // if we're in raw mode just fire and forget if (EMS_TxTelegram.action == EMS_TX_TELEGRAM_RAW) { @@ -1520,9 +1522,11 @@ void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) { case EMS_OFFSET_RCPLUSStatusMessage_currsetpoint: // current setpoint temp, e.g. Thermostat -> all, telegram: 10 00 FF 06 01 A5 22 EMS_Thermostat.hc[hc].setpoint_roomTemp = _toByte(0); // value is * 2 break; - case EMS_OFFSET_RCPLUSStatusMessage_mode: // thermostat mode auto/manual - // manual : 10 00 FF 0A 01 A5 02 - // auto : Thermostat -> all, type 0x01A5 telegram: 10 00 FF 0A 01 A5 03 + case EMS_OFFSET_RCPLUSStatusMessage_mode: // thermostat mode auto/manual + // manual : 10 00 FF 0A 01 A5 02 + // auto : Thermostat -> all, type 0x01A5 telegram: 10 00 FF 0A 01 A5 03 + + // TODO this may be bit 2 instead of 1 on an RC300 - still to validate EMS_Thermostat.hc[hc].mode = _bitRead(0, 0); // bit 1, mode (auto=1 or manual=0) EMS_Thermostat.hc[hc].day_mode = _bitRead(0, 1); // get day mode flag @@ -2521,8 +2525,10 @@ void ems_scanDevices() { std::list Device_Ids; // create a new list - // add boiler device_id which is always 0x08 - Device_Ids.push_back(EMS_ID_BOILER); + + Device_Ids.push_back(EMS_ID_BOILER); // add boiler device_id which is always 0x08 + Device_Ids.push_back(EMS_ID_HP); // add heat pump + Device_Ids.push_back(EMS_ID_SM); // add solar module // copy over thermostats for (_Thermostat_Device tt : Thermostat_Devices) { @@ -2534,9 +2540,6 @@ void ems_scanDevices() { Device_Ids.push_back(ot.device_id); } - Device_Ids.push_back(EMS_ID_HP); // add heat pump - Device_Ids.push_back(EMS_ID_SM); // add solar module - // remove duplicates and reserved IDs (like our own device) Device_Ids.sort(); Device_Ids.unique(); diff --git a/src/ems.h b/src/ems.h index 59a9bcb7e..fa52f1373 100644 --- a/src/ems.h +++ b/src/ems.h @@ -186,7 +186,7 @@ const _EMS_TxTelegram EMS_TX_TELEGRAM_NEW = { // where defintions are stored typedef struct { uint8_t product_id; - char model_string[80]; + char model_string[100]; } _Boiler_Device; typedef struct { diff --git a/src/ems_devices.h b/src/ems_devices.h index 7c1fb5fa8..1078b1e33 100644 --- a/src/ems_devices.h +++ b/src/ems_devices.h @@ -160,16 +160,12 @@ typedef enum { EMS_MODEL_NONE, // unset EMS_MODEL_ALL, // common for all devices - // heatpump - EMS_MODEL_HP, + EMS_MODEL_HP, // heatpump + EMS_MODEL_SM, // solar module + EMS_MODEL_MM, // mixer module + EMS_MODEL_UBA, // boiler - // solar module - EMS_MODEL_SM, - - // boiler - EMS_MODEL_UBA, - - // and the thermostats + // and the various thermostats EMS_MODEL_ES73, EMS_MODEL_RC10, EMS_MODEL_RC20, @@ -187,9 +183,8 @@ typedef enum { EMS_MODEL_FR100, EMS_MODEL_FR110, EMS_MODEL_FW120, - - // mixing devices - EMS_MODEL_MM100 + EMS_MODEL_FW200, + EMS_MODEL_FR120 } _EMS_MODEL_ID; @@ -205,7 +200,7 @@ const _Boiler_Device Boiler_Devices[] = { {203, "Buderus Logamax U122/Junkers Cerapur"}, {208, "Buderus Logamax plus/GB192/Bosch Condens GC9000"}, {64, "Sieger BK13,BK15/Nefit Smartline/Buderus GB1x2"}, - {95, "Bosch Condens 2500/Buderus Logamax GB062/Junkers Cerapur Top/Junkers HT3"}, + {95, "Bosch Condens 2500/Buderus Logamax GB062/Junkers Cerapur Top/Worcester Greenstar i/Generic HT3"}, {122, "Nefit Proline"}, {170, "Buderus Logano GB212"}, {172, "Nefit Enviline"} @@ -235,7 +230,10 @@ const _Mixing_Device Mixing_Devices[] = { {160, "MM100 Mixing Module"}, {161, "MM200 Mixing Module"}, {69, "MM10 Mixer Module"}, - {159, "MM50 Mixing Module"} + {159, "MM50 Mixing Module"}, + {79, "MM100 Mixer Module"}, + {80, "MM200 Mixer Module"}, + {78, "MM400 Mixer Module"} }; @@ -251,7 +249,7 @@ const _Other_Device Other_Devices[] = { {125, 0x09, "BC25 Base Controller"}, {169, 0x09, "BC40 Base Controller"}, {152, 0x09, "Junkers Controller"}, - {95, 0x09, "Junkers Controller"}, + {95, 0x09, "HT3 Controller"}, {230, 0x09, "BC Base Controller"}, {205, 0x02, "Nefit Moduline Easy Connect"}, @@ -274,6 +272,7 @@ const _HeatPump_Device HeatPump_Devices[] = { /* * Known thermostat types and their capabilities * format is MODEL_ID, PRODUCT ID, DEVICE ID, DESCRIPTION + * Typically on DeviceID 0x10 or 0x18 */ const _Thermostat_Device Thermostat_Devices[] = { @@ -297,9 +296,11 @@ const _Thermostat_Device Thermostat_Devices[] = { // Junkers {EMS_MODEL_FW100, 105, 0x10, "Junkers FW100", EMS_THERMOSTAT_WRITE_NO}, - {EMS_MODEL_FR10, 111, 0x18, "Junkers FR10", EMS_THERMOSTAT_WRITE_NO}, - {EMS_MODEL_FR100, 105, 0x18, "Junkers FR100", EMS_THERMOSTAT_WRITE_NO}, + {EMS_MODEL_FW200, 106, 0x10, "Junkers FW200", EMS_THERMOSTAT_WRITE_NO}, + {EMS_MODEL_FR100, 107, 0x18, "Junkers FR100", EMS_THERMOSTAT_WRITE_NO}, {EMS_MODEL_FR110, 108, 0x18, "Junkers FR110", EMS_THERMOSTAT_WRITE_NO}, + {EMS_MODEL_FR10, 111, 0x18, "Junkers FR10", EMS_THERMOSTAT_WRITE_NO}, + {EMS_MODEL_FR120, 191, 0x10, "Junkers FR120", EMS_THERMOSTAT_WRITE_NO}, {EMS_MODEL_FW120, 192, 0x10, "Junkers FW120", EMS_THERMOSTAT_WRITE_NO}, {EMS_MODEL_FR50, 147, 0x10, "Junkers FR50", EMS_THERMOSTAT_WRITE_NO} diff --git a/src/version.h b/src/version.h index 1533a7e99..f16beb84d 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define APP_VERSION "1.9.4b1" +#define APP_VERSION "1.9.4b4" diff --git a/src/websrc/index.html b/src/websrc/index.html index 944620a64..074fec01c 100644 --- a/src/websrc/index.html +++ b/src/websrc/index.html @@ -194,7 +194,10 @@