From 94aad53b39712ddd8dc060881a17c34fec5c0ac6 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sun, 13 May 2018 15:50:34 +0100 Subject: [PATCH 1/5] domoticz: use 'ln -sf' in serial hotplug script Otherwise, stale symlinks don't get replaced Signed-off-by: David Woodhouse --- utils/domoticz/files/domoticz.hotplug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/domoticz/files/domoticz.hotplug b/utils/domoticz/files/domoticz.hotplug index 7138175ef..3cd8651c1 100644 --- a/utils/domoticz/files/domoticz.hotplug +++ b/utils/domoticz/files/domoticz.hotplug @@ -28,7 +28,7 @@ add() { chgrp domoticz "/dev/$DEVICENAME" chmod g+rw "/dev/$DEVICENAME" - [ -n "$symlink" ] && ln -s "/dev/$DEVICENAME" "/dev/$symlink" + [ -n "$symlink" ] && ln -sf "/dev/$DEVICENAME" "/dev/$symlink" } remove() { From a4a5fcc245a7e70a25bee4e6525e9523005a208b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 22 May 2018 16:50:27 +0100 Subject: [PATCH 2/5] domoticz: support -ssldhparam config/command line option Signed-off-by: David Woodhouse --- utils/domoticz/files/domoticz.config | 1 + utils/domoticz/files/domoticz.init | 2 ++ 2 files changed, 3 insertions(+) diff --git a/utils/domoticz/files/domoticz.config b/utils/domoticz/files/domoticz.config index b300f3f2d..870701c05 100644 --- a/utils/domoticz/files/domoticz.config +++ b/utils/domoticz/files/domoticz.config @@ -5,6 +5,7 @@ config domoticz # option sslcert '/path/to/ssl.crt' # option sslkey '/path/to/ssl.key' # option sslpass 'passphrase' + # option ssldhparam '/path/to/dhparam.pem' option sslwww '0' # CAUTION - by default, /var is not persistent accross reboots # Don't forget the trailing / - domoticz requires it diff --git a/utils/domoticz/files/domoticz.init b/utils/domoticz/files/domoticz.init index 26e0c42d4..16e986e5e 100644 --- a/utils/domoticz/files/domoticz.init +++ b/utils/domoticz/files/domoticz.init @@ -13,6 +13,7 @@ start_domoticz() { config_get sslcert "$section" "sslcert" config_get sslkey "$section" "sslkey" config_get sslpass "$section" "sslpass" + config_get ssldhparam "$section" "ssldhparam" config_get sslwww "$section" "sslwww" config_get syslog "$section" "syslog" config_get userdata "$section" "userdata" @@ -30,6 +31,7 @@ start_domoticz() { procd_append_param command -sslwww "$sslwww" [ -n "$sslkey" ] && procd_append_param command -sslkey "$sslkey" [ -n "$sslpass" ] && procd_append_param command -sslpass "$sslpass" + [ -n "$ssldhparam" ] && procd_append_param command -ssldhparam "$ssldhparam" } || procd_append_param command -sslwww 0 } From acb6cf153c42dec12d1684386dabb6ba1d1b7db4 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 22 May 2018 13:41:34 +0100 Subject: [PATCH 3/5] domoticz: build with -flto This makes quite a significant difference to the executable size: text data bss dec hex filename 7921421 87804 31692 8040917 7ab1d5 domoticz 5862321 86180 31212 5979713 5b3e41 domoticz-lto As an added bonus, it still seems to work. Signed-off-by: David Woodhouse --- utils/domoticz/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/domoticz/Makefile b/utils/domoticz/Makefile index d8dee8139..ba240960d 100644 --- a/utils/domoticz/Makefile +++ b/utils/domoticz/Makefile @@ -62,7 +62,8 @@ CMAKE_OPTIONS += \ -DUSE_STATIC_OPENZWAVE=no \ -DUSE_PYTHON=no -TARGET_CXXFLAGS+=-DWITH_GPIO +TARGET_CFLAGS+=-flto +TARGET_CXXFLAGS+=-DWITH_GPIO -flto define Build/Prepare $(call Build/Prepare/Default) From a98239c4938fec644bda4531a401b33032e34ac5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sun, 13 May 2018 15:52:50 +0100 Subject: [PATCH 4/5] domoticz: update to 3.9571 and clean up FHS handling Upstream has merged a simplified version of the FHS patch, with a few changes... Scripts are actually configuration. There are examples, but the point is that you write your own. So they should live in the data directory (e.g. /var/lib/domoticz) not in /usr/share/domoticz. The only exception is the dzVents runtime. So.... the upstream patch handles the dzVents runtime bit. Drop the part of our patch which added -scripts, because it can just be based in the userdata directory and we don't need to change that. Ship the default scripts/ directory in /etc/domoticz/scripts, and on startup make a *symlink* to it from /var/lib/domoticz/scripts. Symlink from /etc/domoticz/scripts/dzVents{data,generated_scripts} to temporary directories under /var/lib/domoticz/dzVents so that those directories (which are written to by Domoticz) don't land on the root file system. Anyone with a writeable file system who *wants* the data/ directory to be persistent, can change that. Just as they can change the userdata config option to point to a real file system somewhere. Also drop the renaming of the OpenZWave Config/ directory. It's purely cosmetric so there's no need for us to carry that change. It can go upstream first, if it really offends anyone. Drop the patches which are now merged upstream, and turn off the newly added USE_OPENSSL_STATIC. Add -noupdates to the command line. Finally, gzip the static www files to save space. In the common case, clients will use "Accept-Encodiong: gzip" and Domoticz will serve them as-is. It can also decompress on the fly if it really has to, but now we aren't asking it to *compress* on the fly, which is probably a losing proposition on an OpenWRT box. Signed-off-by: David Woodhouse --- utils/domoticz/Makefile | 44 +- utils/domoticz/files/domoticz.init | 29 +- .../001-Make-compatible-with-boost-1.66.patch | 62 --- utils/domoticz/patches/900_fix-build.patch | 11 - utils/domoticz/patches/901_no-udev.patch | 42 -- .../domoticz/patches/902_disable-libusb.patch | 39 -- utils/domoticz/patches/903_fhs.patch | 407 ------------------ 7 files changed, 55 insertions(+), 579 deletions(-) delete mode 100644 utils/domoticz/patches/001-Make-compatible-with-boost-1.66.patch delete mode 100644 utils/domoticz/patches/900_fix-build.patch delete mode 100644 utils/domoticz/patches/901_no-udev.patch delete mode 100644 utils/domoticz/patches/902_disable-libusb.patch delete mode 100644 utils/domoticz/patches/903_fhs.patch diff --git a/utils/domoticz/Makefile b/utils/domoticz/Makefile index ba240960d..8fc93e5af 100644 --- a/utils/domoticz/Makefile +++ b/utils/domoticz/Makefile @@ -9,13 +9,20 @@ include $(TOPDIR)/rules.mk PKG_NAME:=domoticz PKG_VERSION_MAJOR:=3 -PKG_VERSION_PATCH:=8153 +PKG_VERSION_PATCH:=9571 +PKG_COMMIT:=dfb39a9e739a0a07ab865577ed44e0b6aa9e7bdc PKG_VERSION:=$(PKG_VERSION_MAJOR).$(PKG_VERSION_PATCH) -PKG_RELEASE:=3 +PKG_RELEASE:=1 +ifeq ($(PKG_COMMIT),) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/domoticz/domoticz/archive/$(PKG_VERSION)/$(PKG_SOURCE) -PKG_HASH:=5ea8f37f2ef900e9bd17b1b5375e75bfdec4f09001e3e2e0b647a260989d014c +else +PKG_SOURCE:=$(PKG_NAME)-$(PKG_COMMIT).tar.gz +PKG_SOURCE_URL:=https://github.com/domoticz/domoticz/archive/$(PKG_COMMIT)/$(PKG_SOURCE) +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_COMMIT) +endif +PKG_HASH:=7e77a8ea87216f65c2f279535eb43d957e22ca14ccebfb1ef2054f9bc797a5c3 PKG_LICENSE:=GPL-3.0 PKG_LICENSE_FILES:=License.txt @@ -60,22 +67,30 @@ CMAKE_OPTIONS += \ -DUSE_STATIC_BOOST=no \ -DUSE_STATIC_LIBSTDCXX=no \ -DUSE_STATIC_OPENZWAVE=no \ - -DUSE_PYTHON=no + -DUSE_OPENSSL_STATIC=no \ + -DUSE_PYTHON=no \ + -DWITH_LIBUSB=no TARGET_CFLAGS+=-flto TARGET_CXXFLAGS+=-DWITH_GPIO -flto define Build/Prepare $(call Build/Prepare/Default) - # Fix APPVERSION to suppress update popup + # Fix APPVERSION/APPDATE since we don't build from a git tree sed -i 's/#define APPVERSION.*/#define APPVERSION $(PKG_VERSION_PATCH)/' \ $(PKG_BUILD_DIR)/appversion.default + COMMITDATE=`tar tvfz $(DL_DIR)/$(PKG_SOURCE) --full-time | sed 's/.* \(20..-..-.. ..:..:..\) domoticz-.*/\1/;q'`; \ + COMMITTS=`date --date="$$$${COMMITDATE}" +%s`; \ + sed -i "s/#define APPDATE.*/#define APPDATE $$$${COMMITTS}/" $(PKG_BUILD_DIR)/appversion.default +ifneq ($(PKG_COMMIT),) + sed -i "s/#define APPHASH.*/#define APPHASH \"$(shell echo $(PKG_COMMIT) | cut -c1-8)\"/" $(PKG_BUILD_DIR)/appversion.default +endif # Remove unwanted scripts cd $(PKG_BUILD_DIR)/scripts && rm -rf \ buienradar_rain_example.pl \ _domoticz_main* \ download_update.sh \ - dzVents/{.gitignore,documentation,examples,generated_scripts} \ + dzVents/{.gitignore,documentation,examples,generated_scripts,data} \ dzVents/runtime/{integration-tests,misc/smoothing.xlsx,tests} \ logrotate/ \ lua_parsers/example* \ @@ -84,26 +99,35 @@ define Build/Prepare readme.txt \ restart_domoticz \ templates/All.Python \ - update_domoticz + update_domoticz \ + domoticz.conf # Remove *.md cd $(PKG_BUILD_DIR) && $(FIND) -name '*.md' -delete endef define Package/domoticz/install - $(INSTALL_DIR) $(1)/etc/config $(1)/etc/hotplug.d/tty $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/config $(1)/etc/hotplug.d/tty $(1)/etc/init.d $(1)/etc/domoticz $(INSTALL_BIN) ./files/domoticz.hotplug $(1)/etc/hotplug.d/tty/domoticz $(INSTALL_BIN) ./files/domoticz.init $(1)/etc/init.d/domoticz $(INSTALL_CONF) ./files/domoticz.config $(1)/etc/config/domoticz $(INSTALL_DIR) $(1)/usr/share/domoticz $(1)/usr/bin - $(CP) $(PKG_INSTALL_DIR)/usr/Config $(1)/usr/share/domoticz/openzwave - $(CP) $(PKG_INSTALL_DIR)/usr/scripts $(1)/usr/share/domoticz/ + $(CP) $(PKG_INSTALL_DIR)/usr/dzVents $(1)/usr/share/domoticz/dzVents + $(CP) $(PKG_INSTALL_DIR)/usr/Config $(1)/usr/share/domoticz/Config + $(CP) $(PKG_INSTALL_DIR)/usr/scripts $(1)/etc/domoticz/scripts + ln -sf /var/lib/domoticz/dzVents/generated_scripts $(1)/etc/domoticz/scripts/dzVents + ln -sf /var/lib/domoticz/dzVents/data $(1)/etc/domoticz/scripts/dzVents $(CP) $(PKG_INSTALL_DIR)/usr/www $(1)/usr/share/domoticz/ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/domoticz $(1)/usr/bin/domoticz + # compress static web content + find $(1)/usr/share/domoticz/www -name "*.css" -exec gzip -9 {} \; + find $(1)/usr/share/domoticz/www -name "*.js" -exec gzip -9 {} \; + find $(1)/usr/share/domoticz/www -name "*.html" -exec sh -c 'grep -q "<\!--#embed" {} || gzip -9 {}' \; endef define Package/domoticz/conffiles /etc/config/domoticz /var/lib/domoticz/ +/etc/domoticz/ endef $(eval $(call BuildPackage,domoticz)) diff --git a/utils/domoticz/files/domoticz.init b/utils/domoticz/files/domoticz.init index 16e986e5e..89aaeae0c 100644 --- a/utils/domoticz/files/domoticz.init +++ b/utils/domoticz/files/domoticz.init @@ -16,16 +16,29 @@ start_domoticz() { config_get ssldhparam "$section" "ssldhparam" config_get sslwww "$section" "sslwww" config_get syslog "$section" "syslog" - config_get userdata "$section" "userdata" + config_get userdata "$section" "userdata" userdata /var/lib/domoticz [ -n "$loglevel" ] && procd_append_param command -loglevel "$loglevel" [ -n "$syslog" ] && procd_append_param command -syslog "$syslog" - [ -n "$userdata" ] && { - mkdir -p "${userdata}/generated_scripts" - chmod -R 0770 "$userdata" - chown -R domoticz:domoticz "$userdata" - procd_append_param command -userdata "$userdata" + + [ -d "${userdata}" ] || { + mkdir -p "${userdata}" + chmod 0770 "$userdata" + chown domoticz:domoticz "$userdata" } + + # By default, ${userdata}/scripts is a symlink to /etc/domoticz/scripts + # and the two dzVents directories under there which Domoticz will actually + # write to at runtime are symlinked back to /var/lib again. + [ -d "${userdata}/scripts" ] || ln -sf /etc/domoticz/scripts "${userdata}/scripts" + for DIR in data generated_scripts; do + [ -d /var/lib/domoticz/dzVents/$DIR ] || { + mkdir -p /var/lib/domoticz/dzVents/$DIR + chown domoticz.domoticz /var/lib/domoticz/dzVents/$DIR + } + done + procd_append_param command -userdata "$userdata" + [ -n "$sslcert" -a "${sslwww:-0}" -gt 0 ] && { procd_append_param command -sslcert "$sslcert" procd_append_param command -sslwww "$sslwww" @@ -39,8 +52,8 @@ start_service() { procd_open_instance procd_set_param command "$PROG" - procd_append_param command -scripts /usr/share/domoticz/scripts/ - procd_append_param command -wwwroot /usr/share/domoticz/www/ + procd_append_param command -noupdates + procd_append_param command -approot /usr/share/domoticz/ config_load "domoticz" config_get_bool disabled "$section" "disabled" 0 diff --git a/utils/domoticz/patches/001-Make-compatible-with-boost-1.66.patch b/utils/domoticz/patches/001-Make-compatible-with-boost-1.66.patch deleted file mode 100644 index 77c183c77..000000000 --- a/utils/domoticz/patches/001-Make-compatible-with-boost-1.66.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 11a29e071019645967ee748d410954ec5f73866f Mon Sep 17 00:00:00 2001 -From: Rob Peters -Date: Wed, 24 Jan 2018 12:03:24 +0100 -Subject: [PATCH] Make compatible with boost 1.66 - ---- - msbuild/domoticz.vcxproj | 2 +- - webserver/proxyclient.cpp | 2 +- - webserver/server.cpp | 4 ++-- - 3 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/msbuild/domoticz.vcxproj b/msbuild/domoticz.vcxproj -index e4aa595..1aa9e7a 100755 ---- a/msbuild/domoticz.vcxproj -+++ b/msbuild/domoticz.vcxproj -@@ -58,7 +58,7 @@ - Use - Level3 - Disabled -- WIN32;ENABLE_PYTHON;_DEBUG;PTW32_STATIC_LIB;WITH_OPENZWAVE;OPENZWAVE_USEDLL;WWW_ENABLE_SSL;_CONSOLE;%(PreprocessorDefinitions) -+ WIN32;ENABLE_PYTHON;_DEBUG;PTW32_STATIC_LIB;WITH_OPENZWAVE;OPENZWAVE_USEDLL;WWW_ENABLE_SSL;_CONSOLE;BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE;%(PreprocessorDefinitions) - ./Windows Libraries/Boost/boost_1_63_0;./libusb;../MQTT;..\hardware\openzwave;./Windows Libraries/openssl;./Windows Libraries/Curl;./Windows Libraries/pthread;../hardware/plugins/Include;%(AdditionalIncludeDirectories) - MultiThreadedDebugDLL - false -diff --git a/webserver/proxyclient.cpp b/webserver/proxyclient.cpp -index 203ee61..efc9815 100644 ---- a/webserver/proxyclient.cpp -+++ b/webserver/proxyclient.cpp -@@ -639,7 +639,7 @@ namespace http { - void CProxyManager::StartThread() - { - try { -- boost::asio::ssl::context ctx(io_service, boost::asio::ssl::context::sslv23); -+ boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); - ctx.set_verify_mode(boost::asio::ssl::verify_none); - - proxyclient.reset(new CProxyClient(io_service, ctx, m_pWebEm)); -diff --git a/webserver/server.cpp b/webserver/server.cpp -index 5255aa3..0c1af08 100644 ---- a/webserver/server.cpp -+++ b/webserver/server.cpp -@@ -148,7 +148,7 @@ void server::handle_accept(const boost::system::error_code& e) { - ssl_server::ssl_server(const ssl_server_settings & ssl_settings, request_handler & user_request_handler) : - server_base(ssl_settings, user_request_handler), - settings_(ssl_settings), -- context_(io_service_, ssl_settings.get_ssl_method()) -+ context_(ssl_settings.get_ssl_method()) - { - #ifdef DEBUG_WWW - _log.Log(LOG_STATUS, "[web:%s] create ssl_server using ssl_server_settings : %s", ssl_settings.listening_port.c_str(), ssl_settings.to_string().c_str()); -@@ -161,7 +161,7 @@ ssl_server::ssl_server(const ssl_server_settings & ssl_settings, request_handler - ssl_server::ssl_server(const server_settings & settings, request_handler & user_request_handler) : - server_base(settings, user_request_handler), - settings_(dynamic_cast(settings)), -- context_(io_service_, dynamic_cast(settings).get_ssl_method()) { -+ context_(dynamic_cast(settings).get_ssl_method()) { - #ifdef DEBUG_WWW - _log.Log(LOG_STATUS, "[web:%s] create ssl_server using server_settings : %s", settings.listening_port.c_str(), settings.to_string().c_str()); - #endif --- -2.7.4 - diff --git a/utils/domoticz/patches/900_fix-build.patch b/utils/domoticz/patches/900_fix-build.patch deleted file mode 100644 index b9fbebdcb..000000000 --- a/utils/domoticz/patches/900_fix-build.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -645,8 +645,6 @@ else() - target_link_libraries(domoticz -lrt ${Boost_LIBRARIES} ${ZLIB_LIBRARIES} ${CURL_LIBRARIES} pthread ${LUA_LIBRARIES} ${MQTT_LIBRARIES} ${SQLite_LIBRARIES} ${CMAKE_DL_LIBS} ${TELLDUS_LIBRARIES} ${EXECINFO_LIBRARIES}) - ENDIF() - --ADD_PRECOMPILED_HEADER(domoticz "main/stdafx.h") -- - IF(CMAKE_COMPILER_IS_GNUCXX) - option(USE_STATIC_LIBSTDCXX "Build with static libgcc/libstdc++ libraries" YES) - IF(USE_STATIC_LIBSTDCXX) diff --git a/utils/domoticz/patches/901_no-udev.patch b/utils/domoticz/patches/901_no-udev.patch deleted file mode 100644 index 0ea9dd948..000000000 --- a/utils/domoticz/patches/901_no-udev.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -579,39 +579,6 @@ IF(OpenZWave) - target_link_libraries(domoticz ${OpenZWave}) - include_directories(${CMAKE_SOURCE_DIR}/hardware/openzwave) - add_definitions(-DWITH_OPENZWAVE) -- # open-zwave needs libudev -- IF(CMAKE_SYSTEM_NAME STREQUAL "Darwin") -- set(IOKIT_LIBRARY "-framework IOKit -framework CoreFoundation" CACHE FILEPATH "IOKit framework" FORCE) -- target_link_libraries(domoticz ${IOKIT_LIBRARY}) -- else() -- IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") -- MESSAGE(STATUS "Building on FreeBSD, libudev not needed!") -- FIND_PATH(ICONV_INCLUDE_DIR iconv.h) -- FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c) -- IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) -- SET(ICONV_FOUND TRUE) -- #target_link_libraries(domoticz ${ICONV_INCLUDE_DIR}) -- target_link_libraries(domoticz ${ICONV_LIBRARIES} -lrt) -- message(STATUS ${ICONV_LIBRARIES}) -- else() -- MESSAGE(FATAL_ERROR "libiconv not found on your system") -- ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) -- else() -- find_library(UDEV NAMES libudev.a) -- IF(UDEV) -- message(STATUS ${UDEV}) -- target_link_libraries(domoticz ${UDEV} -lrt -lresolv) -- else() -- find_library(UDEV NAMES libudev.so) -- IF(UDEV) -- message(STATUS ${UDEV}) -- target_link_libraries(domoticz ${UDEV} -lrt -lresolv) -- else() -- MESSAGE(FATAL_ERROR "LIB UDEV not found on your system, see install.txt how to get them installed.\nsudo apt-get install libudev-dev") -- ENDIF(UDEV) -- ENDIF(UDEV) -- ENDIF() -- ENDIF() - else() - MESSAGE(STATUS "==== OpenZWave not found, support disabled!") - ENDIF(OpenZWave) diff --git a/utils/domoticz/patches/902_disable-libusb.patch b/utils/domoticz/patches/902_disable-libusb.patch deleted file mode 100644 index f4f03c3db..000000000 --- a/utils/domoticz/patches/902_disable-libusb.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -521,20 +521,23 @@ else() - MESSAGE(FATAL_ERROR "cURL not found on your system, see install.txt how to get them installed. (for example 'sudo apt-get install curl libcurl4-openssl-dev')") - ENDIF(CURL_FOUND) - --find_path(LIBUSB_INCLUDE_DIR usb.h -- HINTS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS}) --find_library(LIBUSB_LIBRARY NAMES usb -- HINTS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS}) --set(LIBUSB_LIBRARIES ${LIBUSB_LIBRARY}) -+option(WITH_LIBUSB "Enable libusb support" NO) -+ if(WITH_LIBUSB) -+ find_path(LIBUSB_INCLUDE_DIR usb.h -+ HINTS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS}) -+ find_library(LIBUSB_LIBRARY NAMES usb -+ HINTS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS}) -+ set(LIBUSB_LIBRARIES ${LIBUSB_LIBRARY}) - --find_package_handle_standard_args(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR) --IF(LIBUSB_FOUND) -- MESSAGE(STATUS "LIBUSB found at: ${LIBUSB_LIBRARIES}") -- add_definitions(-DWITH_LIBUSB) -- target_link_libraries(domoticz ${LIBUSB_LIBRARIES}) --else() -- MESSAGE(STATUS "==== LibUSB not found, support for TE923/Voltcraft disabled!") --ENDIF(LIBUSB_FOUND) -+ find_package_handle_standard_args(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES LIBUSB_INCLUDE_DIR) -+ IF(LIBUSB_FOUND) -+ MESSAGE(STATUS "LIBUSB found at: ${LIBUSB_LIBRARIES}") -+ add_definitions(-DWITH_LIBUSB) -+ target_link_libraries(domoticz ${LIBUSB_LIBRARIES}) -+ else() -+ MESSAGE(STATUS "==== LibUSB not found, support for TE923/Voltcraft disabled!") -+ ENDIF(LIBUSB_FOUND) -+endif(WITH_LIBUSB) - - # - # Find MD5/RMD160/SHA library diff --git a/utils/domoticz/patches/903_fhs.patch b/utils/domoticz/patches/903_fhs.patch deleted file mode 100644 index 11e531af5..000000000 --- a/utils/domoticz/patches/903_fhs.patch +++ /dev/null @@ -1,407 +0,0 @@ -diff --git a/hardware/EvohomeScript.cpp b/hardware/EvohomeScript.cpp -index 5258fc55..0a44e97c 100644 ---- a/hardware/EvohomeScript.cpp -+++ b/hardware/EvohomeScript.cpp -@@ -30,7 +30,7 @@ - - #include - --extern std::string szUserDataFolder; -+extern std::string szScriptsFolder; - - - CEvohomeScript::CEvohomeScript(const int ID) -@@ -143,7 +143,7 @@ void CEvohomeScript::RunScript(const char *pdata, const unsigned char length) - std::string scriptname = OnAction.substr(9); - #if !defined WIN32 - if (scriptname.find("/") != 0) -- scriptname = szUserDataFolder + "scripts/" + scriptname; -+ scriptname = szScriptsFolder + "scripts/" + scriptname; - #endif - std::string scriptparams=""; - //Add parameters -diff --git a/hardware/OpenZWave.cpp b/hardware/OpenZWave.cpp -index 1f5c341c..24db61c9 100644 ---- a/hardware/OpenZWave.cpp -+++ b/hardware/OpenZWave.cpp -@@ -948,7 +948,7 @@ bool COpenZWave::OpenSerialConnector() - - m_nodes.clear(); - m_bNeedSave = false; -- std::string ConfigPath = szStartupFolder + "Config/"; -+ std::string ConfigPath = "/usr/share/domoticz/openzwave/"; - std::string UserPath = ConfigPath; - if (szStartupFolder != szUserDataFolder) - { -diff --git a/main/EventSystem.cpp b/main/EventSystem.cpp -index 4eff02fd..f2b17b97 100644 ---- a/main/EventSystem.cpp -+++ b/main/EventSystem.cpp -@@ -33,9 +33,11 @@ extern "C" { - #endif - } - -+extern std::string szScriptsFolder; - extern std::string szUserDataFolder; - extern http::server::CWebServerHelper m_webservers; - -+static std::string dzv_Dir; - static std::string m_printprefix; - - #ifdef ENABLE_PYTHON -@@ -115,7 +117,6 @@ static const _tJsonMap JsonMap[] = - { NULL, NULL, tString } - }; - -- - CEventSystem::CEventSystem(void) - { - m_stoprequested = false; -@@ -149,7 +150,7 @@ void CEventSystem::StartEventSystem() - GetCurrentScenesGroups(); - GetCurrentUserVariables(); - #ifdef ENABLE_PYTHON -- Plugins::PythonEventsInitialize(szUserDataFolder); -+ Plugins::PythonEventsInitialize(szScriptsFolder); - #endif - - m_thread = boost::shared_ptr(new boost::thread(boost::bind(&CEventSystem::Do_Work, this))); -@@ -179,11 +180,11 @@ void CEventSystem::SetEnabled(const bool bEnabled) - - void CEventSystem::LoadEvents() - { -- std::string dzv_Dir,s; -+ std::string s; - #ifdef WIN32 -- dzv_Dir = szUserDataFolder + "scripts\\dzVents\\generated_scripts\\"; -+ dzv_Dir = szUserDataFolder + "generated_scripts\\"; - #else -- dzv_Dir = szUserDataFolder + "scripts/dzVents/generated_scripts/"; -+ dzv_Dir = szUserDataFolder + "generated_scripts/"; - #endif - boost::unique_lock eventsMutexLock(m_eventsMutex); - _log.Log(LOG_STATUS, "EventSystem: reset all events..."); -@@ -274,18 +275,18 @@ void CEventSystem::LoadEvents() - void CEventSystem::Do_Work() - { - #ifdef WIN32 -- m_lua_Dir = szUserDataFolder + "scripts\\lua\\"; -- m_dzv_Dir = szUserDataFolder + "scripts\\dzVents\\runtime\\"; -+ m_lua_Dir = szScriptsFolder + "lua\\"; -+ m_dzv_Dir = szScriptsFolder + "dzVents\\runtime\\"; - #else -- m_lua_Dir = szUserDataFolder + "scripts/lua/"; -- m_dzv_Dir = szUserDataFolder + "scripts/dzVents/runtime/"; -+ m_lua_Dir = szScriptsFolder + "lua/"; -+ m_dzv_Dir = szScriptsFolder + "dzVents/runtime/"; - #endif - - #ifdef ENABLE_PYTHON - #ifdef WIN32 -- m_python_Dir = szUserDataFolder + "scripts\\python\\"; -+ m_python_Dir = szScriptsFolder + "python\\"; - #else -- m_python_Dir = szUserDataFolder + "scripts/python/"; -+ m_python_Dir = szScriptsFolder + "python/"; - #endif - #endif - m_stoprequested = false; -@@ -1426,9 +1427,9 @@ void CEventSystem::EvaluateEvent(const std::string &reason, const uint64_t Devic - { - std::string dzv_scripts; - #ifdef WIN32 -- dzv_scripts = szUserDataFolder + "scripts\\dzVents\\scripts\\"; -+ dzv_scripts = szScriptsFolder + "dzVents\\scripts\\"; - #else -- dzv_scripts = szUserDataFolder + "scripts/dzVents/scripts/"; -+ dzv_scripts = szScriptsFolder + "dzVents/scripts/"; - #endif - DirectoryListing(FileEntries, dzv_scripts, false, true); - for (itt = FileEntries.begin(); itt != FileEntries.end(); ++itt) -@@ -2404,7 +2405,7 @@ bool CEventSystem::parseBlocklyActions(const std::string &Actions, const std::st - } - #if !defined WIN32 - if (sPath.find("/") != 0) -- sPath = szUserDataFolder + "scripts/" + sPath; -+ sPath = szScriptsFolder + sPath; - #endif - - m_sql.AddTaskItem(_tTaskItem::ExecuteScript(0.2f, sPath, sParam)); -@@ -3508,13 +3509,16 @@ void CEventSystem::EvaluateLua(const std::string &reason, const std::string &fil - { - std::stringstream lua_DirT; - -- lua_DirT << szUserDataFolder << -+ lua_DirT << szScriptsFolder << - #ifdef WIN32 -- "scripts\\dzVents\\"; -+ "dzVents\\"; - #else -- "scripts/dzVents/"; -+ "dzVents/"; - #endif - -+ lua_pushstring(lua_state, "generated_script_path"); -+ lua_pushstring(lua_state, dzv_Dir.c_str()); -+ lua_rawset(lua_state, -3); - lua_pushstring(lua_state, "script_path"); - lua_pushstring(lua_state, lua_DirT.str().c_str()); - lua_rawset(lua_state, -3); -@@ -4695,9 +4699,9 @@ namespace http { - - std::stringstream template_file; - #ifdef WIN32 -- template_file << szUserDataFolder << "scripts\\templates\\" << eventType << "." << interpreter; -+ template_file << szScriptsFolder << "templates\\" << eventType << "." << interpreter; - #else -- template_file << szUserDataFolder << "scripts/templates/" << eventType << "." << interpreter; -+ template_file << szScriptsFolder << "templates/" << eventType << "." << interpreter; - #endif - std::ifstream file; - std::stringstream template_content; -diff --git a/main/EventsPythonModule.cpp b/main/EventsPythonModule.cpp -index f69e7219..2d97562e 100644 ---- a/main/EventsPythonModule.cpp -+++ b/main/EventsPythonModule.cpp -@@ -108,7 +108,7 @@ - - int PythonEventsInitalized = 0; - -- bool PythonEventsInitialize(std::string szUserDataFolder) { -+ bool PythonEventsInitialize(std::string szScriptsFolder) { - - if (!Plugins::Py_LoadLibrary()) - { -@@ -131,9 +131,9 @@ - - std::string ssPath; - #ifdef WIN32 -- ssPath = szUserDataFolder + "scripts\\python\\;"; -+ ssPath = szScriptsFolder + "python\\;"; - #else -- ssPath = szUserDataFolder + "scripts/python/:"; -+ ssPath = szScriptsFolder + "python/:"; - #endif - - std::wstring sPath = std::wstring(ssPath.begin(), ssPath.end()); -diff --git a/main/LuaHandler.cpp b/main/LuaHandler.cpp -index 8fdcb278..c2ad98ff 100644 ---- a/main/LuaHandler.cpp -+++ b/main/LuaHandler.cpp -@@ -22,7 +22,7 @@ extern "C" { - #include "mainworker.h" - #include "../hardware/hardwaretypes.h" - --extern std::string szUserDataFolder; -+extern std::string szScriptsFolder; - - int CLuaHandler::l_domoticz_updateDevice(lua_State* lua_state) - { -@@ -155,9 +155,9 @@ bool CLuaHandler::executeLuaScript(const std::string &script, const std::string - { - std::stringstream lua_DirT; - #ifdef WIN32 -- lua_DirT << szUserDataFolder << "scripts\\lua_parsers\\"; -+ lua_DirT << szScriptsFolder << "lua_parsers\\"; - #else -- lua_DirT << szUserDataFolder << "scripts/lua_parsers/"; -+ lua_DirT << szScriptsFolder << "lua_parsers/"; - #endif - std::string lua_Dir = lua_DirT.str(); - -diff --git a/main/SQLHelper.cpp b/main/SQLHelper.cpp -index 491aa5a2..d529243a 100644 ---- a/main/SQLHelper.cpp -+++ b/main/SQLHelper.cpp -@@ -633,6 +633,7 @@ const char *sqlCreateMobileDevices = - "[LastUpdate] DATETIME DEFAULT(datetime('now', 'localtime'))" - ");"; - -+extern std::string szScriptsFolder; - extern std::string szUserDataFolder; - - CSQLHelper::CSQLHelper(void) -@@ -3683,9 +3684,9 @@ uint64_t CSQLHelper::UpdateValueInt(const int HardwareID, const char* ID, const - //Execute possible script - std::string scriptname; - #ifdef WIN32 -- scriptname = szUserDataFolder + "scripts\\domoticz_main.bat"; -+ scriptname = szScriptsFolder + "domoticz_main.bat"; - #else -- scriptname = szUserDataFolder + "scripts/domoticz_main"; -+ scriptname = szScriptsFolder + "domoticz_main"; - #endif - if (file_exist(scriptname.c_str())) - { -@@ -6641,7 +6642,7 @@ bool CSQLHelper::HandleOnOffAction(const bool bIsOn, const std::string &OnAction - std::string scriptname = OnAction.substr(9); - #if !defined WIN32 - if (scriptname.find("/") != 0) -- scriptname = szUserDataFolder + "scripts/" + scriptname; -+ scriptname = szScriptsFolder + scriptname; - #endif - std::string scriptparams=""; - //Add parameters -@@ -6675,7 +6676,7 @@ bool CSQLHelper::HandleOnOffAction(const bool bIsOn, const std::string &OnAction - std::string scriptname = OffAction.substr(9); - #if !defined WIN32 - if (scriptname.find("/") != 0) -- scriptname = szUserDataFolder + "scripts/" + scriptname; -+ scriptname = szScriptsFolder + scriptname; - #endif - std::string scriptparams = ""; - int pindex = scriptname.find(' '); -diff --git a/main/WebServer.cpp b/main/WebServer.cpp -index f8471791..d2cf10b2 100644 ---- a/main/WebServer.cpp -+++ b/main/WebServer.cpp -@@ -59,6 +59,7 @@ - - #define round(a) ( int ) ( a + .5 ) - -+extern std::string szScriptsFolder; - extern std::string szUserDataFolder; - extern std::string szWWWFolder; - -@@ -2987,9 +2988,9 @@ namespace http { - if (scriptname.find("..") != std::string::npos) - return; - #ifdef WIN32 -- scriptname = szUserDataFolder + "scripts\\" + scriptname; -+ scriptname = szScriptsFolder + scriptname; - #else -- scriptname = szUserDataFolder + "scripts/" + scriptname; -+ scriptname = szScriptsFolder + scriptname; - #endif - if (!file_exist(scriptname.c_str())) - return; -diff --git a/main/domoticz.cpp b/main/domoticz.cpp -index 5ef96f68..52599b14 100644 ---- a/main/domoticz.cpp -+++ b/main/domoticz.cpp -@@ -136,6 +136,7 @@ static const _facilities facilities[] = - }; - std::string logfacname = "user"; - #endif -+std::string szScriptsFolder; - std::string szStartupFolder; - std::string szUserDataFolder; - std::string szWWWFolder; -@@ -696,6 +697,19 @@ int main(int argc, char**argv) - szUserDataFolder = szroot; - } - -+ szScriptsFolder=szStartupFolder; -+ if (cmdLine.HasSwitch("-scripts")) -+ { -+ if (cmdLine.GetArgumentCount("-scripts") != 1) -+ { -+ _log.Log(LOG_ERROR, "Please specify a path for scripts directory"); -+ return 1; -+ } -+ std::string szroot = cmdLine.GetSafeArgument("-scripts", 0, ""); -+ if (szroot.size() != 0) -+ szScriptsFolder = szroot; -+ } -+ - if (cmdLine.HasSwitch("-startupdelay")) - { - if (cmdLine.GetArgumentCount("-startupdelay") != 1) -diff --git a/main/mainworker.cpp b/main/mainworker.cpp -index 803690e1..e89a783b 100644 ---- a/main/mainworker.cpp -+++ b/main/mainworker.cpp -@@ -159,6 +159,7 @@ - - #define round(a) ( int ) ( a + .5 ) - -+extern std::string szScriptsFolder; - extern std::string szStartupFolder; - extern std::string szUserDataFolder; - extern std::string szWWWFolder; -@@ -1473,8 +1474,8 @@ void MainWorker::Do_Work() - m_sql.GetPreferencesVar("ReleaseChannel", nValue); - bool bIsBetaChannel = (nValue != 0); - -- std::string scriptname = szUserDataFolder + "scripts/download_update.sh"; -- std::string strparm = szUserDataFolder; -+ std::string scriptname = szScriptsFolder + "download_update.sh"; -+ std::string strparm = szScriptsFolder; - if (bIsBetaChannel) - strparm += " /beta"; - -diff --git a/notifications/NotificationHTTP.cpp b/notifications/NotificationHTTP.cpp -index decff3b4..632e4e66 100644 ---- a/notifications/NotificationHTTP.cpp -+++ b/notifications/NotificationHTTP.cpp -@@ -6,7 +6,7 @@ - #include "../main/SQLHelper.h" - #include "../main/Logger.h" - --extern std::string szUserDataFolder; -+extern std::string szScriptsFolder; - - CNotificationHTTP::CNotificationHTTP() : CNotificationBase(std::string("http"), OPTIONS_NONE) - { -@@ -105,7 +105,7 @@ bool CNotificationHTTP::SendMessageImplementation( - std::string scriptparams = ""; - #if !defined WIN32 - if (scriptname.find("/") != 0) -- scriptname = szUserDataFolder + "scripts/" + scriptname; -+ scriptname = szScriptsFolder + scriptname; - #endif - //Add parameters - uPos = scriptname.find(" "); -diff --git a/push/GooglePubSubPush.cpp b/push/GooglePubSubPush.cpp -index 359a7d7c..46e489f6 100644 ---- a/push/GooglePubSubPush.cpp -+++ b/push/GooglePubSubPush.cpp -@@ -22,7 +22,7 @@ extern "C" { - using namespace boost::python; - #endif - --extern std::string szUserDataFolder; -+extern std::string szScriptsFolder; - - // this should be filled in by the preprocessor - extern const char * Python_exe; -@@ -231,11 +231,11 @@ void CGooglePubSubPush::DoGooglePubSubPush() - - #ifdef ENABLE_PYTHON_DECAP - #ifdef WIN32 -- python_DirT << szUserDataFolder << "scripts\\python\\"; -- std::string filename = szUserDataFolder + "scripts\\python\\" + "googlepubsub.py"; -+ python_DirT << szScriptsFolder << "python\\"; -+ std::string filename = szScriptsFolder + "python\\" + "googlepubsub.py"; - #else -- python_DirT << szUserDataFolder << "scripts/python/"; -- std::string filename = szUserDataFolder + "scripts/python/" + "googlepubsub.py"; -+ python_DirT << szScriptsFolder << "python/"; -+ std::string filename = szScriptsFolder + "python/" + "googlepubsub.py"; - #endif - - wchar_t * argv[1]; -diff --git a/scripts/dzVents/runtime/dzVents.lua b/scripts/dzVents/runtime/dzVents.lua -index d0dfa869..8370d6a9 100644 ---- a/scripts/dzVents/runtime/dzVents.lua -+++ b/scripts/dzVents/runtime/dzVents.lua -@@ -1,8 +1,9 @@ - local currentPath = globalvariables['script_path'] -+local generatedScriptPath = globalvariables['generated_script_path'] - local triggerReason = globalvariables['script_reason'] - - _G.scriptsFolderPath = currentPath .. 'scripts' -- global --_G.generatedScriptsFolderPath = currentPath .. 'generated_scripts' -- global -+_G.generatedScriptsFolderPath = generatedScriptPath -- global - _G.dataFolderPath = currentPath .. 'data' -- global - - package.path = package.path .. ';' .. currentPath .. '?.lua' -@@ -10,7 +11,7 @@ package.path = package.path .. ';' .. currentPath .. 'runtime/?.lua' - package.path = package.path .. ';' .. currentPath .. 'runtime/device-adapters/?.lua' - package.path = package.path .. ';' .. currentPath .. 'dzVents/?.lua' - package.path = package.path .. ';' .. currentPath .. 'scripts/?.lua' --package.path = package.path .. ';' .. currentPath .. 'generated_scripts/?.lua' -+package.path = package.path .. ';' .. generatedScriptPath .. '?.lua' - package.path = package.path .. ';' .. currentPath .. 'data/?.lua' - - local EventHelpers = require('EventHelpers') From e42d656e812a2e0ae6972544ac51fd7c8082041b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sun, 13 May 2018 15:54:05 +0100 Subject: [PATCH 5/5] domoticz: fix Onkyo custom command handling from dzVents https://github.com/domoticz/domoticz/pull/2386 Signed-off-by: David Woodhouse --- utils/domoticz/patches/101_onkyo_pr2386.patch | 250 ++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 utils/domoticz/patches/101_onkyo_pr2386.patch diff --git a/utils/domoticz/patches/101_onkyo_pr2386.patch b/utils/domoticz/patches/101_onkyo_pr2386.patch new file mode 100644 index 000000000..ce624428f --- /dev/null +++ b/utils/domoticz/patches/101_onkyo_pr2386.patch @@ -0,0 +1,250 @@ +From 86a4fe7e28952f969609cfb52afae06b40aa273e Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Sat, 12 May 2018 15:11:29 +0100 +Subject: [PATCH] Add generic CustomCommand handling for scripts + +The Onkyo-specific support in JSON and dzVents isn't really sufficient, +because it (quite rightly) needs authentication. But dzVents just assumes +it can make unauthenticated calls to localhost:8080, and doesn't work. + +I've been working around this by spawning an external script to invoke +curl, but *that* only works over HTTPS not HTTP for some reason (without +HTTPS I just get an 'Unauthorized' response). And that takes literally +*seconds* to work, on the slow machine I'm using. + +Fix it up so that the script command arrays can have a 'CustomCommand', +done generically so that it can easily cover devices other than Onkyo. +--- + .../runtime/device-adapters/onkyo_device.lua | 4 +- + hardware/DomoticzHardware.cpp | 5 ++ + hardware/DomoticzHardware.h | 1 + + hardware/OnkyoAVTCP.cpp | 4 ++ + hardware/OnkyoAVTCP.h | 1 + + main/EventSystem.cpp | 57 +++++++++++++++++++ + main/EventSystem.h | 1 + + main/SQLHelper.cpp | 4 ++ + main/SQLHelper.h | 15 ++++- + 9 files changed, 88 insertions(+), 4 deletions(-) + +diff --git a/dzVents/runtime/device-adapters/onkyo_device.lua b/dzVents/runtime/device-adapters/onkyo_device.lua +index ec74841f..8222fe6b 100644 +--- a/dzVents/runtime/device-adapters/onkyo_device.lua ++++ b/dzVents/runtime/device-adapters/onkyo_device.lua +@@ -17,9 +17,7 @@ return { + process = function (device, data, domoticz, utils, adapterManager) + + function device.onkyoEISCPCommand(cmd) +- local url = domoticz.settings['Domoticz url'] .. +- '/json.htm?param=onkyoeiscpcommand&type=command&idx=' .. device.id .. '&action=' .. tostring (cmd) +- return domoticz.openURL(url) ++ return TimedCommand(domoticz, 'CustomCommand:' .. device.id, tostring(cmd), 'device') + end + end + } +diff --git a/hardware/DomoticzHardware.cpp b/hardware/DomoticzHardware.cpp +index 7aad167b..75db53c0 100644 +--- a/hardware/DomoticzHardware.cpp ++++ b/hardware/DomoticzHardware.cpp +@@ -36,6 +36,11 @@ CDomoticzHardwareBase::~CDomoticzHardwareBase() + { + } + ++bool CDomoticzHardwareBase::CustomCommand(const uint64_t idx, const std::string &sCommand) ++{ ++ return false; ++} ++ + bool CDomoticzHardwareBase::Start() + { + m_iHBCounter = 0; +diff --git a/hardware/DomoticzHardware.h b/hardware/DomoticzHardware.h +index a8790f91..660fc2de 100644 +--- a/hardware/DomoticzHardware.h ++++ b/hardware/DomoticzHardware.h +@@ -16,6 +16,7 @@ public: + bool Start(); + bool Stop(); + virtual bool WriteToHardware(const char *pdata, const unsigned char length)=0; ++ virtual bool CustomCommand(const uint64_t idx, const std::string &sCommand); + + void EnableOutputLog(const bool bEnableLog); + +diff --git a/hardware/OnkyoAVTCP.cpp b/hardware/OnkyoAVTCP.cpp +index 88766032..9f386c01 100644 +--- a/hardware/OnkyoAVTCP.cpp ++++ b/hardware/OnkyoAVTCP.cpp +@@ -676,6 +676,10 @@ void OnkyoAVTCP::ParseData(const unsigned char *pData, int Len) + m_pPartialPkt = new_partial; + } + ++bool OnkyoAVTCP::CustomCommand(const uint64_t idx, const std::string &sCommand) ++{ ++ return SendPacket(sCommand.c_str()); ++} + + //Webserver helpers + namespace http { +diff --git a/hardware/OnkyoAVTCP.h b/hardware/OnkyoAVTCP.h +index 90dbce51..133f4876 100644 +--- a/hardware/OnkyoAVTCP.h ++++ b/hardware/OnkyoAVTCP.h +@@ -21,6 +21,7 @@ private: + int m_retrycntr; + bool StartHardware(); + bool StopHardware(); ++ bool CustomCommand(uint64_t idx, const std::string &sCommand); + unsigned char *m_pPartialPkt; + int m_PPktLen; + void ReceiveMessage(const char *pData, int Len); +diff --git a/main/EventSystem.cpp b/main/EventSystem.cpp +index cdd3968b..19562d37 100644 +--- a/main/EventSystem.cpp ++++ b/main/EventSystem.cpp +@@ -2481,6 +2481,21 @@ bool CEventSystem::parseBlocklyActions(const _tEventItem &item) + actionsDone = true; + continue; + } ++ else if (deviceName.find("CustomCommand:") == 0) ++ { ++ int idx = atoi(deviceName.substr(14).c_str()); ++ float afterTimerSeconds = 0; ++ size_t aFind = doWhat.find(" AFTER "); ++ if ((aFind > 0) && (aFind != std::string::npos)) { ++ std::string delayString = doWhat.substr(aFind + 7); ++ afterTimerSeconds = static_cast(atof(delayString.c_str())); ++ doWhat = doWhat.substr(0, aFind); ++ StripQuotes(doWhat); ++ } ++ m_sql.AddTaskItem(_tTaskItem::CustomCommand(afterTimerSeconds, idx, doWhat)); ++ actionsDone = true; ++ continue; ++ } + else + { + _log.Log(LOG_ERROR, "EventSystem: Unknown action sequence! (%s)", csubstr.c_str()); +@@ -2623,6 +2638,19 @@ bool CEventSystem::PythonScheduleEvent(std::string ID, const std::string &Action + return false; + } + ++ return true; ++ } else if(ID.find("CustomCommand:") == 0) { ++ int idx = atoi(ID.substr(14).c_str()); ++ std::string doWhat = std::string(Action); ++ float afterTimerSeconds = 0; ++ size_t aFind = Action.find(" AFTER "); ++ if ((aFind > 0) && (aFind != std::string::npos)) { ++ std::string delayString = doWhat.substr(aFind + 7); ++ doWhat = doWhat.substr(0, aFind); ++ afterTimerSeconds = static_cast(atof(delayString.c_str())); ++ StripQuotes(doWhat); ++ } ++ m_sql.AddTaskItem(_tTaskItem::CustomCommand(afterTimerSeconds, idx, doWhat)); + return true; + } + return ScheduleEvent(ID, Action,eventName); +@@ -3540,6 +3568,20 @@ bool CEventSystem::processLuaCommand(lua_State *lua_state, const std::string &fi + return false; + } + } ++ else if (lCommand.find("CustomCommand:") == 0) ++ { ++ int idx = atoi(lCommand.substr(14).c_str()); ++ std::string luaString = lua_tostring(lua_state, -1); ++ float afterTimerSeconds = 0; ++ size_t aFind = luaString.find(" AFTER "); ++ if ((aFind > 0) && (aFind != std::string::npos)) { ++ std::string delayString = luaString.substr(aFind + 7); ++ afterTimerSeconds = static_cast(atof(delayString.c_str())); ++ luaString = luaString.substr(0, aFind); ++ StripQuotes(luaString); ++ } ++ m_sql.AddTaskItem(_tTaskItem::CustomCommand(afterTimerSeconds, idx, luaString)); ++ } + else + { + if (ScheduleEvent(lua_tostring(lua_state, -2), lua_tostring(lua_state, -1), filename)) { +@@ -3557,6 +3599,21 @@ void CEventSystem::report_errors(lua_State *L, int status, std::string filename) + } + } + ++bool CEventSystem::CustomCommand(const uint64_t idx, const std::string &sCommand) ++{ ++ std::vector > result; ++ result = m_sql.safe_query("SELECT H.ID FROM DeviceStatus DS, Hardware H WHERE (DS.ID=='%u') AND (DS.HardwareID == H.ID)", idx); ++ if (result.size() != 1) ++ return false; ++ ++ int HardwareID = atoi(result[0][0].c_str()); ++ CDomoticzHardwareBase *pHardware = m_mainworker.GetHardware(HardwareID); ++ if (!pHardware) ++ return false; ++ ++ return pHardware->CustomCommand(idx, sCommand); ++} ++ + void CEventSystem::UpdateDevice(const uint64_t idx, const int nValue, const std::string &sValue, const int Protected, const bool bEventTrigger) + { + //Get device parameters +diff --git a/main/EventSystem.h b/main/EventSystem.h +index d154c4e8..cfebe2cc 100644 +--- a/main/EventSystem.h ++++ b/main/EventSystem.h +@@ -131,6 +131,7 @@ public: + bool GetEventTrigger(const uint64_t ulDevID, const _eReason reason, const bool bEventTrigger); + void SetEventTrigger(const uint64_t ulDevID, const _eReason reason, const float fDelayTime); + void UpdateDevice(const uint64_t idx, const int nValue, const std::string &sValue, const int Protected, const bool bEventTrigger = false); ++ bool CustomCommand(const uint64_t idx, const std::string &sCommand); + + void TriggerURL(const std::string &result, const std::vector &headerData, const std::string &callback); + +diff --git a/main/SQLHelper.cpp b/main/SQLHelper.cpp +index 7a46f021..0ea71d54 100644 +--- a/main/SQLHelper.cpp ++++ b/main/SQLHelper.cpp +@@ -3401,6 +3401,10 @@ void CSQLHelper::Do_Work() + { + m_mainworker.m_eventsystem.UpdateDevice(itt->_idx, itt->_nValue, itt->_sValue, itt->_HardwareID, (itt->_switchtype ? true : false)); + } ++ else if (itt->_ItemType == TITEM_CUSTOM_COMMAND) ++ { ++ m_mainworker.m_eventsystem.CustomCommand(itt->_idx, itt->_command); ++ } + + ++itt; + } +diff --git a/main/SQLHelper.h b/main/SQLHelper.h +index c0d40580..8ad60e3d 100644 +--- a/main/SQLHelper.h ++++ b/main/SQLHelper.h +@@ -49,7 +49,8 @@ enum _eTaskItemType + TITEM_SEND_NOTIFICATION, + TITEM_SET_SETPOINT, + TITEM_SEND_IFTTT_TRIGGER, +- TITEM_UPDATEDEVICE ++ TITEM_UPDATEDEVICE, ++ TITEM_CUSTOM_COMMAND, + }; + + struct _tTaskItem +@@ -261,6 +262,18 @@ struct _tTaskItem + tItem._sValue = varvalue; + tItem._command = mode; + tItem._sUntil = until; ++ ++ if (DelayTime) ++ getclock(&tItem._DelayTimeBegin); ++ return tItem; ++ } ++ static _tTaskItem CustomCommand(const float DelayTime, const uint64_t idx, const std::string &cmdstr) ++ { ++ _tTaskItem tItem; ++ tItem._ItemType = TITEM_CUSTOM_COMMAND; ++ tItem._DelayTime = DelayTime; ++ tItem._idx = idx; ++ tItem._command = cmdstr; + if (DelayTime) + getclock(&tItem._DelayTimeBegin); + return tItem; +-- +2.17.0 +