From 540fa6a7b56bcedf7b3eb917bc8866e98c67c719 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Mon, 5 Feb 2024 22:33:59 +0700 Subject: [PATCH 01/14] Set things so that one can generate a stand alone library and access it via python. --- python/Makefile | 101 +++++++++++++++++++++++++++++++++++++++++++++ python/libirhvac.i | 36 ++++++++++++++++ src/IRac.cpp | 13 ++++++ src/IRac.h | 9 ++++ src/IRsend.cpp | 18 ++++++++ src/IRsend.h | 20 +++++++-- 6 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 python/Makefile create mode 100644 python/libirhvac.i diff --git a/python/Makefile b/python/Makefile new file mode 100644 index 000000000..51050f392 --- /dev/null +++ b/python/Makefile @@ -0,0 +1,101 @@ +# SYNOPSIS: +# +# make [all] - makes everything. +# make TARGET - makes the given target. +# make run_tests - makes everything and runs all test +# make run-% - run specific test file (exclude .py) +# replace % with given test file +# make clean - removes all files generated by make. + +# Please tweak the following variable definitions as needed by your +# project, except GTEST_HEADERS, which you can use in your own targets +# but shouldn't modify. + + +# Where to find user code. +SRC_DIR = ../src + +# Where to find test code. +TEST_DIR = ../test + +INCLUDES = -I$(SRC_DIR) -I$(TEST_DIR) +DEFFLAGS = -DUNIT_TEST -DPYTHONLIB +# Flags passed to the preprocessor. +# Set Google Test's header directory as a system directory, such that +# the compiler doesn't generate warnings in Google Test headers. +CPPFLAGS += -D_IR_LOCALE_=en-AU -fPIC $(DEFFLAGS) + +# Flags passed to the C++ compiler. +CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 + + + +objects = $(patsubst %.cpp,%,$(wildcard *.cpp)) + +all : _irhvac.so + +library : $(objects) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) + +swig : libirhvac_wrap.cxx + swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i +clean : + rm -f *.o *.pyc +distclean : + rm -f *.o *.pyc libirhvac_wrap.cxx irhvac.py _irhvac.so + + +# Keep all intermediate files. +.SECONDARY: + +# All the IR protocol object files. +PROTOCOL_OBJS = $(patsubst %.cpp,%.o,$(wildcard $(SRC_DIR)/ir_*.cpp)) +PROTOCOLS = $(patsubst $(SRC_DIR)/%,%,$(PROTOCOL_OBJS)) + +# Common object files +COMMON_OBJ = libirhvac_wrap.o IRutils.o IRtimer.o IRsend.o IRrecv.o IRtext.o IRac.o $(PROTOCOLS) + +# Common dependencies +COMMON_DEPS = $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRsend.h $(SRC_DIR)/IRtimer.h \ + $(SRC_DIR)/IRutils.h $(SRC_DIR)/IRremoteESP8266.h \ + $(SRC_DIR)/IRtext.h $(SRC_DIR)/i18n.h +# Common test dependencies +COMMON_TEST_DEPS = $(COMMON_DEPS) $(TEST_DIR)/IRsend_test.h + +IRtext.o : $(SRC_DIR)/IRtext.cpp $(SRC_DIR)/IRtext.h $(SRC_DIR)/IRremoteESP8266.h $(SRC_DIR)/i18n.h $(SRC_DIR)/locale/*.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(SRC_DIR)/IRtext.cpp + +IRutils.o : $(SRC_DIR)/IRutils.cpp $(SRC_DIR)/IRutils.h $(SRC_DIR)/IRremoteESP8266.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/IRutils.cpp + +IRsend.o : $(SRC_DIR)/IRsend.cpp $(SRC_DIR)/IRsend.h $(SRC_DIR)/IRremoteESP8266.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/IRsend.cpp + +IRrecv.o : $(SRC_DIR)/IRrecv.cpp $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRremoteESP8266.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/IRrecv.cpp + +libirhvac_wrap.o : libirhvac_wrap.cxx + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python3.11 -c libirhvac_wrap.cxx + +libirhvac_wrap.cxx : + swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i + +_irhvac.so : $(COMMON_OBJ) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) + +# new specific targets goes above this line + +$(objects) : %: $(COMMON_OBJ) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ + +ir_%.o : $(SRC_DIR)/ir_%.h $(SRC_DIR)/ir_%.cpp $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(SRC_DIR)/ir_$*.cpp + +ir_%.o : $(SRC_DIR)/ir_%.cpp $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(SRC_DIR)/ir_$*.cpp + +%.o : %.cpp $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $*.cpp + +%.o : $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(SRC_DIR)/$*.cpp diff --git a/python/libirhvac.i b/python/libirhvac.i new file mode 100644 index 000000000..9c179a8bb --- /dev/null +++ b/python/libirhvac.i @@ -0,0 +1,36 @@ +%module (package="pyhvac") irhvac +#define SWIGPYTHON_BUILTIN +%include +%include "stdint.i" +%{ + #include + #include "IRac.h" + #include "IRremoteESP8266.h" + #include "IRsend.h" +%} +%include +%template(VectorOfInt) std::vector; +%typemap(out) std::vector (PyObject* _outer) %{ + // Allocate a PyList object of the requested size. + _outer = PyList_New($1.size()); + // Populate the PyList. PyLong_FromLong converts a C++ "long" to a + // Python PyLong object. + for(int x = 0; x < $1.size(); x++) { + PyList_SetItem(_outer,x,PyLong_FromLong($1[x])); + } + $result = SWIG_Python_AppendOutput($result,_outer); +%} +%include +%typemap(out) std::vector (PyObject* _outer) %{ + // Allocate a PyList object of the requested size. + _outer = PyList_New($1.size()); + // Populate the PyList. PyLong_FromLong converts a C++ "long" to a + // Python PyLong object. + for(int x = 0; x < $1.size(); x++) { + PyList_SetItem(_outer,x,PyLong_FromLong($1[x])); + } + $result = SWIG_Python_AppendOutput($result,_outer); + %} +%include +%include + diff --git a/src/IRac.cpp b/src/IRac.cpp index 571e31c8e..2c8b0fbe4 100644 --- a/src/IRac.cpp +++ b/src/IRac.cpp @@ -18,6 +18,10 @@ #else using ::roundf; #endif +#ifdef PYTHONLIB +#include +extern std::vector timingList; +#endif #include "IRsend.h" #include "IRremoteESP8266.h" #include "IRtext.h" @@ -73,6 +77,7 @@ #ifndef UNIT_TEST #define OUTPUT_DECODE_RESULTS_FOR_UT(ac) #else +#ifndef PYTHONLIB /* NOTE: THIS IS NOT A DOXYGEN COMMENT (would require ENABLE_PREPROCESSING-YES) /// If compiling for UT *and* a test receiver @c IRrecv is provided via the /// @c _utReceived param, this injects an "output" gadget @c _lastDecodeResults @@ -98,6 +103,9 @@ } \ } \ } +#else +#define OUTPUT_DECODE_RESULTS_FOR_UT(ac) +#endif // PYTHONLIB #endif // UNIT_TEST /// Class constructor @@ -181,6 +189,11 @@ stdAc::state_t IRac::getState(void) { return next; } /// @return A Ptr to a state containing the previously sent settings. stdAc::state_t IRac::getStatePrev(void) { return _prev; } +#ifdef PYTHONLIB +std::vector IRac::getTiming(void) { return timingList; } +void IRac::resetTiming(void) { timingList.clear(); } +#endif + /// Is the given protocol supported by the IRac class? /// @param[in] protocol The vendor/protocol type. /// @return true if the protocol is supported by this class, otherwise false. diff --git a/src/IRac.h b/src/IRac.h index e3c261d0d..fc50dbf53 100644 --- a/src/IRac.h +++ b/src/IRac.h @@ -8,6 +8,9 @@ #else #include #endif +#ifdef PYTHONLIB +#include +#endif #include "IRremoteESP8266.h" #include "ir_Airton.h" #include "ir_Airwell.h" @@ -107,15 +110,21 @@ class IRac { static String swinghToString(const stdAc::swingh_t swingh); stdAc::state_t getState(void); stdAc::state_t getStatePrev(void); +#ifdef PYTHONLIB + std::vector getTiming(void); + void resetTiming(void); +#endif bool hasStateChanged(void); stdAc::state_t next; ///< The state we want the device to be in after we send #ifdef UNIT_TEST +#ifndef PYTHONLIB /// @cond IGNORE /// UT-specific /// See @c OUTPUT_DECODE_RESULTS_FOR_UT macro description in IRac.cpp std::shared_ptr _utReceiver = nullptr; std::unique_ptr _lastDecodeResults = nullptr; /// @endcond +#endif #else private: diff --git a/src/IRsend.cpp b/src/IRsend.cpp index 10e440b32..d78086d2b 100644 --- a/src/IRsend.cpp +++ b/src/IRsend.cpp @@ -8,6 +8,9 @@ #else #define __STDC_LIMIT_MACROS #include +#ifdef PYTHONLIB +#include +#endif #endif #include #ifdef UNIT_TEST @@ -15,6 +18,10 @@ #endif #include "IRtimer.h" +#ifdef PYTHONLIB +std::vector timingList; +#endif + /// Constructor for an IRsend object. /// @param[in] IRsendPin Which GPIO pin to use when sending an IR command. /// @param[in] inverted Optional flag to invert the output. (default = false) @@ -155,6 +162,11 @@ void IRsend::_delayMicroseconds(uint32_t usec) { /// Ref: /// https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/ uint16_t IRsend::mark(uint16_t usec) { +#ifdef PYTHONLIB + // std::cout << usec << " "; + timingList.push_back(usec); + return 1; +#else // Handle the simple case of no required frequency modulation. if (!modulation || _dutycycle >= 100) { ledOn(); @@ -185,6 +197,7 @@ uint16_t IRsend::mark(uint16_t usec) { elapsed = usecTimer.elapsed(); // Update & recache the actual elapsed time. } return counter; +#endif } /// Turn the pin (LED) off for a given time. @@ -194,7 +207,12 @@ uint16_t IRsend::mark(uint16_t usec) { void IRsend::space(uint32_t time) { ledOff(); if (time == 0) return; +#ifdef PYTHONLIB + // std::cout << time << " "; + timingList.push_back(time); +#else _delayMicroseconds(time); +#endif } /// Calculate & set any offsets to account for execution times during sending. diff --git a/src/IRsend.h b/src/IRsend.h index 38491372a..6edab0659 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -6,6 +6,9 @@ #define __STDC_LIMIT_MACROS #include +#ifdef PYTHONLIB +#include +#endif // PYTHONLIB #include "IRremoteESP8266.h" // Originally from https://github.com/shirriff/Arduino-IRremote/ @@ -14,6 +17,11 @@ #if TEST || UNIT_TEST #define VIRTUAL virtual +#ifdef PYTHONLIB +#define VIRTUALMS +#else +#define VIRTUALMS virtual +#endif // PYTHONLIB #else #define VIRTUAL #endif @@ -43,6 +51,11 @@ const uint32_t kDefaultMessageGap = 100000; /// @note Not using "-1" as it may be a valid external temp const float kNoTempValue = -100.0; +#ifdef PYTHONLIB +// Global +extern std::vector timingList; +#endif + /// Enumerators and Structures for the Common A/C API. namespace stdAc { /// Common A/C settings for A/C operating modes. @@ -228,6 +241,7 @@ enum argo_ac_remote_model_t { SAC_WREM3 // (2) ARGO WREM3 remote (touch buttons), bit-len vary by cmd }; +#ifndef SWIG // Classes /// Class for sending all basic IR protocols. @@ -241,8 +255,8 @@ class IRsend { void begin(); void enableIROut(uint32_t freq, uint8_t duty = kDutyDefault); VIRTUAL void _delayMicroseconds(uint32_t usec); - VIRTUAL uint16_t mark(uint16_t usec); - VIRTUAL void space(uint32_t usec); + VIRTUALMS uint16_t mark(uint16_t usec); + VIRTUALMS void space(uint32_t usec); int8_t calibrate(uint16_t hz = 38000U); void sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz); void sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, @@ -917,5 +931,5 @@ class IRsend { const uint16_t repeat, const uint16_t freq); #endif // SEND_SONY }; - +#endif //SWIG #endif // IRSEND_H_ From dd76c44aed26d8196f96c965ab5d051826745104 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Sun, 11 Feb 2024 16:17:20 +0700 Subject: [PATCH 02/14] Some clean-up. Generic include for Python. --- python/Makefile | 4 ++-- src/IRsend.cpp | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/python/Makefile b/python/Makefile index 51050f392..b239111db 100644 --- a/python/Makefile +++ b/python/Makefile @@ -40,7 +40,7 @@ library : $(objects) swig : libirhvac_wrap.cxx swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i clean : - rm -f *.o *.pyc + rm -f *.o *.pyc *.cxx *.cpp distclean : rm -f *.o *.pyc libirhvac_wrap.cxx irhvac.py _irhvac.so @@ -75,7 +75,7 @@ IRrecv.o : $(SRC_DIR)/IRrecv.cpp $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRremoteESP8266. $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/IRrecv.cpp libirhvac_wrap.o : libirhvac_wrap.cxx - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python3.11 -c libirhvac_wrap.cxx + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python -c libirhvac_wrap.cxx libirhvac_wrap.cxx : swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i diff --git a/src/IRsend.cpp b/src/IRsend.cpp index d78086d2b..0b001ab23 100644 --- a/src/IRsend.cpp +++ b/src/IRsend.cpp @@ -8,9 +8,6 @@ #else #define __STDC_LIMIT_MACROS #include -#ifdef PYTHONLIB -#include -#endif #endif #include #ifdef UNIT_TEST From 45ac7fd7fbc0cd6f4e1a93cece315cee09e85a8b Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Sun, 11 Feb 2024 21:46:15 +0700 Subject: [PATCH 03/14] Select few. --- python/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/Makefile b/python/Makefile index b239111db..0461716f7 100644 --- a/python/Makefile +++ b/python/Makefile @@ -75,7 +75,7 @@ IRrecv.o : $(SRC_DIR)/IRrecv.cpp $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRremoteESP8266. $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/IRrecv.cpp libirhvac_wrap.o : libirhvac_wrap.cxx - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python -c libirhvac_wrap.cxx + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python3.10 -I/usr/include/python3.11 -I/usr/include/python3.12 -c libirhvac_wrap.cxx libirhvac_wrap.cxx : swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i From 93798623ce4c1c06fd0ec0c24dd1a5b74fbf40b6 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Wed, 14 Feb 2024 22:44:45 +0700 Subject: [PATCH 04/14] Add generic include. --- python/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/Makefile b/python/Makefile index 0461716f7..9e9754077 100644 --- a/python/Makefile +++ b/python/Makefile @@ -75,7 +75,7 @@ IRrecv.o : $(SRC_DIR)/IRrecv.cpp $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRremoteESP8266. $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/IRrecv.cpp libirhvac_wrap.o : libirhvac_wrap.cxx - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python3.10 -I/usr/include/python3.11 -I/usr/include/python3.12 -c libirhvac_wrap.cxx + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python3.10 -I/usr/include/python3.11 -I/usr/include/python3.12 -I/usr/include/python -c libirhvac_wrap.cxx libirhvac_wrap.cxx : swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i From 52ad00fc2b4c6434f46c446fd71a6974ebc58046 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Fri, 16 Feb 2024 20:06:32 +0700 Subject: [PATCH 05/14] Simplified includes. --- python/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/Makefile b/python/Makefile index 9e9754077..b9e54e17b 100644 --- a/python/Makefile +++ b/python/Makefile @@ -28,7 +28,7 @@ CPPFLAGS += -D_IR_LOCALE_=en-AU -fPIC $(DEFFLAGS) # Flags passed to the C++ compiler. CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 - +PYTHONINCL = $(shell python3-config --includes) objects = $(patsubst %.cpp,%,$(wildcard *.cpp)) @@ -75,7 +75,7 @@ IRrecv.o : $(SRC_DIR)/IRrecv.cpp $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRremoteESP8266. $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_DIR)/IRrecv.cpp libirhvac_wrap.o : libirhvac_wrap.cxx - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -I/usr/include/python3.10 -I/usr/include/python3.11 -I/usr/include/python3.12 -I/usr/include/python -c libirhvac_wrap.cxx + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(PYTHONINCL) -c libirhvac_wrap.cxx libirhvac_wrap.cxx : swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i From 5383e7cd7b524e5d6dbf793c5cb695c2da82ee4e Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Sun, 18 Feb 2024 16:51:32 +0700 Subject: [PATCH 06/14] cpplint shenanigans --- src/IRac.cpp | 2 +- src/IRsend.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/IRac.cpp b/src/IRac.cpp index 2c8b0fbe4..4015b99bb 100644 --- a/src/IRac.cpp +++ b/src/IRac.cpp @@ -105,7 +105,7 @@ extern std::vector timingList; } #else #define OUTPUT_DECODE_RESULTS_FOR_UT(ac) -#endif // PYTHONLIB +#endif // PYTHONLIB #endif // UNIT_TEST /// Class constructor diff --git a/src/IRsend.h b/src/IRsend.h index 6edab0659..1dc49ebc9 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -8,7 +8,7 @@ #include #ifdef PYTHONLIB #include -#endif // PYTHONLIB +#endif // PYTHONLIB #include "IRremoteESP8266.h" // Originally from https://github.com/shirriff/Arduino-IRremote/ @@ -21,7 +21,7 @@ #define VIRTUALMS #else #define VIRTUALMS virtual -#endif // PYTHONLIB +#endif // PYTHONLIB #else #define VIRTUAL #endif @@ -931,5 +931,5 @@ class IRsend { const uint16_t repeat, const uint16_t freq); #endif // SEND_SONY }; -#endif //SWIG +#endif //SWIG #endif // IRSEND_H_ From 9d2cf9cddacd4bfec30ff820677e751b9e97b8a1 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Sun, 18 Feb 2024 16:53:46 +0700 Subject: [PATCH 07/14] more cpplint shenanigans --- src/IRsend.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IRsend.h b/src/IRsend.h index 1dc49ebc9..a04210aa2 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -931,5 +931,5 @@ class IRsend { const uint16_t repeat, const uint16_t freq); #endif // SEND_SONY }; -#endif //SWIG +#endif // SWIG #endif // IRSEND_H_ From 255d4737e90794444a8ccf19c093f5a18f455e32 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Sun, 18 Feb 2024 19:21:41 +0700 Subject: [PATCH 08/14] Ooops silly me. Forgot to define VIRTUALMS when UNIT_TEST is not define. --- src/IRsend.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/IRsend.h b/src/IRsend.h index a04210aa2..a1a1c28fc 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -24,6 +24,7 @@ #endif // PYTHONLIB #else #define VIRTUAL +#define VIRTUALMS #endif // Constants From 1d1a4df04179f5825c1e07e0d85ba87803db69e5 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Mon, 19 Feb 2024 21:27:14 +0700 Subject: [PATCH 09/14] Remove duplicated code from SWIG file. Makefile now download and install locally SWIG 4.2.0. Added a simple test to make sure the lib builds and produce some reasonable output. Add the test to the UnitTest.yml workflow definition. --- .github/workflows/UnitTests.yml | 9 +++++++++ python/Makefile | 21 +++++++++++++++++---- python/libirhvac.i | 10 ---------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/.github/workflows/UnitTests.yml b/.github/workflows/UnitTests.yml index a99e18c80..37cace0ef 100644 --- a/.github/workflows/UnitTests.yml +++ b/.github/workflows/UnitTests.yml @@ -28,3 +28,12 @@ jobs: run: (cd test; make all) - name: Run library unit tests run: (cd test; make run) + + Swig_Tests: + runs-on: ubuntu-latest + env: + MAKEFLAGS: "-j 2" + steps: + - uses: actions/checkout@v2 + - name: Build extension and run simple test + run: (cd python; make test) diff --git a/python/Makefile b/python/Makefile index b9e54e17b..b229ccd69 100644 --- a/python/Makefile +++ b/python/Makefile @@ -37,13 +37,22 @@ all : _irhvac.so library : $(objects) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) -swig : libirhvac_wrap.cxx - swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i +swig : libirhvac_wrap.cxx swig-4.2.0/swig + swig-4.2.0/swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i clean : rm -f *.o *.pyc *.cxx *.cpp + rm -rf swig-4.2.0 distclean : rm -f *.o *.pyc libirhvac_wrap.cxx irhvac.py _irhvac.so + rm -rf swig-4.2.0 +install-swig : swig-4.2.0/swig + rm -rf swig-4.2.0 + curl -s -L -o - http://downloads.sourceforge.net/project/swig/swig/swig-4.2.0/swig-4.2.0.tar.gz | tar xfz - + ( cd swig-4.2.0; ./configure ; make ) + +test : _irhvac.so + python test_lib.py # Keep all intermediate files. .SECONDARY: @@ -77,12 +86,16 @@ IRrecv.o : $(SRC_DIR)/IRrecv.cpp $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRremoteESP8266. libirhvac_wrap.o : libirhvac_wrap.cxx $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(PYTHONINCL) -c libirhvac_wrap.cxx -libirhvac_wrap.cxx : - swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i +libirhvac_wrap.cxx : swig-4.2.0/swig + swig-4.2.0/swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i _irhvac.so : $(COMMON_OBJ) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) +swig-4.2.0/swig : + rm -rf swig-4.2.0 + curl -s -L -o - http://downloads.sourceforge.net/project/swig/swig/swig-4.2.0/swig-4.2.0.tar.gz | tar xfz - + ( cd swig-4.2.0; ./configure ; make ) # new specific targets goes above this line $(objects) : %: $(COMMON_OBJ) diff --git a/python/libirhvac.i b/python/libirhvac.i index 9c179a8bb..7f8ebe569 100644 --- a/python/libirhvac.i +++ b/python/libirhvac.i @@ -21,16 +21,6 @@ $result = SWIG_Python_AppendOutput($result,_outer); %} %include -%typemap(out) std::vector (PyObject* _outer) %{ - // Allocate a PyList object of the requested size. - _outer = PyList_New($1.size()); - // Populate the PyList. PyLong_FromLong converts a C++ "long" to a - // Python PyLong object. - for(int x = 0; x < $1.size(); x++) { - PyList_SetItem(_outer,x,PyLong_FromLong($1[x])); - } - $result = SWIG_Python_AppendOutput($result,_outer); - %} %include %include From 8356389df7d5d72326d51370c6d9b2643807823e Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Mon, 19 Feb 2024 21:36:50 +0700 Subject: [PATCH 10/14] Let's piggyback on Tool_Tests. --- .github/workflows/UnitTests.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/UnitTests.yml b/.github/workflows/UnitTests.yml index 37cace0ef..ce79b6e35 100644 --- a/.github/workflows/UnitTests.yml +++ b/.github/workflows/UnitTests.yml @@ -13,6 +13,8 @@ jobs: run: (cd tools; make all) - name: Run tools unit tests run: (cd tools; make run_tests) + - name: Build swig extension and run simple test + run: (cd python; make test) Unit_Tests: runs-on: ubuntu-latest @@ -28,12 +30,3 @@ jobs: run: (cd test; make all) - name: Run library unit tests run: (cd test; make run) - - Swig_Tests: - runs-on: ubuntu-latest - env: - MAKEFLAGS: "-j 2" - steps: - - uses: actions/checkout@v2 - - name: Build extension and run simple test - run: (cd python; make test) From 8eb036b187954282740f7c1d895781383de2b379 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Mon, 19 Feb 2024 22:34:13 +0700 Subject: [PATCH 11/14] We need to install swig when using docker. So rearrange make file to support that. --- .github/workflows/UnitTests.yml | 2 +- python/Makefile | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/UnitTests.yml b/.github/workflows/UnitTests.yml index ce79b6e35..3c197b6b9 100644 --- a/.github/workflows/UnitTests.yml +++ b/.github/workflows/UnitTests.yml @@ -14,7 +14,7 @@ jobs: - name: Run tools unit tests run: (cd tools; make run_tests) - name: Build swig extension and run simple test - run: (cd python; make test) + run: (apt-get -y install libpcre2-dev python3-dev; cd python; make testdocker) Unit_Tests: runs-on: ubuntu-latest diff --git a/python/Makefile b/python/Makefile index b229ccd69..70fca0e3f 100644 --- a/python/Makefile +++ b/python/Makefile @@ -37,8 +37,8 @@ all : _irhvac.so library : $(objects) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) -swig : libirhvac_wrap.cxx swig-4.2.0/swig - swig-4.2.0/swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i +swig : libirhvac_wrap.cxx + swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i clean : rm -f *.o *.pyc *.cxx *.cpp rm -rf swig-4.2.0 @@ -46,14 +46,15 @@ distclean : rm -f *.o *.pyc libirhvac_wrap.cxx irhvac.py _irhvac.so rm -rf swig-4.2.0 -install-swig : swig-4.2.0/swig - rm -rf swig-4.2.0 - curl -s -L -o - http://downloads.sourceforge.net/project/swig/swig/swig-4.2.0/swig-4.2.0.tar.gz | tar xfz - - ( cd swig-4.2.0; ./configure ; make ) test : _irhvac.so python test_lib.py +docker : swig-4.2.0/swig _irhvac.so + +testdocker : swig-4.2.0/swig _irhvac.so + python test_lib.py + # Keep all intermediate files. .SECONDARY: @@ -86,8 +87,8 @@ IRrecv.o : $(SRC_DIR)/IRrecv.cpp $(SRC_DIR)/IRrecv.h $(SRC_DIR)/IRremoteESP8266. libirhvac_wrap.o : libirhvac_wrap.cxx $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(PYTHONINCL) -c libirhvac_wrap.cxx -libirhvac_wrap.cxx : swig-4.2.0/swig - swig-4.2.0/swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i +libirhvac_wrap.cxx : + swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i _irhvac.so : $(COMMON_OBJ) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) @@ -95,7 +96,7 @@ _irhvac.so : $(COMMON_OBJ) swig-4.2.0/swig : rm -rf swig-4.2.0 curl -s -L -o - http://downloads.sourceforge.net/project/swig/swig/swig-4.2.0/swig-4.2.0.tar.gz | tar xfz - - ( cd swig-4.2.0; ./configure ; make ) + ( cd swig-4.2.0; ./configure ; make; make install ) # new specific targets goes above this line $(objects) : %: $(COMMON_OBJ) From 7ef45379a7091deb2faffd182653aff1c62d866d Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Tue, 20 Feb 2024 22:14:04 +0700 Subject: [PATCH 12/14] Try to use swig without installing it. --- .github/workflows/UnitTests.yml | 2 +- python/Makefile | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/UnitTests.yml b/.github/workflows/UnitTests.yml index 3c197b6b9..0f1daa48b 100644 --- a/.github/workflows/UnitTests.yml +++ b/.github/workflows/UnitTests.yml @@ -14,7 +14,7 @@ jobs: - name: Run tools unit tests run: (cd tools; make run_tests) - name: Build swig extension and run simple test - run: (apt-get -y install libpcre2-dev python3-dev; cd python; make testdocker) + run: (cd python; make testdocker) Unit_Tests: runs-on: ubuntu-latest diff --git a/python/Makefile b/python/Makefile index 70fca0e3f..d7f941d11 100644 --- a/python/Makefile +++ b/python/Makefile @@ -11,6 +11,11 @@ # project, except GTEST_HEADERS, which you can use in your own targets # but shouldn't modify. +ifeq (,$(wildcard ./.dockerenv)) +SWIGTYPE = local +else +SWIGTYPE = global +endif # Where to find user code. SRC_DIR = ../src @@ -38,7 +43,12 @@ library : $(objects) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) swig : libirhvac_wrap.cxx +ifneq (,$(wildcard /.dockerenv)) + SWIG_LIB=$(shell realpath -qe swig-4.2.0/Lib) ./swig-4.2.0/swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i +else swig $(INCLUDES) $(DEFFLAGS) -c++ -python libirhvac.i +endif + clean : rm -f *.o *.pyc *.cxx *.cpp rm -rf swig-4.2.0 @@ -96,7 +106,7 @@ _irhvac.so : $(COMMON_OBJ) swig-4.2.0/swig : rm -rf swig-4.2.0 curl -s -L -o - http://downloads.sourceforge.net/project/swig/swig/swig-4.2.0/swig-4.2.0.tar.gz | tar xfz - - ( cd swig-4.2.0; ./configure ; make; make install ) + ( cd swig-4.2.0; ./configure ; make ) # new specific targets goes above this line $(objects) : %: $(COMMON_OBJ) From 94c2c20770147a92c7a2949ad633eef7175f76a0 Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Tue, 20 Feb 2024 22:38:18 +0700 Subject: [PATCH 13/14] =?UTF-8?q?Add=20the=20test=20file=20=F0=9F=99=84.?= =?UTF-8?q?=20Do=20not=20delete=20the=20swig=20directory.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/Makefile | 1 - python/test_lib.py | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 python/test_lib.py diff --git a/python/Makefile b/python/Makefile index d7f941d11..26d28919f 100644 --- a/python/Makefile +++ b/python/Makefile @@ -104,7 +104,6 @@ _irhvac.so : $(COMMON_OBJ) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -shared -Wl,-soname,lib_irhvac.so -o _irhvac.so $(COMMON_OBJ) swig-4.2.0/swig : - rm -rf swig-4.2.0 curl -s -L -o - http://downloads.sourceforge.net/project/swig/swig/swig-4.2.0/swig-4.2.0.tar.gz | tar xfz - ( cd swig-4.2.0; ./configure ; make ) # new specific targets goes above this line diff --git a/python/test_lib.py b/python/test_lib.py new file mode 100644 index 000000000..b346c2821 --- /dev/null +++ b/python/test_lib.py @@ -0,0 +1,11 @@ +import irhvac +ac=irhvac.IRac(4) + +ac.next.protocol = irhvac.COOLIX +ac.next.mode = irhvac.opmode_t_kAuto +ac.next.degrees = 24 +ac.sendAc() +assert ac.getTiming() == [4692, 4416, 552, 1656, 552, 552, 552, 1656, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 1656, 552, 552, 552, 1656, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 1656, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 552, 552, 552, 552, 552, 552, 552, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 1656, 552, 1656, 552, 5244, 4692, 4416, 552, 1656, 552, 552, 552, 1656, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 1656, 552, 552, 552, 1656, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 1656, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 552, 552, 552, 552, 552, 552, 552, 552, 1656, 552, 552, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, 1656, 552, 1656, 552, 1656, 552, 1656, 552, 1656, 552, 5244, 100000] +print("Success!") + + From c6cc4dd0aa02144ed0554290204c0ec7ae12e14d Mon Sep 17 00:00:00 2001 From: Francois Wautier Date: Thu, 22 Feb 2024 21:11:52 +0700 Subject: [PATCH 14/14] Changed PYTHONLIB to SWIGLIB in ifdef's. This way, it is no longer Python specifics since one could use swig create libraries for other languages. --- python/Makefile | 2 +- src/IRac.cpp | 8 ++++---- src/IRac.h | 6 +++--- src/IRsend.cpp | 6 +++--- src/IRsend.h | 10 +++++----- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/python/Makefile b/python/Makefile index 26d28919f..e144ed023 100644 --- a/python/Makefile +++ b/python/Makefile @@ -24,7 +24,7 @@ SRC_DIR = ../src TEST_DIR = ../test INCLUDES = -I$(SRC_DIR) -I$(TEST_DIR) -DEFFLAGS = -DUNIT_TEST -DPYTHONLIB +DEFFLAGS = -DUNIT_TEST -DSWIGLIB # Flags passed to the preprocessor. # Set Google Test's header directory as a system directory, such that # the compiler doesn't generate warnings in Google Test headers. diff --git a/src/IRac.cpp b/src/IRac.cpp index 4015b99bb..2e36f609c 100644 --- a/src/IRac.cpp +++ b/src/IRac.cpp @@ -18,7 +18,7 @@ #else using ::roundf; #endif -#ifdef PYTHONLIB +#ifdef SWIGLIB #include extern std::vector timingList; #endif @@ -77,7 +77,7 @@ extern std::vector timingList; #ifndef UNIT_TEST #define OUTPUT_DECODE_RESULTS_FOR_UT(ac) #else -#ifndef PYTHONLIB +#ifndef SWIGLIB /* NOTE: THIS IS NOT A DOXYGEN COMMENT (would require ENABLE_PREPROCESSING-YES) /// If compiling for UT *and* a test receiver @c IRrecv is provided via the /// @c _utReceived param, this injects an "output" gadget @c _lastDecodeResults @@ -105,7 +105,7 @@ extern std::vector timingList; } #else #define OUTPUT_DECODE_RESULTS_FOR_UT(ac) -#endif // PYTHONLIB +#endif // SWIGLIB #endif // UNIT_TEST /// Class constructor @@ -189,7 +189,7 @@ stdAc::state_t IRac::getState(void) { return next; } /// @return A Ptr to a state containing the previously sent settings. stdAc::state_t IRac::getStatePrev(void) { return _prev; } -#ifdef PYTHONLIB +#ifdef SWIGLIB std::vector IRac::getTiming(void) { return timingList; } void IRac::resetTiming(void) { timingList.clear(); } #endif diff --git a/src/IRac.h b/src/IRac.h index fc50dbf53..8e4e13b26 100644 --- a/src/IRac.h +++ b/src/IRac.h @@ -8,7 +8,7 @@ #else #include #endif -#ifdef PYTHONLIB +#ifdef SWIGLIB #include #endif #include "IRremoteESP8266.h" @@ -110,14 +110,14 @@ class IRac { static String swinghToString(const stdAc::swingh_t swingh); stdAc::state_t getState(void); stdAc::state_t getStatePrev(void); -#ifdef PYTHONLIB +#ifdef SWIGLIB std::vector getTiming(void); void resetTiming(void); #endif bool hasStateChanged(void); stdAc::state_t next; ///< The state we want the device to be in after we send #ifdef UNIT_TEST -#ifndef PYTHONLIB +#ifndef SWIGLIB /// @cond IGNORE /// UT-specific /// See @c OUTPUT_DECODE_RESULTS_FOR_UT macro description in IRac.cpp diff --git a/src/IRsend.cpp b/src/IRsend.cpp index 0b001ab23..ac9e21301 100644 --- a/src/IRsend.cpp +++ b/src/IRsend.cpp @@ -15,7 +15,7 @@ #endif #include "IRtimer.h" -#ifdef PYTHONLIB +#ifdef SWIGLIB std::vector timingList; #endif @@ -159,7 +159,7 @@ void IRsend::_delayMicroseconds(uint32_t usec) { /// Ref: /// https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/ uint16_t IRsend::mark(uint16_t usec) { -#ifdef PYTHONLIB +#ifdef SWIGLIB // std::cout << usec << " "; timingList.push_back(usec); return 1; @@ -204,7 +204,7 @@ uint16_t IRsend::mark(uint16_t usec) { void IRsend::space(uint32_t time) { ledOff(); if (time == 0) return; -#ifdef PYTHONLIB +#ifdef SWIGLIB // std::cout << time << " "; timingList.push_back(time); #else diff --git a/src/IRsend.h b/src/IRsend.h index a1a1c28fc..ef1e42fc0 100644 --- a/src/IRsend.h +++ b/src/IRsend.h @@ -6,9 +6,9 @@ #define __STDC_LIMIT_MACROS #include -#ifdef PYTHONLIB +#ifdef SWIGLIB #include -#endif // PYTHONLIB +#endif // SWIGLIB #include "IRremoteESP8266.h" // Originally from https://github.com/shirriff/Arduino-IRremote/ @@ -17,11 +17,11 @@ #if TEST || UNIT_TEST #define VIRTUAL virtual -#ifdef PYTHONLIB +#ifdef SWIGLIB #define VIRTUALMS #else #define VIRTUALMS virtual -#endif // PYTHONLIB +#endif // SWIGLIB #else #define VIRTUAL #define VIRTUALMS @@ -52,7 +52,7 @@ const uint32_t kDefaultMessageGap = 100000; /// @note Not using "-1" as it may be a valid external temp const float kNoTempValue = -100.0; -#ifdef PYTHONLIB +#ifdef SWIGLIB // Global extern std::vector timingList; #endif