domoticz: update to 3.9571 and clean up FHS handling
authorDavid Woodhouse <dwmw2@infradead.org>
Sun, 13 May 2018 14:52:50 +0000 (15:52 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Mon, 25 Jun 2018 14:26:25 +0000 (15:26 +0100)
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 <dwmw2@infradead.org>
utils/domoticz/Makefile
utils/domoticz/files/domoticz.init
utils/domoticz/patches/001-Make-compatible-with-boost-1.66.patch [deleted file]
utils/domoticz/patches/900_fix-build.patch [deleted file]
utils/domoticz/patches/901_no-udev.patch [deleted file]
utils/domoticz/patches/902_disable-libusb.patch [deleted file]
utils/domoticz/patches/903_fhs.patch [deleted file]

index ba240960dce06b2d9d56ade2cffed6c821d7ea83..8fc93e5aff64d427a8b1c096740a7372c6bff524 100644 (file)
@@ -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))
index 16e986e5ea9bb72e5536ca47175a0e89a31dc817..89aaeae0c812fe4bd7101f0042ca9dd7e3d517ad 100644 (file)
@@ -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 (file)
index 77c183c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-From 11a29e071019645967ee748d410954ec5f73866f Mon Sep 17 00:00:00 2001
-From: Rob Peters <ROb@DVBControl.com>
-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 @@
-       <PrecompiledHeader>Use</PrecompiledHeader>
-       <WarningLevel>Level3</WarningLevel>
-       <Optimization>Disabled</Optimization>
--      <PreprocessorDefinitions>WIN32;ENABLE_PYTHON;_DEBUG;PTW32_STATIC_LIB;WITH_OPENZWAVE;OPENZWAVE_USEDLL;WWW_ENABLE_SSL;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-+      <PreprocessorDefinitions>WIN32;ENABLE_PYTHON;_DEBUG;PTW32_STATIC_LIB;WITH_OPENZWAVE;OPENZWAVE_USEDLL;WWW_ENABLE_SSL;_CONSOLE;BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-       <AdditionalIncludeDirectories>./Windows Libraries/Boost/boost_1_63_0;./libusb;../MQTT;..\hardware\openzwave;./Windows Libraries/openssl;./Windows Libraries/Curl;./Windows Libraries/pthread;../hardware/plugins/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-       <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-       <EnablePREfast>false</EnablePREfast>
-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<ssl_server_settings const &>(settings)),
--              context_(io_service_, dynamic_cast<ssl_server_settings const &>(settings).get_ssl_method()) {
-+              context_(dynamic_cast<ssl_server_settings const &>(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 (file)
index b9fbebd..0000000
+++ /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 (file)
index 0ea9dd9..0000000
+++ /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 (file)
index f4f03c3..0000000
+++ /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 (file)
index 11e531a..0000000
+++ /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 <string>
--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<boost::thread>(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<boost::shared_mutex> 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')