diff --git a/.github/workflows/build-ci.yml b/.github/workflows/build-ci.yml index 7c464fc5..ed125ebe 100644 --- a/.github/workflows/build-ci.yml +++ b/.github/workflows/build-ci.yml @@ -51,6 +51,18 @@ jobs: with: name: firmware path: ./firmware_os_esp8266.bin + build-demo: + name: Build Demo + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build Script + run: sudo ./build.sh -s demo + build-docker: name: Build Docker runs-on: ubuntu-latest diff --git a/OpenSprinkler.cpp b/OpenSprinkler.cpp index a50231ff..ccbb6bfd 100644 --- a/OpenSprinkler.cpp +++ b/OpenSprinkler.cpp @@ -95,8 +95,8 @@ extern ProgramData pd; #else #if defined(OSPI) unsigned char OpenSprinkler::pin_sr_data = PIN_SR_DATA; - OTCConfig OpenSprinkler::otc; #endif + OTCConfig OpenSprinkler::otc; // todo future: LCD define for Linux-based systems #endif diff --git a/build.sh b/build.sh index 0b43dc7d..f85197db 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e while getopts ":s" opt; do case $opt in @@ -10,16 +11,32 @@ while getopts ":s" opt; do done echo "Building OpenSprinkler..." +#Git update submodules + +if git submodule status | grep --quiet '^-'; then + echo "A git submodule is not initialized." + git submodule update --recursive --init +else + echo "Updating submodules." + git submodule update --recursive +fi + if [ "$1" == "demo" ]; then echo "Installing required libraries..." - apt-get install -y libmosquitto-dev + apt-get install -y libmosquitto-dev libssl-dev echo "Compiling demo firmware..." - g++ -o OpenSprinkler -DDEMO -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp etherport.cpp mqtt.cpp -lpthread -lmosquitto + + ws=$(ls external/TinyWebsockets/tiny_websockets_lib/src/*.cpp) + otf=$(ls external/OpenThings-Framework-Firmware-Library/*.cpp) + g++ -o OpenSprinkler -DDEMO -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp mqtt.cpp -Iexternal/TinyWebsockets/tiny_websockets_lib/include $ws -Iexternal/OpenThings-Framework-Firmware-Library/ $otf -lpthread -lmosquitto -lssl -lcrypto elif [ "$1" == "osbo" ]; then echo "Installing required libraries..." - apt-get install -y libmosquitto-dev + apt-get install -y libmosquitto-dev libssl-dev echo "Compiling osbo firmware..." - g++ -o OpenSprinkler -DOSBO -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp etherport.cpp mqtt.cpp -lpthread -lmosquitto + + ws=$(ls external/TinyWebsockets/tiny_websockets_lib/src/*.cpp) + otf=$(ls external/OpenThings-Framework-Firmware-Library/*.cpp) + g++ -o OpenSprinkler -DOSBO -std=c++14 main.cpp OpenSprinkler.cpp program.cpp opensprinkler_server.cpp utils.cpp weather.cpp gpio.cpp mqtt.cpp -Iexternal/TinyWebsockets/tiny_websockets_lib/include $ws -Iexternal/OpenThings-Framework-Firmware-Library/ $otf -lpthread -lmosquitto -lssl -lcrypto else echo "Installing required libraries..." apt-get update diff --git a/defines.h b/defines.h index 083f44fc..51f86a29 100755 --- a/defines.h +++ b/defines.h @@ -404,6 +404,8 @@ enum { #define V2_PIN_SENSOR1 3 // sensor 1 #define V2_PIN_SENSOR2 10 // sensor 2 + #define USE_OTF + #elif defined(OSPI) // for OSPi #define OS_HW_VERSION OSPI_HW_VERSION_BASE @@ -422,6 +424,8 @@ enum { #define PIN_FREE_LIST {5,6,7,8,9,10,11,12,13,16,18,19,20,21,23,24,25,26} // free GPIO pins #define ETHER_BUFFER_SIZE 16384 + #define USE_OTF + #elif defined(OSBO) // for OSBo #define OS_HW_VERSION OSBO_HW_VERSION_BASE @@ -437,6 +441,8 @@ enum { #define PIN_FREE_LIST {38,39,34,35,45,44,26,47,27,65,63,62,37,36,33,32,61,86,88,87,89,76,77,74,72,73,70,71} #define ETHER_BUFFER_SIZE 16384 + #define USE_OTF + #else // for demo / simulation // use fake hardware pins #if defined(DEMO) @@ -453,6 +459,8 @@ enum { #define PIN_RFTX 0 #define PIN_FREE_LIST {} #define ETHER_BUFFER_SIZE 16384 + + #define USE_OTF #endif #if defined(ENABLE_DEBUG) /** Serial debug functions */ diff --git a/external/OpenThings-Framework-Firmware-Library b/external/OpenThings-Framework-Firmware-Library index bec92660..39d22e99 160000 --- a/external/OpenThings-Framework-Firmware-Library +++ b/external/OpenThings-Framework-Firmware-Library @@ -1 +1 @@ -Subproject commit bec92660c29f656b720c13d621d43736f4b3d2c7 +Subproject commit 39d22e9958837e3c14c7f74176b792ec8779b66c diff --git a/main.cpp b/main.cpp index 054f6ee5..d576715d 100644 --- a/main.cpp +++ b/main.cpp @@ -1864,7 +1864,7 @@ static void perform_ntp_sync() { #if !defined(ARDUINO) // main function for RPI/BBB int main(int argc, char *argv[]) { - printf("Starting OpenSprinklerPi\n"); + printf("Starting OpenSprinkler\n"); int opt; while(-1 != (opt = getopt(argc, argv, "d:"))) { diff --git a/opensprinkler_server.cpp b/opensprinkler_server.cpp index 1b7a9261..42b3aed8 100644 --- a/opensprinkler_server.cpp +++ b/opensprinkler_server.cpp @@ -49,7 +49,6 @@ #define handle_return(x) {if(x==HTML_OK) res.writeBodyData(ether_buffer, strlen(ether_buffer)); else otf_send_result(req,res,x); return;} #else - #include "SdFat.h" extern SdFat sd; extern EthernetClient *m_client; @@ -136,7 +135,7 @@ static const char htmlReturnHome[] PROGMEM = "\n" ; -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) unsigned char findKeyVal (const OTF::Request &req,char *strbuf, uint16_t maxlen,const char *key,bool key_in_pgm=false,uint8_t *keyfound=NULL) { #if defined(ARDUINO) char* result = key_in_pgm ? req.getQueryParameter((const __FlashStringHelper *)key) : req.getQueryParameter(key); @@ -220,7 +219,7 @@ void rewind_ether_buffer() { } void send_packet(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) res.writeBodyData(ether_buffer, strlen(ether_buffer)); #else m_client->write((const uint8_t *)ether_buffer, strlen(ether_buffer)); @@ -233,7 +232,7 @@ char dec2hexchar(unsigned char dec) { else return 'A'+(dec-10); } -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) void print_header(OTF_PARAMS_DEF, bool isJson=true, int len=0) { res.writeStatus(200, F("OK")); res.writeHeader(F("Content-Type"), isJson?F("application/json"):F("text/html")); @@ -249,8 +248,8 @@ void print_header(bool isJson=true) { } #endif -#if defined(ESP8266) || defined(OSPI) -#if defined(OSPI) +#if defined(USE_OTF) +#if !defined(ARDUINO) string two_digits(uint8_t x) { return std::to_string(x); } @@ -379,7 +378,7 @@ void on_ap_try_connect(OTF_PARAMS_DEF) { /** Check and verify password */ -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) boolean check_password(char *p) { return true; } @@ -393,7 +392,7 @@ boolean check_password(char *p) #endif if (os.iopts[IOPT_IGNORE_PASSWORD]) return true; -#if !defined(ESP8266) && !defined(OSPI) +#if !defined(USE_OTF) if (m_client && !p) { p = get_buffer; } @@ -472,7 +471,7 @@ void server_json_stations_main(OTF_PARAMS_DEF) { /** Output stations data */ void server_json_stations(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) if(!process_password(OTF_PARAMS)) return; rewind_ether_buffer(); print_header(OTF_PARAMS); @@ -487,7 +486,7 @@ void server_json_stations(OTF_PARAMS_DEF) { /** Output station special attribute */ void server_json_station_special(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) if(!process_password(OTF_PARAMS)) return; rewind_ether_buffer(); print_header(OTF_PARAMS); @@ -516,7 +515,7 @@ void server_json_station_special(OTF_PARAMS_DEF) { handle_return(HTML_OK); } -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) void server_change_board_attrib(const OTF::Request &req, char header, unsigned char *attrib) #else void server_change_board_attrib(char *p, char header, unsigned char *attrib) @@ -533,7 +532,7 @@ void server_change_board_attrib(char *p, char header, unsigned char *attrib) } } -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) void server_change_stations_attrib(const OTF::Request &req, char header, unsigned char *attrib) #else void server_change_stations_attrib(char *p, char header, unsigned char *attrib) @@ -1022,7 +1021,7 @@ void server_json_options_main() { /** Output Options */ void server_json_options(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) if(!process_password(OTF_PARAMS,true)) return; rewind_ether_buffer(); print_header(OTF_PARAMS); @@ -1076,7 +1075,7 @@ void server_json_programs_main(OTF_PARAMS_DEF) { /** Output program data */ void server_json_programs(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) if(!process_password(OTF_PARAMS)) return; rewind_ether_buffer(); print_header(OTF_PARAMS); @@ -1091,7 +1090,7 @@ void server_json_programs(OTF_PARAMS_DEF) { /** Output script url form */ void server_view_scripturl(OTF_PARAMS_DEF) { rewind_ether_buffer(); -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) print_header(OTF_PARAMS,false,strlen(ether_buffer)); #else print_header(false); @@ -1219,7 +1218,7 @@ bfill.emit_p(PSTR("\"otc\":{$O},\"otcs\":$D,"), SOPT_OTC_OPTS, otf->getCloudStat /** Output controller variables in json */ void server_json_controller(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) if(!process_password(OTF_PARAMS)) return; rewind_ether_buffer(); print_header(OTF_PARAMS); @@ -1236,7 +1235,7 @@ void server_json_controller(OTF_PARAMS_DEF) { void server_home(OTF_PARAMS_DEF) { rewind_ether_buffer(); -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) print_header(OTF_PARAMS,false,strlen(ether_buffer)); #else print_header(false); @@ -1266,7 +1265,7 @@ void server_home(OTF_PARAMS_DEF) */ void server_change_values(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) extern uint32_t reboot_timer; if(!process_password(OTF_PARAMS)) return; #else @@ -1283,7 +1282,7 @@ void server_change_values(OTF_PARAMS_DEF) #endif if (findKeyVal(FKV_SOURCE, tmp_buffer, TMP_BUFFER_SIZE, PSTR("rbt"), true) && atoi(tmp_buffer) > 0) { - #if defined(ESP8266) || defined(OSPI) + #if defined(USE_OTF) os.status.safe_reboot = 0; reboot_timer = os.now_tz() + 1; handle_return(HTML_SUCCESS); @@ -1586,7 +1585,7 @@ void server_json_status_main() { /** Output station status */ void server_json_status(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) if(!process_password(OTF_PARAMS)) return; rewind_ether_buffer(); print_header(OTF_PARAMS); @@ -1744,7 +1743,7 @@ void server_json_log(OTF_PARAMS_DEF) { if (findKeyVal(FKV_SOURCE, type, 4, PSTR("type"), true)) type_specified = true; -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) // as the log data can be large, we will use ESP8266's sendContent function to // send multiple packets of data, instead of the standard way of using send(). rewind_ether_buffer(); @@ -1877,7 +1876,7 @@ void server_pause_queue(OTF_PARAMS_DEF) { /** Output all JSON data, including jc, jp, jo, js, jn */ void server_json_all(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) if(!process_password(OTF_PARAMS,true)) return; rewind_ether_buffer(); print_header(OTF_PARAMS); @@ -1913,7 +1912,7 @@ static int freeHeap () { #endif void server_json_debug(OTF_PARAMS_DEF) { -#if defined(ESP8266) || defined(OSPI) +#if defined(USE_OTF) rewind_ether_buffer(); print_header(OTF_PARAMS); #else @@ -2170,7 +2169,7 @@ void start_server_ap() { #endif -#if defined(OSPI) +#if defined(USE_OTF) && !defined(ARDUINO) void initalize_otf() { if(!otf) return; static bool callback_initialized = false; @@ -2193,7 +2192,7 @@ void initalize_otf() { } #endif -#if !defined(ESP8266) && !defined(OSPI) +#if !defined(USE_OTF) // This funtion is only used for non-OTF platforms void handle_web_request(char *p) { rewind_ether_buffer(); diff --git a/platformio.ini b/platformio.ini index 6ac8c843..83c94f55 100644 --- a/platformio.ini +++ b/platformio.ini @@ -54,4 +54,10 @@ board_build.f_flash = 80000000L platform = native build_flags = ${env.build_flags} - -DOSPI \ No newline at end of file + -DOSPI + +[env:demo] +platform = native +build_flags = + ${env.build_flags} + -DDEMO \ No newline at end of file