Fix for boost 1.87

Removed the diff for the msbuild project files, didn't apply cleanly and not relevant anyway.
This will merged in the next stable of domoticz.

Pullrequest: https://github.com/domoticz/domoticz/pull/6252
Patch: https://patch-diff.githubusercontent.com/raw/domoticz/domoticz/pull/6252.patch-diff

diff --git hardware/ASyncSerial.cpp hardware/ASyncSerial.cpp
index 52c950d..6147cdb 100644
--- hardware/ASyncSerial.cpp
+++ hardware/ASyncSerial.cpp
@@ -54,7 +54,7 @@ public:
   {
   }
 
-    boost::asio::io_service io; ///< Io service object
+    boost::asio::io_context io; ///< Io service object
     boost::asio::serial_port port; ///< Serial port object
     boost::thread backgroundThread; ///< Thread that runs read/write operations
     bool open{ false };		    ///< True if port open
@@ -117,10 +117,10 @@ void AsyncSerial::open(const std::string& devname, unsigned int baud_rate,
 		throw;
 	}
 
-	pimpl->io.reset();
+	pimpl->io.restart();
 
-	// This gives some work to the io_service before it is started
-	pimpl->io.post([this] { return doRead(); });
+	// This gives some work to the io_context before it is started
+	boost::asio::post(pimpl->io, [this] { return doRead(); });
 
 	boost::thread t([p = &pimpl->io] { p->run(); });
 	pimpl->backgroundThread.swap(t);
@@ -149,10 +149,10 @@ void AsyncSerial::openOnlyBaud(const std::string& devname, unsigned int baud_rat
 		throw;
 	}
 
-	pimpl->io.reset();
+	pimpl->io.restart();
 
-	//This gives some work to the io_service before it is started
-	pimpl->io.post([this] { return doRead(); });
+	//This gives some work to the io_context before it is started
+	boost::asio::post(pimpl->io, [this] { return doRead(); });
 
 	boost::thread t([p = &pimpl->io] { p->run(); });
 	pimpl->backgroundThread.swap(t);
@@ -176,9 +176,9 @@ void AsyncSerial::close()
     if(!isOpen()) return;
 
     pimpl->open = false;
-    pimpl->io.post([this] { doClose(); });
+    boost::asio::post(pimpl->io, [this] { doClose(); });
     pimpl->backgroundThread.join();
-    pimpl->io.reset();
+    pimpl->io.restart();
     if(errorStatus())
     {
         throw(boost::system::system_error(boost::system::error_code(),
@@ -192,7 +192,7 @@ void AsyncSerial::write(const char *data, size_t size)
         std::lock_guard<std::mutex> l(pimpl->writeQueueMutex);
         pimpl->writeQueue.insert(pimpl->writeQueue.end(),data,data+size);
     }
-    pimpl->io.post([this] { doWrite(); });
+    boost::asio::post(pimpl->io, [this] { doWrite(); });
 }
 
 void AsyncSerial::write(const std::string &data)
@@ -201,7 +201,7 @@ void AsyncSerial::write(const std::string &data)
 		std::lock_guard<std::mutex> l(pimpl->writeQueueMutex);
 		pimpl->writeQueue.insert(pimpl->writeQueue.end(), data.c_str(), data.c_str()+data.size());
 	}
-	pimpl->io.post([this] { doWrite(); });
+	boost::asio::post(pimpl->io, [this] { doWrite(); });
 }
 
 void AsyncSerial::write(const std::vector<char>& data)
@@ -211,7 +211,7 @@ void AsyncSerial::write(const std::vector<char>& data)
         pimpl->writeQueue.insert(pimpl->writeQueue.end(),data.begin(),
                 data.end());
     }
-    pimpl->io.post([this] { doWrite(); });
+    boost::asio::post(pimpl->io, [this] { doWrite(); });
 }
 
 void AsyncSerial::writeString(const std::string& s)
@@ -220,7 +220,7 @@ void AsyncSerial::writeString(const std::string& s)
         std::lock_guard<std::mutex> l(pimpl->writeQueueMutex);
         pimpl->writeQueue.insert(pimpl->writeQueue.end(),s.begin(),s.end());
     }
-    pimpl->io.post([this] { doWrite(); });
+    boost::asio::post(pimpl->io, [this] { doWrite(); });
 }
 
 void AsyncSerial::doRead()
diff --git hardware/ASyncSerial.h hardware/ASyncSerial.h
index 0a51ef0..de83f8a 100644
--- hardware/ASyncSerial.h
+++ hardware/ASyncSerial.h
@@ -123,27 +123,27 @@ class AsyncSerial : private domoticz::noncopyable
 
 	/**
 	 * Callback called to start an asynchronous read operation.
-	 * This callback is called by the io_service in the spawned thread.
+	 * This callback is called by the io_context in the spawned thread.
 	 */
 	void doRead();
 
 	/**
 	 * Callback called at the end of the asynchronous operation.
-	 * This callback is called by the io_service in the spawned thread.
+	 * This callback is called by the io_context in the spawned thread.
 	 */
 	void readEnd(const boost::system::error_code &error, size_t bytes_transferred);
 
 	/**
 	 * Callback called to start an asynchronous write operation.
 	 * If it is already in progress, does nothing.
-	 * This callback is called by the io_service in the spawned thread.
+	 * This callback is called by the io_context in the spawned thread.
 	 */
 	void doWrite();
 
 	/**
 	 * Callback called at the end of an asynchronuous write operation,
 	 * if there is more data to write, restarts a new write operation.
-	 * This callback is called by the io_service in the spawned thread.
+	 * This callback is called by the io_context in the spawned thread.
 	 */
 	void writeEnd(const boost::system::error_code &error);
 
diff --git hardware/ASyncTCP.cpp hardware/ASyncTCP.cpp
index a375561..7c3b536 100644
--- hardware/ASyncTCP.cpp
+++ hardware/ASyncTCP.cpp
@@ -4,213 +4,241 @@
 #include <boost/system/error_code.hpp>     // for error_code
 #include "../main/Logger.h"
 
-struct hostent;
-
 #define MAX_TCP_BUFFER_SIZE 4096
 
-#ifndef WIN32
-	#include <unistd.h> //gethostbyname
-#endif
-
 #define STATUS_OK(err) !err
-
-ASyncTCP::ASyncTCP(const bool secure)
+#define STATUS_ERR(err) err
+
+ASyncTCP::ASyncTCP(const bool secure) :
+	m_Tcpwork(boost::asio::make_work_guard(m_io_context))
+	, m_Socket(m_io_context)
+	, m_Resolver(m_io_context)
+	, m_ReconnectTimer(m_io_context)
+	, m_TimeoutTimer(m_io_context)
+	, m_SendStrand(m_io_context)
 #ifdef WWW_ENABLE_SSL
-	: mSecure(secure)
+	, m_bSecure(secure)
 #endif
 {
 	m_pRXBuffer = new uint8_t[MAX_TCP_BUFFER_SIZE];
 #ifdef WWW_ENABLE_SSL
 	mContext.set_verify_mode(boost::asio::ssl::verify_none);
-	if (mSecure) 
+	if (m_bSecure)
 	{
-		mSslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(mIos, mContext));
+		m_SslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_context, mContext));
 	}
 #endif
 }
 
 ASyncTCP::~ASyncTCP()
 {
-	assert(mTcpthread == nullptr);
-	mIsTerminating = true;
-	if (mTcpthread)
+	assert(m_Tcpthread == nullptr);
+	m_bIsTerminating = true;
+	if (m_Tcpthread)
 	{
 		//This should never happen. terminate() never called!!
-		_log.Log(LOG_ERROR, "ASyncTCP: Workerthread not closed. terminate() never called!!!");
-		mIos.stop();
-		if (mTcpthread)
+		_log.Log(LOG_ERROR, "ASyncTCP: Worker thread not closed. terminate() never called!!!");
+		m_io_context.stop();
+		if (m_Tcpthread)
 		{
-			mTcpthread->join();
-			mTcpthread.reset();
+			m_Tcpthread->join();
+			m_Tcpthread.reset();
 		}
 	}
 	if (m_pRXBuffer != nullptr)
 		delete[] m_pRXBuffer;
 }
 
-void ASyncTCP::SetReconnectDelay(int32_t Delay)
+void ASyncTCP::SetReconnectDelay(const int32_t Delay)
 {
-	mReconnectDelay = Delay;
+	m_iReconnectDelay = Delay;
 }
 
 void ASyncTCP::connect(const std::string& ip, uint16_t port)
 {
-	assert(!mSocket.is_open());
-	if (mSocket.is_open())
+	assert(!m_Socket.is_open());
+	if (m_Socket.is_open())
 	{
 		_log.Log(LOG_ERROR, "ASyncTCP: connect called while socket is still open. !!!");
 		terminate();
 	}
 
-	// RK: We reset mIos here because it might have been stopped in terminate()
-	mIos.reset();
-	// RK: After the reset, we need to provide it work anew
-	mTcpwork = std::make_shared<boost::asio::io_service::work>(mIos);
-	if (!mTcpthread)
-		mTcpthread = std::make_shared<std::thread>([p = &mIos] { p->run(); });
-
-	mIp = ip;
-	mPort = port;
+	m_IP = ip;
+	m_Port = port;
 	std::string port_str = std::to_string(port);
-	boost::asio::ip::tcp::resolver::query query(ip, port_str);
 	timeout_start_timer();
-	mResolver.async_resolve(query, [this](auto &&err, auto &&iter) { cb_resolve_done(err, iter); });
+
+	m_Resolver.async_resolve(
+		ip, port_str,
+		[this](const boost::system::error_code& error, const boost::asio::ip::tcp::resolver::results_type& endpoints) {
+			handle_resolve(error, endpoints);
+		}
+	);
+
+	// RK: We restart m_io_context here because it might have been stopped in terminate()
+	m_io_context.restart();
+	// RK: After the reset, we need to provide it work anew
+	m_Tcpwork.reset();
+	m_Tcpwork.emplace(boost::asio::make_work_guard(m_io_context));
+	if (!m_Tcpthread)
+		m_Tcpthread = std::make_shared<std::thread>([p = &m_io_context] { p->run(); });
 }
 
-void ASyncTCP::cb_resolve_done(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
+void ASyncTCP::handle_resolve(const boost::system::error_code& error, const boost::asio::ip::tcp::resolver::results_type &endpoints)
 {
-	if (mIsTerminating) return;
+	if (m_bIsTerminating) return;
 
-	if (STATUS_OK(error))
-	{
-		connect_start(endpoint_iterator);
-	}
-	else
+	if (STATUS_ERR(error))
 	{
 		process_error(error);
+		return;
 	}
-}
-
-void ASyncTCP::connect_start(boost::asio::ip::tcp::resolver::iterator& endpoint_iterator)
-{
-	if (mIsConnected) return;
-
-	mEndPoint = *endpoint_iterator++;
+	if (m_bIsConnected) return;
 
 	timeout_start_timer();
+
 #ifdef WWW_ENABLE_SSL
-	if (mSecure)
+	if (m_bSecure)
 	{
 		// we reset the ssl socket, because the ssl context needs to be reinitialized after a reconnect
-		mSslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(mIos, mContext));
-		mSslSocket->lowest_layer().async_connect(mEndPoint, [this, endpoint_iterator](auto &&err) mutable { cb_connect_done(err, endpoint_iterator); });
+		m_SslSocket.reset(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(m_io_context, mContext));
+		boost::asio::async_connect(m_SslSocket->lowest_layer(), endpoints,
+			[this](const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint)
+			{
+				handle_connect(error, endpoint);
+			}
+		);
 	}
 	else
 #endif
 	{
-		mSocket.async_connect(mEndPoint, [this, endpoint_iterator](auto &&err) mutable { cb_connect_done(err, endpoint_iterator); });
+		boost::asio::async_connect(m_Socket, endpoints,
+			[this](const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint)
+			{
+				handle_connect(error, endpoint);
+			}
+		);
 	}
 }
 
-void ASyncTCP::cb_connect_done(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator &endpoint_iterator)
+void ASyncTCP::handle_connect(const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& /*endpoint*/)
 {
-	if (mIsTerminating) return;
+	if (m_bIsTerminating) return;
 
-	if (STATUS_OK(error))
+	if (STATUS_ERR(error))
 	{
+		process_error(error);
+		return;
+	}
 #ifdef WWW_ENABLE_SSL
-		if (mSecure) 
-		{
-			timeout_start_timer();
-			mSslSocket->async_handshake(boost::asio::ssl::stream_base::client, [this](auto &&err) { cb_handshake_done(err); });
-		}
-		else
-#endif
-		{
-			process_connection();
-		}
+	if (m_bSecure)
+	{
+		timeout_start_timer();
+		m_SslSocket->async_handshake(boost::asio::ssl::stream_base::client,
+			[this](const boost::system::error_code& error) {
+				cb_handshake_done(error);
+			}
+		);
 	}
-	else 
+	else
+#endif
 	{
-		if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) 
-		{
-			// The connection failed. Try the next endpoint in the list.
-			connect_start(endpoint_iterator);
-			return;
-		}
-		process_error(error);
+		process_connection();
 	}
 }
 
 #ifdef WWW_ENABLE_SSL
 void ASyncTCP::cb_handshake_done(const boost::system::error_code& error)
 {
-	if (mIsTerminating) return;
+	if (m_bIsTerminating) return;
 
-	if (STATUS_OK(error))
-	{
-		process_connection();
-	}
-	else
+	if (STATUS_ERR(error))
 	{
 		process_error(error);
+		return;
 	}
+	process_connection();
+#endif
 }
+
+void ASyncTCP::process_connection()
+{
+	m_bIsConnected = true;
+#ifdef WWW_ENABLE_SSL
+
+	if (!m_bSecure)
 #endif
+	{
+		// RK: only if non-secure
+		boost::asio::socket_base::keep_alive option(true);
+		m_Socket.set_option(option);
+	}
+	OnConnect();
+	do_read_start();
+	do_write_start();
+}
 
 void ASyncTCP::reconnect_start_timer()
 {
-	if (mIsReconnecting) return;
+	if (m_bIsReconnecting) return;
 
-	if (mReconnectDelay != 0)
+	if (m_iReconnectDelay != 0)
 	{
-		mIsReconnecting = true;
-
-		mReconnectTimer.expires_from_now(boost::posix_time::seconds(mReconnectDelay));
-		mReconnectTimer.async_wait([this](auto &&err) { cb_reconnect_start(err); });
+		m_bIsReconnecting = true;
+
+		m_ReconnectTimer.expires_from_now(boost::posix_time::seconds(m_iReconnectDelay));
+		m_ReconnectTimer.async_wait(
+			[this](const boost::system::error_code& error) {
+				cb_reconnect_start(error);
+			}
+		);
 	}
 }
 
 void ASyncTCP::cb_reconnect_start(const boost::system::error_code& error)
 {
-	mIsReconnecting = false;
-	mReconnectTimer.cancel();
-	mTimeoutTimer.cancel();
+	m_bIsReconnecting = false;
+	m_ReconnectTimer.cancel();
+	m_TimeoutTimer.cancel();
 
-	if (mIsConnected) return;
+	if (m_bIsConnected) return;
 	if (error) return; // timer was cancelled
 
 	do_close();
-	connect(mIp, mPort);
+	connect(m_IP, m_Port);
 }
 
 
 void ASyncTCP::terminate(const bool silent)
 {
-	mIsTerminating = true;
+	m_bIsTerminating = true;
 	disconnect(silent);
-	mTcpwork.reset();
-	mIos.stop();
-	if (mTcpthread)
+	m_Tcpwork.reset();
+	m_io_context.stop();
+	if (m_Tcpthread)
 	{
-		mTcpthread->join();
-		mTcpthread.reset();
+		m_Tcpthread->join();
+		m_Tcpthread.reset();
 	}
-	mIsReconnecting = false;
-	mIsConnected = false;
-	mWriteQ.clear();
-	mIsTerminating = false;
+	m_bIsReconnecting = false;
+	m_bIsConnected = false;
+	m_WriteQ.clear();
+	m_bIsTerminating = false;
 }
 
 void ASyncTCP::disconnect(const bool silent)
 {
-	mReconnectTimer.cancel();
-	mTimeoutTimer.cancel();
-	if (!mTcpthread) return;
+	m_ReconnectTimer.cancel();
+	m_TimeoutTimer.cancel();
+	if (!m_Tcpthread) return;
 
 	try
 	{
-		mIos.post([this] { do_close(); });
+		boost::asio::post(m_io_context, 
+			[this] {
+				do_close();
+			}
+		);
 	}
 	catch (...)
 	{
@@ -223,62 +251,68 @@ void ASyncTCP::disconnect(const bool silent)
 
 void ASyncTCP::do_close()
 {
-	if (mIsReconnecting) {
+	if (m_bIsReconnecting) {
 		return;
 	}
-	mReconnectTimer.cancel();
-	mTimeoutTimer.cancel();
+	m_ReconnectTimer.cancel();
+	m_TimeoutTimer.cancel();
 	boost::system::error_code ec;
 #ifdef WWW_ENABLE_SSL
-	if (mSecure)
+	if (m_bSecure)
 	{
-		if (mSslSocket->lowest_layer().is_open())
+		if (m_SslSocket->lowest_layer().is_open())
 		{
-			mSslSocket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
-			mSslSocket->lowest_layer().close(ec);
+			m_SslSocket->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
+			m_SslSocket->lowest_layer().close(ec);
 		}
 	}
 	else
 #endif
 	{
-		if (mSocket.is_open())
+		if (m_Socket.is_open())
 		{
-			mSocket.close(ec);
+			m_Socket.close(ec);
 		}
 	}
 }
 
 void ASyncTCP::do_read_start()
 {
-	if (mIsTerminating) return;
-	if (!mIsConnected) return;
+	if (m_bIsTerminating) return;
+	if (!m_bIsConnected) return;
 
 	timeout_start_timer();
 #ifdef WWW_ENABLE_SSL
-	if (mSecure)
+	if (m_bSecure)
 	{
-		mSslSocket->async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), [this](auto &&err, auto bytes) { cb_read_done(err, bytes); });
+		m_SslSocket->async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE),
+			[this](const boost::system::error_code& error, size_t bytes_transferred) {
+				cb_read_done(error, bytes_transferred);
+			}
+		);
 	}
 	else
 #endif
 	{
-		mSocket.async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE), [this](auto &&err, auto bytes) { cb_read_done(err, bytes); });
+		m_Socket.async_read_some(boost::asio::buffer(m_pRXBuffer, MAX_TCP_BUFFER_SIZE),
+			[this](const boost::system::error_code& error, size_t bytes_transferred) {
+				cb_read_done(error, bytes_transferred);
+			}
+		);
 	}
 }
 
 void ASyncTCP::cb_read_done(const boost::system::error_code& error, size_t bytes_transferred)
 {
-	if (mIsTerminating) return;
+	if (m_bIsTerminating) return;
 
-	if (STATUS_OK(error))
-	{
-		OnData(m_pRXBuffer, bytes_transferred);
-		do_read_start();
-	}
-	else
+	if (STATUS_ERR(error))
 	{
 		process_error(error);
+		return;
 	}
+	OnData(m_pRXBuffer, bytes_transferred);
+	do_read_start();
 }
 
 void ASyncTCP::write(const uint8_t* pData, size_t length)
@@ -288,77 +322,66 @@ void ASyncTCP::write(const uint8_t* pData, size_t length)
 
 void ASyncTCP::write(const std::string& msg)
 {
-	if (!mTcpthread) return;
+	if (!m_Tcpthread) return;
 
-	mSendStrand.post([this, msg]() { cb_write_queue(msg); });
+	boost::asio::post(m_SendStrand, [this, msg]() { cb_write_queue(msg); });
 }
 
 void ASyncTCP::cb_write_queue(const std::string& msg)
 {
-	mWriteQ.push_back(msg);
+	m_WriteQ.push_back(msg);
 
-	if (mWriteQ.size() == 1)
+	if (m_WriteQ.size() == 1)
 		do_write_start();
 }
 
 void ASyncTCP::do_write_start()
 {
-	if (mIsTerminating) return;
-	if (!mIsConnected) return;
-	if (mWriteQ.empty())
+	if (m_bIsTerminating) return;
+	if (!m_bIsConnected) return;
+	if (m_WriteQ.empty())
 		return;
 
 	timeout_start_timer();
 #ifdef WWW_ENABLE_SSL
-	if (mSecure) 
+	if (m_bSecure)
 	{
-		boost::asio::async_write(*mSslSocket, boost::asio::buffer(mWriteQ.front()), [this](auto &&err, auto) { cb_write_done(err); });
+		boost::asio::async_write(*m_SslSocket, boost::asio::buffer(m_WriteQ.front()),
+			[this](const boost::system::error_code& error, std::size_t length) {
+				cb_write_done(error, length);
+			}
+		);
 	}
 	else
 #endif
 	{
-		boost::asio::async_write(mSocket, boost::asio::buffer(mWriteQ.front()), [this](auto &&err, auto) { cb_write_done(err); });
+		boost::asio::async_write(m_Socket, boost::asio::buffer(m_WriteQ.front()),
+			[this](const boost::system::error_code& error, std::size_t length) {
+				cb_write_done(error, length);
+			}
+		);
 	}
 }
 
-void ASyncTCP::cb_write_done(const boost::system::error_code& error)
+void ASyncTCP::cb_write_done(const boost::system::error_code& error, std::size_t /*length*/)
 {
-	if (mIsTerminating) return;
+	if (m_bIsTerminating) return;
 
-	if (STATUS_OK(error))
-	{
-		mWriteQ.pop_front();
-		do_write_start();
-	}
-	else
+	if (STATUS_ERR(error))
 	{
 		process_error(error);
+		return;
 	}
-}
-
-void ASyncTCP::process_connection()
-{
-	mIsConnected = true;
-#ifdef WWW_ENABLE_SSL
-
-	if (!mSecure)
-#endif
-	{
-		// RK: only if non-secure
-		boost::asio::socket_base::keep_alive option(true);
-		mSocket.set_option(option);
-	}
-	OnConnect();
-	do_read_start();
+	m_WriteQ.pop_front();
 	do_write_start();
 }
 
 void ASyncTCP::process_error(const boost::system::error_code& error)
 {
 	do_close();
-	if (mIsConnected)
+	if (m_bIsConnected)
 	{
-		mIsConnected = false;
+		m_bIsConnected = false;
 		OnDisconnect();
 	}
 
@@ -369,20 +392,23 @@ void ASyncTCP::process_error(const boost::system::error_code& error)
 	reconnect_start_timer();
 }
 
-/* timeout methods */
 void ASyncTCP::timeout_start_timer()
 {
-	if (0 == mTimeoutDelay) {
+	if (0 == m_iTimeoutDelay) {
 		return;
 	}
 	timeout_cancel_timer();
-	mTimeoutTimer.expires_from_now(boost::posix_time::seconds(mTimeoutDelay));
-	mTimeoutTimer.async_wait([this](auto &&err) { timeout_handler(err); });
+	m_TimeoutTimer.expires_from_now(boost::posix_time::seconds(m_iTimeoutDelay));
+	m_TimeoutTimer.async_wait(
+		[this](const boost::system::error_code& error) {
+			timeout_handler(error);
+		}
+	);
 }
 
 void ASyncTCP::timeout_cancel_timer()
 {
-	mTimeoutTimer.cancel();
+	m_TimeoutTimer.cancel();
 }
 
 void ASyncTCP::timeout_handler(const boost::system::error_code& error)
@@ -397,5 +423,5 @@ void ASyncTCP::timeout_handler(const boost::system::error_code& error)
 
 void ASyncTCP::SetTimeout(const uint32_t Timeout)
 {
-	mTimeoutDelay = Timeout;
+	m_iTimeoutDelay = Timeout;
 }
diff --git hardware/ASyncTCP.h hardware/ASyncTCP.h
index cf859bb..a8b3ae2 100644
--- hardware/ASyncTCP.h
+++ hardware/ASyncTCP.h
@@ -3,39 +3,31 @@
 #include <stddef.h>			 // for size_t
 #include <deque>			 // for write queue
 #include <boost/asio/deadline_timer.hpp> // for deadline_timer
-#include <boost/asio/io_service.hpp>	 // for io_service
+#include <boost/asio/io_context.hpp>	 // for io_context
 #include <boost/asio/strand.hpp>	 // for strand
 #include <boost/asio/ip/tcp.hpp>	 // for tcp, tcp::endpoint, tcp::s...
 #include <boost/asio/ssl.hpp>		 // for secure sockets
 #include <boost/asio/ssl/stream.hpp>	 // for secure sockets
 #include <exception>			  // for exception
+#include <optional>			// for optional
 
 #define ASYNCTCP_THREAD_NAME "ASyncTCP"
 #define DEFAULT_RECONNECT_TIME 30
 #define DEFAULT_TIMEOUT_TIME 60
 
-namespace boost
-{
-	namespace system
-	{
-		class error_code;
-	} // namespace system
-} // namespace boost
-
 class ASyncTCP
 {
-      protected:
+protected:
 	ASyncTCP(bool secure = false);
 	virtual ~ASyncTCP();
-
-	void connect(const std::string &hostname, uint16_t port);
+	void connect(const std::string& hostname, uint16_t port);
 	void disconnect(bool silent = true);
-	void write(const std::string &msg);
-	void write(const uint8_t *pData, size_t length);
-	void SetReconnectDelay(int32_t Delay = DEFAULT_RECONNECT_TIME);
+	void write(const std::string& msg);
+	void write(const uint8_t* pData, size_t length);
+	void SetReconnectDelay(const int32_t Delay = DEFAULT_RECONNECT_TIME);
 	bool isConnected()
 	{
-		return mIsConnected;
+		return m_bIsConnected;
 	};
 	void terminate(bool silent = true);
 	void SetTimeout(uint32_t Timeout = DEFAULT_TIMEOUT_TIME);
@@ -43,65 +35,61 @@ class ASyncTCP
 	// Callback interface to implement in derived classes
 	virtual void OnConnect() = 0;
 	virtual void OnDisconnect() = 0;
-	virtual void OnData(const uint8_t *pData, size_t length) = 0;
-	virtual void OnError(const boost::system::error_code &error) = 0;
-
-	boost::asio::io_service mIos; // protected to allow derived classes to attach timers etc.
+	virtual void OnData(const uint8_t* pData, size_t length) = 0;
+	virtual void OnError(const boost::system::error_code& error) = 0;
 
-      private:
-	void cb_resolve_done(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
-	void connect_start(boost::asio::ip::tcp::resolver::iterator &endpoint_iterator);
-	void cb_connect_done(const boost::system::error_code &error, boost::asio::ip::tcp::resolver::iterator &endpoint_iterator);
+	boost::asio::io_context m_io_context; // protected to allow derived classes to attach timers etc.
+private:
+	void handle_resolve(const boost::system::error_code& ec, const boost::asio::ip::tcp::resolver::results_type &results);
+	void handle_connect(const boost::system::error_code& error, const boost::asio::ip::tcp::endpoint& endpoint);
 #ifdef WWW_ENABLE_SSL
-	void cb_handshake_done(const boost::system::error_code &error);
+	void cb_handshake_done(const boost::system::error_code& error);
 #endif
 
-	/* timeout methods */
 	void timeout_start_timer();
 	void timeout_cancel_timer();
 	void reconnect_start_timer();
-	void timeout_handler(const boost::system::error_code &error);
+	void timeout_handler(const boost::system::error_code& error);
 
-	void cb_reconnect_start(const boost::system::error_code &error);
+	void cb_reconnect_start(const boost::system::error_code& error);
 
 	void do_close();
 
 	void do_read_start();
-	void cb_read_done(const boost::system::error_code &error, size_t bytes_transferred);
+	void cb_read_done(const boost::system::error_code& error, size_t bytes_transferred);
 
-	void cb_write_queue(const std::string &msg);
+	void cb_write_queue(const std::string& msg);
 	void do_write_start();
-	void cb_write_done(const boost::system::error_code &error);
+	void cb_write_done(const boost::system::error_code& error, size_t length);
 
 	void process_connection();
-	void process_error(const boost::system::error_code &error);
+	void process_error(const boost::system::error_code& error);
 
-	bool mIsConnected = false;
-	bool mIsReconnecting = false;
-	bool mIsTerminating = false;
+	bool m_bIsConnected = false;
+	bool m_bIsReconnecting = false;
+	bool m_bIsTerminating = false;
 
-	boost::asio::io_service::strand mSendStrand{ mIos };
-	std::deque<std::string> mWriteQ; // we need a write queue to allow concurrent writes
+	boost::asio::io_context::strand m_SendStrand;
+	std::deque<std::string> m_WriteQ; // we need a write queue to allow concurrent writes
 
 	uint8_t* m_pRXBuffer = nullptr;
 
-	int mReconnectDelay = DEFAULT_RECONNECT_TIME;
-	int mTimeoutDelay = 0;
-	boost::asio::deadline_timer mReconnectTimer{ mIos };
-	boost::asio::deadline_timer mTimeoutTimer{ mIos };
+	int m_iReconnectDelay = DEFAULT_RECONNECT_TIME;
+	int m_iTimeoutDelay = 0;
+	boost::asio::deadline_timer m_ReconnectTimer;
+	boost::asio::deadline_timer m_TimeoutTimer;
 
-	std::shared_ptr<std::thread> mTcpthread;
-	std::shared_ptr<boost::asio::io_service::work> mTcpwork;
+	std::shared_ptr<std::thread> m_Tcpthread;
+	std::optional<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> m_Tcpwork;
 
 #ifdef WWW_ENABLE_SSL
-	const bool mSecure;
+	const bool m_bSecure;
 	boost::asio::ssl::context mContext{ boost::asio::ssl::context::sslv23 };
-	std::shared_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> mSslSocket; // the ssl socket
+	std::shared_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> m_SslSocket;
 #endif
-	boost::asio::ip::tcp::socket mSocket{ mIos };
-	boost::asio::ip::tcp::endpoint mEndPoint;
-	boost::asio::ip::tcp::resolver mResolver{ mIos };
+	boost::asio::ip::tcp::socket m_Socket;
+	boost::asio::ip::tcp::resolver m_Resolver;
 
-	std::string mIp;
-	uint16_t mPort;
+	std::string m_IP;
+	uint16_t m_Port;
 };
diff --git hardware/Arilux.cpp hardware/Arilux.cpp
index 400f5a3..20bc373 100644
--- hardware/Arilux.cpp
+++ hardware/Arilux.cpp
@@ -79,7 +79,7 @@ void Arilux::InsertUpdateSwitch(const std::string &lightName, const int subType,
 {
 	uint32_t sID;
 	try {
-		sID = boost::asio::ip::address_v4::from_string(location).to_ulong();
+		sID = boost::asio::ip::make_address_v4(location).to_uint();
 	} catch (const std::exception &e) {
 		Log(LOG_ERROR, "Bad IP address: %s (%s)", location.c_str(), e.what());
 		return;
@@ -112,8 +112,8 @@ bool Arilux::SendTCPCommand(uint32_t ip,std::vector<unsigned char> &command)
 	sum = sum & 0xFF;
 	command.push_back((unsigned char)sum);
 
-	boost::asio::io_service io_service;
-	boost::asio::ip::tcp::socket sendSocket(io_service);
+	boost::asio::io_context io_context;
+	boost::asio::ip::tcp::socket sendSocket(io_context);
 	boost::asio::ip::address_v4 address(ip);
 	boost::asio::ip::tcp::endpoint endpoint(address, 5577);
 	try
diff --git hardware/Kodi.cpp hardware/Kodi.cpp
index b528017..5ababf6 100644
--- hardware/Kodi.cpp
+++ hardware/Kodi.cpp
@@ -143,14 +143,14 @@ _eNotificationTypes	CKodiNode::CKodiStatus::NotificationType()
 	}
 }
 
-CKodiNode::CKodiNode(boost::asio::io_service *pIos, const int pHwdID, const int PollIntervalsec, const int pTimeoutMs,
+CKodiNode::CKodiNode(boost::asio::io_context *pIoc, const int pHwdID, const int PollIntervalsec, const int pTimeoutMs,
 	const std::string& pID, const std::string& pName, const std::string& pIP, const std::string& pPort)
 {
 	m_Busy = false;
 	m_Stoppable = false;
 	m_PlaylistPosition = 0;
 
-	m_Ios = pIos;
+	m_Ioc = pIoc;
 	m_HwdID = pHwdID;
 	m_DevID = atoi(pID.c_str());
 	sprintf(m_szDevID, "%X%02X%02X%02X", 0, 0, (m_DevID & 0xFF00) >> 8, m_DevID & 0xFF);
@@ -581,11 +581,10 @@ void CKodiNode::handleConnect()
 		{
 			m_iMissedPongs = 0;
 			boost::system::error_code ec;
-			boost::asio::ip::tcp::resolver resolver(*m_Ios);
-			boost::asio::ip::tcp::resolver::query query(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1)));
-			auto iter = resolver.resolve(query);
-			boost::asio::ip::tcp::endpoint endpoint = *iter;
-			m_Socket = new boost::asio::ip::tcp::socket(*m_Ios);
+			boost::asio::ip::tcp::resolver resolver(*m_Ioc);
+			auto iter = resolver.resolve(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1)));
+			boost::asio::ip::tcp::endpoint endpoint = *iter.begin();
+			m_Socket = new boost::asio::ip::tcp::socket(*m_Ioc);
 			m_Socket->connect(endpoint, ec);
 			if (!ec)
 			{
@@ -975,19 +974,19 @@ void CKodi::Do_Work()
 					_log.Log(LOG_NORM, "Kodi: (%s) - Restarting thread.", node->m_Name.c_str());
 					boost::thread *tAsync = new boost::thread(&CKodiNode::Do_Work, node);
 					SetThreadName(tAsync->native_handle(), "KodiNode");
-					m_ios.stop();
+					m_ioc.stop();
 				}
 				if (node->IsOn())
 					bWorkToDo = true;
 			}
 
-			if (bWorkToDo && m_ios.stopped())  // make sure that there is a boost thread to service i/o operations
+			if (bWorkToDo && m_ioc.stopped())  // make sure that there is a boost thread to service i/o operations
 			{
-				m_ios.reset();
+				m_ioc.restart();
 				// Note that this is the only thread that handles async i/o so we don't
 				// need to worry about locking or concurrency issues when processing messages
 				_log.Log(LOG_NORM, "Kodi: Restarting I/O service thread.");
-				boost::thread bt([p = &m_ios] { p->run(); });
+				boost::thread bt([p = &m_ioc] { p->run(); });
 				SetThreadName(bt.native_handle(), "KodiIO");
 			}
 		}
@@ -1138,7 +1137,7 @@ void CKodi::ReloadNodes()
 {
 	UnloadNodes();
 
-	m_ios.reset();	// in case this is not the first time in
+	m_ioc.restart();	// in case this is not the first time in
 
 	std::vector<std::vector<std::string> > result;
 	result = m_sql.safe_query("SELECT ID,Name,MacAddress,Timeout FROM WOLNodes WHERE (HardwareID==%d)", m_HwdID);
@@ -1149,7 +1148,7 @@ void CKodi::ReloadNodes()
 		// create a vector to hold the nodes
 		for (const auto &sd : result)
 		{
-			auto pNode = std::make_shared<CKodiNode>(&m_ios, m_HwdID, m_iPollInterval, m_iPingTimeoutms, sd[0], sd[1], sd[2], sd[3]);
+			auto pNode = std::make_shared<CKodiNode>(&m_ioc, m_HwdID, m_iPollInterval, m_iPingTimeoutms, sd[0], sd[1], sd[2], sd[3]);
 			m_pNodes.push_back(pNode);
 		}
 		// start the threads to control each kodi
@@ -1161,7 +1160,7 @@ void CKodi::ReloadNodes()
 		}
 		sleep_milliseconds(100);
 		_log.Log(LOG_NORM, "Kodi: Starting I/O service thread.");
-		boost::thread bt([p = &m_ios] { p->run(); });
+		boost::thread bt([p = &m_ioc] { p->run(); });
 		SetThreadName(bt.native_handle(), "KodiIO");
 	}
 }
@@ -1170,10 +1169,10 @@ void CKodi::UnloadNodes()
 {
 	std::lock_guard<std::mutex> l(m_mutex);
 
-	m_ios.stop();	// stop the service if it is running
+	m_ioc.stop();	// stop the service if it is running
 	sleep_milliseconds(100);
 
-	while (((!m_pNodes.empty()) || (!m_ios.stopped())))
+	while (((!m_pNodes.empty()) || (!m_ioc.stopped())))
 	{
 		for (auto itt = m_pNodes.begin(); itt != m_pNodes.end(); ++itt)
 		{
diff --git hardware/Kodi.h hardware/Kodi.h
index 14f331c..4435740 100644
--- hardware/Kodi.h
+++ hardware/Kodi.h
@@ -150,7 +150,7 @@ class CKodiNode : public std::enable_shared_from_this<CKodiNode>, StoppableTask
 	};
 
       public:
-	CKodiNode(boost::asio::io_service *, int, int, int, const std::string &, const std::string &, const std::string &, const std::string &);
+	CKodiNode(boost::asio::io_context *, int, int, int, const std::string &, const std::string &, const std::string &, const std::string &);
 	~CKodiNode();
 	void Do_Work();
 	void SendCommand(const std::string &);
@@ -207,7 +207,7 @@ class CKodiNode : public std::enable_shared_from_this<CKodiNode>, StoppableTask
 	int m_iPollIntSec;
 	int m_iMissedPongs;
 	std::string m_sLastMessage;
-	boost::asio::io_service *m_Ios;
+	boost::asio::io_context *m_Ioc;
 	boost::asio::ip::tcp::socket *m_Socket;
 	std::array<char, 256> m_Buffer;
 };
@@ -243,5 +243,5 @@ class CKodi : public CDomoticzHardwareBase
 	int m_iPingTimeoutms;
 	std::shared_ptr<std::thread> m_thread;
 	std::mutex m_mutex;
-	boost::asio::io_service m_ios;
+	boost::asio::io_context m_ioc;
 };
diff --git hardware/MQTTAutoDiscover.h hardware/MQTTAutoDiscover.h
index 0832664..1501d6f 100644
--- hardware/MQTTAutoDiscover.h
+++ hardware/MQTTAutoDiscover.h
@@ -176,7 +176,7 @@ public:
 	void on_message(const struct mosquitto_message *message) override;
 	void on_connect(int rc) override;
 	void on_disconnect(int rc) override;
-	void on_going_down();
+	void on_going_down() override;
 private:
 	void InsertUpdateSwitch(_tMQTTASensor* pSensor);
 
diff --git hardware/PanasonicTV.cpp hardware/PanasonicTV.cpp
index fc57d34..ce20565 100644
--- hardware/PanasonicTV.cpp
+++ hardware/PanasonicTV.cpp
@@ -356,18 +356,17 @@ std::string CPanasonicNode::handleWriteAndRead(const std::string& pMessageToSend
 {
 
 	_log.Debug(DEBUG_HARDWARE, "Panasonic Plugin: (%s) Handling message: '%s'.", m_Name.c_str(), pMessageToSend.c_str());
-	boost::asio::io_service io_service;
+	boost::asio::io_context io_context;
 	// Get a list of endpoints corresponding to the server name.
-	boost::asio::ip::tcp::resolver resolver(io_service);
-	boost::asio::ip::tcp::resolver::query query(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1)));
-	auto iter = resolver.resolve(query);
+	boost::asio::ip::tcp::resolver resolver(io_context);
+	auto endpoints = resolver.resolve(m_IP, (m_Port[0] != '-' ? m_Port : m_Port.substr(1)));
+	auto iter = endpoints.begin();
 	boost::asio::ip::tcp::endpoint endpoint = *iter;
-	boost::asio::ip::tcp::resolver::iterator end;
 
 	// Try each endpoint until we successfully establish a connection.
-	boost::asio::ip::tcp::socket socket(io_service);
+	boost::asio::ip::tcp::socket socket(io_context);
 	boost::system::error_code error = boost::asio::error::host_not_found;
-	while (error && iter != end)
+	while (error && iter != endpoints.end())
 	{
 		socket.close();
 		if (handleConnect(socket, *iter, error))
@@ -1060,7 +1059,7 @@ void CPanasonic::ReloadNodes()
 {
 	UnloadNodes();
 
-	//m_ios.reset();	// in case this is not the first time in
+	//m_ioc.reset();	// in case this is not the first time in
 
 	std::vector<std::vector<std::string> > result;
 	result = m_sql.safe_query("SELECT ID,Name,MacAddress,Timeout FROM WOLNodes WHERE (HardwareID==%d)", m_HwdID);
@@ -1088,10 +1087,10 @@ void CPanasonic::UnloadNodes()
 {
 	std::lock_guard<std::mutex> l(m_mutex);
 
-	m_ios.stop();	// stop the service if it is running
+	m_ioc.stop();	// stop the service if it is running
 	sleep_milliseconds(100);
 
-	while (((!m_pNodes.empty()) || (!m_ios.stopped())))
+	while (((!m_pNodes.empty()) || (!m_ioc.stopped())))
 	{
 		for (auto itt = m_pNodes.begin(); itt != m_pNodes.end(); ++itt)
 		{
diff --git hardware/PanasonicTV.h hardware/PanasonicTV.h
index b0a94ff..30e1ca1 100644
--- hardware/PanasonicTV.h
+++ hardware/PanasonicTV.h
@@ -39,7 +39,7 @@ class CPanasonic : public CDomoticzHardwareBase
 	bool m_bTryIfOff;
 	std::shared_ptr<std::thread> m_thread;
 	std::mutex m_mutex;
-	boost::asio::io_service m_ios;
+	boost::asio::io_context m_ioc;
 
 	friend class CPanasonicNode; 
 };
diff --git hardware/Pinger.cpp hardware/Pinger.cpp
index a66c7a1..e070b29 100644
--- hardware/Pinger.cpp
+++ hardware/Pinger.cpp
@@ -21,23 +21,23 @@
 #if BOOST_VERSION >= 107000
 #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
 #else
-#define GET_IO_SERVICE(s) ((s).get_io_service())
+#define GET_IO_SERVICE(s) ((s).get_io_context())
 #endif
 
 class pinger
 	: private domoticz::noncopyable
 {
 public:
-  pinger(boost::asio::io_service &io_service, const char *destination, const int iPingTimeoutms)
+  pinger(boost::asio::io_context &io_context, const char *destination, const int iPingTimeoutms)
 	  : num_replies_(0)
 	  , m_PingState(false)
-	  , resolver_(io_service)
-	  , socket_(io_service, boost::asio::ip::icmp::v4())
-	  , timer_(io_service)
+	  , resolver_(io_context)
+	  , socket_(io_context, boost::asio::ip::icmp::v4())
+	  , timer_(io_context)
 	  , sequence_number_(0)
   {
-	  boost::asio::ip::icmp::resolver::query query(boost::asio::ip::icmp::v4(), destination, "");
-	  destination_ = *resolver_.resolve(query);
+	  auto endpoints = resolver_.resolve(boost::asio::ip::icmp::v4(), destination, "");
+	  destination_ = endpoints.begin()->endpoint();
 
 	  num_tries_ = 1;
 	  PingTimeoutms_ = iPingTimeoutms;
@@ -332,11 +332,11 @@ void CPinger::ReloadNodes()
 void CPinger::Do_Ping_Worker(const PingNode &Node)
 {
 	bool bPingOK = false;
-	boost::asio::io_service io_service;
+	boost::asio::io_context io_context;
 	try
 	{
-		pinger p(io_service, Node.IP.c_str(), m_iPingTimeoutms);
-		io_service.run();
+		pinger p(io_context, Node.IP.c_str(), m_iPingTimeoutms);
+		io_context.run();
 		if (p.m_PingState == true)
 		{
 			bPingOK = true;
diff --git hardware/RFLinkMQTT.h hardware/RFLinkMQTT.h
index e938328..72433b8 100644
--- hardware/RFLinkMQTT.h
+++ hardware/RFLinkMQTT.h
@@ -46,7 +46,7 @@ protected:
 	boost::signals2::connection m_sDeviceReceivedConnection;
 	boost::signals2::connection m_sSwitchSceneConnection;
 	void selectNextIPAdress( void );
-	virtual bool WriteInt(const std::string &sendString); // override;
+	bool WriteInt(const std::string &sendString) override;
 	void Do_Work();
 	virtual void SendHeartbeat();
 	void StopMQTT();
diff --git hardware/TCPProxy/tcpproxy_server.cpp hardware/TCPProxy/tcpproxy_server.cpp
index 8aceb0b..d77d4bf 100644
--- hardware/TCPProxy/tcpproxy_server.cpp
+++ hardware/TCPProxy/tcpproxy_server.cpp
@@ -18,12 +18,12 @@
 #if BOOST_VERSION >= 107000
 #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
 #else
-#define GET_IO_SERVICE(s) ((s).get_io_service())
+#define GET_IO_SERVICE(s) ((s).get_io_context())
 #endif
 
 namespace tcp_proxy
 {
-	bridge::bridge(boost::asio::io_service& ios)
+	bridge::bridge(boost::asio::io_context& ios)
       : downstream_socket_(ios),
         upstream_socket_(ios)
 	{
@@ -44,7 +44,7 @@ namespace tcp_proxy
 		boost::asio::ip::tcp::endpoint end;
 
 
-		boost::asio::io_service &ios= GET_IO_SERVICE(downstream_socket_);
+		boost::asio::io_context &ios= GET_IO_SERVICE(downstream_socket_);
 		boost::asio::ip::tcp::resolver resolver(ios);
 		boost::asio::ip::tcp::resolver::query query(upstream_host, upstream_port, boost::asio::ip::resolver_query_base::numeric_service);
 		auto i = resolver.resolve(query);
@@ -137,10 +137,10 @@ namespace tcp_proxy
 	}
 //Acceptor Class
 	acceptor::acceptor(const std::string &local_host, unsigned short local_port, const std::string &upstream_host, const std::string &upstream_port)
-		: io_service_()
+		: io_context_()
 		, m_bDoStop(false)
 		, localhost_address(boost::asio::ip::address_v4::from_string(local_host))
-		, acceptor_(io_service_, boost::asio::ip::tcp::endpoint(localhost_address, local_port))
+		, acceptor_(io_context_, boost::asio::ip::tcp::endpoint(localhost_address, local_port))
 		, upstream_host_(upstream_host)
 		, upstream_port_(upstream_port)
 	{
@@ -151,7 +151,7 @@ namespace tcp_proxy
 	{
 		try
 		{
-			session_ = std::make_shared<bridge>(io_service_);
+			session_ = std::make_shared<bridge>(io_context_);
 			session_->sDownstreamData.connect([this](auto d, auto l) { OnDownstreamData(d, l); });
 			session_->sUpstreamData.connect([this](auto d, auto l) { OnUpstreamData(d, l); });
 
@@ -169,11 +169,11 @@ namespace tcp_proxy
 		m_bDoStop=false;
 
 		accept_connections();
-		// The io_service::run() call will block until all asynchronous operations
+		// The io_context::run() call will block until all asynchronous operations
 		// have finished. While the server is running, there is always at least one
 		// asynchronous operation outstanding: the asynchronous accept call waiting
 		// for new incoming connections.
-		io_service_.run();
+		io_context_.run();
 		return true;
 	}
 	bool acceptor::stop()
@@ -181,14 +181,14 @@ namespace tcp_proxy
 		m_bDoStop=true;
 		// Post a call to the stop function so that server::stop() is safe to call
 		// from any thread.
-		io_service_.post([this] { handle_stop(); });
+		io_context_.post([this] { handle_stop(); });
 		return true;
 	}
 
 	void acceptor::handle_stop()
 	{
 		// The server is stopped by canceling all outstanding asynchronous
-		// operations. Once all operations have finished the io_service::run() call
+		// operations. Once all operations have finished the io_context::run() call
 		// will exit.
 		acceptor_.close();
 		//connection_manager_.stop_all();
diff --git hardware/TCPProxy/tcpproxy_server.h hardware/TCPProxy/tcpproxy_server.h
index 3d1a150..148e65f 100644
--- hardware/TCPProxy/tcpproxy_server.h
+++ hardware/TCPProxy/tcpproxy_server.h
@@ -10,7 +10,7 @@ namespace tcp_proxy
 	class bridge : public std::enable_shared_from_this<bridge>
 	{
 	public:
-		explicit bridge(boost::asio::io_service& ios);
+		explicit bridge(boost::asio::io_context& ios);
 		boost::asio::ip::tcp::socket& downstream_socket();
 		boost::asio::ip::tcp::socket& upstream_socket();
 
@@ -52,8 +52,8 @@ namespace tcp_proxy
 		void OnUpstreamData(const unsigned char *pData, size_t Len);
 		void OnDownstreamData(const unsigned char *pData, size_t Len);
 
-		/// The io_service used to perform asynchronous operations.
-		boost::asio::io_service io_service_;
+		/// The io_context used to perform asynchronous operations.
+		boost::asio::io_context io_context_;
 		bool m_bDoStop;
 		boost::asio::ip::address_v4 localhost_address;
 		boost::asio::ip::tcp::acceptor acceptor_;
diff --git hardware/XiaomiDeviceSupport.h hardware/XiaomiDeviceSupport.h
index fad7884..4a76d96 100644
--- hardware/XiaomiDeviceSupport.h
+++ hardware/XiaomiDeviceSupport.h
@@ -15,6 +15,7 @@
 class XiaomiDeviceSupport
 {
       public:
+	virtual ~XiaomiDeviceSupport() = default;
 	/**
 	 * Method to get 'model' corresponding to the ID of the device in case the Gateway API didn't provide it.
 	 *
diff --git hardware/XiaomiGateway.cpp hardware/XiaomiGateway.cpp
index 66acdc5..fb4387a 100644
--- hardware/XiaomiGateway.cpp
+++ hardware/XiaomiGateway.cpp
@@ -538,12 +538,12 @@ bool XiaomiGateway::SendMessageToGateway(const std::string &controlmessage)
 {
 	std::string message = controlmessage;
 	bool result = true;
-	boost::asio::io_service io_service;
-	boost::asio::ip::udp::socket socket_(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0));
+	boost::asio::io_context io_context;
+	boost::asio::ip::udp::socket socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0));
 	stdreplace(message, "@gatewaykey", GetGatewayKey());
 	std::shared_ptr<std::string> message1(new std::string(message));
 	boost::asio::ip::udp::endpoint remote_endpoint_;
-	remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(m_GatewayIp), 9898);
+	remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(m_GatewayIp), 9898);
 	socket_.send_to(boost::asio::buffer(*message1), remote_endpoint_);
 	sleep_milliseconds(150); // TODO: reduce or remove sleep
 	std::array<char, 512> recv_buffer_;
@@ -1015,15 +1015,14 @@ bool XiaomiGateway::StopHardware()
 void XiaomiGateway::Do_Work()
 {
 	Log(LOG_STATUS, "XiaomiGateway (ID=%d): Worker started...", m_HwdID);
-	boost::asio::io_service io_service;
+	boost::asio::io_context io_context;
 	// Find the local ip address that is similar to the xiaomi gateway
 	try
 	{
-		boost::asio::ip::udp::resolver resolver(io_service);
-		boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), m_GatewayIp, "");
-		auto endpoints = resolver.resolve(query);
-		boost::asio::ip::udp::endpoint ep = *endpoints;
-		boost::asio::ip::udp::socket socket(io_service);
+		boost::asio::ip::udp::resolver resolver(io_context);
+		auto endpoints = resolver.resolve(boost::asio::ip::udp::v4(), m_GatewayIp, "");
+		boost::asio::ip::udp::endpoint ep = *endpoints.begin();
+		boost::asio::ip::udp::socket socket(io_context);
 		socket.connect(ep);
 		boost::asio::ip::address addr = socket.local_endpoint().address();
 		std::string compareIp = m_GatewayIp.substr(0, (m_GatewayIp.length() - 3));
@@ -1073,11 +1072,11 @@ void XiaomiGateway::Do_Work()
 		}
 	}
 
-	XiaomiGateway::xiaomi_udp_server udp_server(io_service, m_HwdID, m_GatewayIp, m_LocalIp, m_ListenPort9898, m_OutputMessage, m_IncludeVoltage, this);
+	XiaomiGateway::xiaomi_udp_server udp_server(io_context, m_HwdID, m_GatewayIp, m_LocalIp, m_ListenPort9898, m_OutputMessage, m_IncludeVoltage, this);
 	boost::thread bt;
 	if (m_ListenPort9898)
 	{
-		bt = boost::thread([p = &io_service] { p->run(); });
+		bt = boost::thread([p = &io_context] { p->run(); });
 		SetThreadName(bt.native_handle(), "XiaomiGatewayIO");
 	}
 
@@ -1094,7 +1093,7 @@ void XiaomiGateway::Do_Work()
 			// Log(LOG_STATUS, "sec_counter %d", sec_counter);
 		}
 	}
-	io_service.stop();
+	io_context.stop();
 	if (bt.joinable())
 	{
 		bt.join();
@@ -1178,9 +1177,9 @@ unsigned int XiaomiGateway::GetShortID(const std::string &nodeid)
 	return sID;
 }
 
-XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_service, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, const bool listenPort9898,
+XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_context &io_context, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, const bool listenPort9898,
 						    const bool outputMessage, const bool includeVoltage, XiaomiGateway *parent)
-	: socket_(io_service, boost::asio::ip::udp::v4())
+	: socket_(io_context, boost::asio::ip::udp::v4())
 {
 	m_HardwareID = m_HwdID;
 	m_XiaomiGateway = parent;
@@ -1196,8 +1195,8 @@ XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_
 			if (!m_localip.empty())
 			{
 				boost::system::error_code ec;
-				boost::asio::ip::address listen_addr = boost::asio::ip::address::from_string(m_localip, ec);
-				boost::asio::ip::address mcast_addr = boost::asio::ip::address::from_string("224.0.0.50", ec);
+				boost::asio::ip::address listen_addr = boost::asio::ip::make_address_v4(m_localip, ec);
+				boost::asio::ip::address mcast_addr = boost::asio::ip::make_address_v4("224.0.0.50", ec);
 				boost::asio::ip::udp::endpoint listen_endpoint(mcast_addr, 9898);
 
 				socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 9898));
@@ -1213,9 +1212,9 @@ XiaomiGateway::xiaomi_udp_server::xiaomi_udp_server(boost::asio::io_service &io_
 				socket_.bind(boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 9898));
 				std::shared_ptr<std::string> message(new std::string(R"({"cmd":"whois"})"));
 				boost::asio::ip::udp::endpoint remote_endpoint;
-				remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("224.0.0.50"), 4321);
+				remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4("224.0.0.50"), 4321);
 				socket_.send_to(boost::asio::buffer(*message), remote_endpoint);
-				socket_.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string("224.0.0.50")));
+				socket_.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::make_address_v4("224.0.0.50")));
 			}
 		}
 		catch (const boost::system::system_error &ex)
@@ -1720,7 +1719,7 @@ void XiaomiGateway::xiaomi_udp_server::handle_receive(const boost::system::error
 					message.append("\"}");
 					std::shared_ptr<std::string> message1(new std::string(message));
 					boost::asio::ip::udp::endpoint remote_endpoint;
-					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(TrueGateway->GetGatewayIp().c_str()), 9898);
+					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(TrueGateway->GetGatewayIp().c_str()), 9898);
 					socket_.send_to(boost::asio::buffer(*message1), remote_endpoint);
 				}
 			}
@@ -1746,7 +1745,7 @@ void XiaomiGateway::xiaomi_udp_server::handle_receive(const boost::system::error
 					std::string message = R"({"cmd" : "get_id_list"})";
 					std::shared_ptr<std::string> message2(new std::string(message));
 					boost::asio::ip::udp::endpoint remote_endpoint;
-					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(TrueGateway->GetGatewayIp().c_str()), 9898);
+					remote_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4(TrueGateway->GetGatewayIp().c_str()), 9898);
 					socket_.send_to(boost::asio::buffer(*message2), remote_endpoint);
 				}
 			}
diff --git hardware/XiaomiGateway.h hardware/XiaomiGateway.h
index dce4b34..1f552f3 100644
--- hardware/XiaomiGateway.h
+++ hardware/XiaomiGateway.h
@@ -100,7 +100,7 @@ class XiaomiGateway : public CDomoticzHardwareBase
 	class xiaomi_udp_server
 	{
 	      public:
-		xiaomi_udp_server(boost::asio::io_service &io_service, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, bool listenPort9898, bool outputMessage,
+		xiaomi_udp_server(boost::asio::io_context &io_context, int m_HwdID, const std::string &gatewayIp, const std::string &localIp, bool listenPort9898, bool outputMessage,
 				  bool includeVolage, XiaomiGateway *parent);
 		~xiaomi_udp_server() = default;
 
diff --git hardware/Yeelight.cpp hardware/Yeelight.cpp
index cdb7889..e5fe8fc 100644
--- hardware/Yeelight.cpp
+++ hardware/Yeelight.cpp
@@ -93,8 +93,8 @@ void Yeelight::Do_Work()
 
 	try
 	{
-		boost::asio::io_service io_service;
-		udp_server server(io_service, m_HwdID);
+		boost::asio::io_context io_context;
+		udp_server server(io_context, m_HwdID);
 		int sec_counter = YEELIGHT_POLL_INTERVAL - 5;
 		while (!IsStopRequested(1000))
 		{
@@ -105,7 +105,7 @@ void Yeelight::Do_Work()
 			if (sec_counter % 60 == 0) //poll YeeLights every minute
 			{
 				server.start_send();
-				io_service.run();
+				io_context.run();
 			}
 		}
 	}
@@ -227,12 +227,11 @@ bool Yeelight::WriteToHardware(const char *pdata, const unsigned char length)
 
 	try
 	{
-		boost::asio::io_service io_service;
-		boost::asio::ip::tcp::socket sendSocket(io_service);
-		boost::asio::ip::tcp::resolver resolver(io_service);
-		boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), szTmp, "55443");
-		auto iterator = resolver.resolve(query);
-		boost::asio::connect(sendSocket, iterator);
+		boost::asio::io_context io_context;
+		boost::asio::ip::tcp::socket sendSocket(io_context);
+		boost::asio::ip::tcp::resolver resolver(io_context);
+		auto endpoints = resolver.resolve(boost::asio::ip::tcp::v4(), szTmp, "55443");
+		boost::asio::connect(sendSocket, endpoints);
 
 		std::string message;
 		std::string message2;
@@ -404,8 +403,8 @@ bool Yeelight::WriteToHardware(const char *pdata, const unsigned char length)
 std::array<char, 1024> recv_buffer_;
 int hardwareId;
 
-Yeelight::udp_server::udp_server(boost::asio::io_service& io_service, int m_HwdID)
-	: socket_(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0))
+Yeelight::udp_server::udp_server(boost::asio::io_context& io_context, int m_HwdID)
+	: socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0))
 {
 	socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
 	socket_.set_option(boost::asio::socket_base::broadcast(true));
@@ -421,7 +420,7 @@ void Yeelight::udp_server::start_send()
 		//Log(LOG_STATUS, "start_send..................");
 		std::shared_ptr<std::string> message(
 			new std::string(testMessage));
-		remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string("239.255.255.250"), 1982);
+		remote_endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address_v4("239.255.255.250"), 1982);
 		socket_.send_to(boost::asio::buffer(*message), remote_endpoint_);
 		sleep_milliseconds(150);
 		start_receive();
diff --git hardware/Yeelight.h hardware/Yeelight.h
index fb03c28..3b7b4c3 100644
--- hardware/Yeelight.h
+++ hardware/Yeelight.h
@@ -25,7 +25,7 @@ class Yeelight : public CDomoticzHardwareBase
 	class udp_server
 	{
 	      public:
-		udp_server(boost::asio::io_service &io_service, int m_HwdID);
+		udp_server(boost::asio::io_context &io_context, int m_HwdID);
 		boost::asio::ip::udp::socket socket_;
 		boost::asio::ip::udp::endpoint remote_endpoint_;
 		void start_send();
diff --git hardware/plugins/PluginManager.cpp hardware/plugins/PluginManager.cpp
index 2813112..423edbb 100644
--- hardware/plugins/PluginManager.cpp
+++ hardware/plugins/PluginManager.cpp
@@ -64,7 +64,7 @@ namespace Plugins {
 	// PyMODINIT_FUNC PyInit_DomoticzEvents(void);
 
 	std::mutex PluginMutex;	// controls accessto the message queue and m_pPlugins map
-	boost::asio::io_service ios;
+	boost::asio::io_context ios;
 
 	std::map<int, CDomoticzHardwareBase*>	CPluginSystem::m_pPlugins;
 	std::map<std::string, std::string>		CPluginSystem::m_PluginXml;
@@ -315,7 +315,7 @@ namespace Plugins {
 		// Create initial IO Service thread
 		ios.restart();
 		// Create some work to keep IO Service alive
-		auto work = boost::asio::io_service::work(ios);
+		auto work = boost::asio::make_work_guard(ios);
 		boost::thread_group BoostThreads;
 		for (int i = 0; i < 1; i++)
 		{
diff --git hardware/plugins/PluginTransports.cpp hardware/plugins/PluginTransports.cpp
index 52d14e7..f7ace0f 100644
--- hardware/plugins/PluginTransports.cpp
+++ hardware/plugins/PluginTransports.cpp
@@ -116,15 +116,14 @@ namespace Plugins {
 				m_bConnected = false;
 				m_Socket = new boost::asio::ip::tcp::socket(ios);
 
-				boost::system::error_code ec;
-				boost::asio::ip::tcp::resolver::query query(m_IP, m_Port);
-				auto iter = m_Resolver.resolve(query);
-				boost::asio::ip::tcp::endpoint endpoint = *iter;
-
 				//
 				//	Async resolve/connect based on http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/http/client/async_client.cpp
 				//
-				m_Resolver.async_resolve(query, [this](auto &&err, auto end) { handleAsyncResolve(err, end); });
+				m_Resolver.async_resolve(m_IP, m_Port,
+					[this](auto &&err, auto endpoints) {
+						handleAsyncResolve(err, endpoints);
+					}
+				);
 			}
 		}
 		catch (std::exception& e)
@@ -139,15 +138,14 @@ namespace Plugins {
 		return true;
 	}
 
-	void CPluginTransportTCP::handleAsyncResolve(const boost::system::error_code & err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
+	void CPluginTransportTCP::handleAsyncResolve(const boost::system::error_code & err, boost::asio::ip::tcp::resolver::results_type endpoints)
 	{
 		CPlugin*		pPlugin = ((CConnection*)m_pConnection)->pPlugin;
 		AccessPython	Guard(pPlugin, "CPluginTransportTCP::handleAsyncResolve");
 
 		if (!err)
 		{
-			boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
-			m_Socket->async_connect(endpoint, [this, endpoint_iterator](auto &&err) mutable { handleAsyncConnect(err, ++endpoint_iterator); });
+			boost::asio::async_connect(*m_Socket, endpoints, [this](auto &&err, const boost::asio::ip::tcp::endpoint &endpoint) mutable { handleAsyncConnect(err, endpoint); });
 		}
 		else
 		{
@@ -169,7 +167,7 @@ namespace Plugins {
 		}
 	}
 
-	void CPluginTransportTCP::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator)
+	void CPluginTransportTCP::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint)
 	{
 		CPlugin*		pPlugin = ((CConnection*)m_pConnection)->pPlugin;
 		AccessPython	Guard(pPlugin, "CPluginTransportTCP::handleAsyncResolve");
@@ -481,7 +479,7 @@ namespace Plugins {
 		}
 	};
 
-	void CPluginTransportTCPSecure::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator)
+	void CPluginTransportTCPSecure::handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint)
 	{
 		CPlugin* pPlugin = ((CConnection*)m_pConnection)->pPlugin;
 		if (!pPlugin) return;
@@ -498,7 +496,7 @@ namespace Plugins {
 			SSL_set_tlsext_host_name(m_TLSSock->native_handle(), m_IP.c_str());			// Enable SNI
 
 			m_TLSSock->set_verify_mode(boost::asio::ssl::verify_none);
-			m_TLSSock->set_verify_callback(boost::asio::ssl::rfc2818_verification(m_IP));
+			m_TLSSock->set_verify_callback(boost::asio::ssl::host_name_verification(m_IP));
 			// m_TLSSock->set_verify_callback([this](auto v, auto &c){ VerifyCertificate(v, c);});
 			try
 			{
@@ -648,7 +646,7 @@ namespace Plugins {
 					// Hanlde multicast
 					if (((m_IP.substr(0, 4) >= "224.") && (m_IP.substr(0, 4) <= "239.")) || (m_IP.substr(0, 4) == "255."))
 					{
-						m_Socket->set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address::from_string(m_IP.c_str())), ec);
+						m_Socket->set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::make_address_v4(m_IP.c_str())), ec);
 						m_Socket->set_option(boost::asio::ip::multicast::hops(2), ec);
 					}
 				}
@@ -764,7 +762,7 @@ namespace Plugins {
 			}
 			else
 			{
-				boost::asio::ip::udp::endpoint destination(boost::asio::ip::address::from_string(m_IP.c_str()), atoi(m_Port.c_str()));
+				boost::asio::ip::udp::endpoint destination(boost::asio::ip::make_address_v4(m_IP.c_str()), atoi(m_Port.c_str()));
 				size_t bytes_transferred = m_Socket->send_to(boost::asio::buffer(pMessage, pMessage.size()), destination);
 			}
 		}
@@ -825,12 +823,14 @@ namespace Plugins {
 		}
 	};
 
-	void CPluginTransportICMP::handleAsyncResolve(const boost::system::error_code &ec, const boost::asio::ip::icmp::resolver::iterator &endpoint_iterator)
+	void CPluginTransportICMP::handleAsyncResolve(const boost::system::error_code &ec, boost::asio::ip::icmp::resolver::results_type endpoints)
 	{
 		if (!ec)
 		{
+			m_Endpoint = endpoints.begin()->endpoint();
+			m_IP = m_Endpoint.address().to_string();
+
 			m_bConnected = true;
-			m_IP = endpoint_iterator->endpoint().address().to_string();
 
 			// Listen will fail (10022 - bad parameter) unless something has been sent(?)
 			std::string body("ping");
@@ -857,15 +857,11 @@ namespace Plugins {
 				m_bConnecting = true;
 				m_Socket = new boost::asio::ip::icmp::socket(ios, boost::asio::ip::icmp::v4());
 
-				boost::system::error_code ec;
-				boost::asio::ip::icmp::resolver::query query(boost::asio::ip::icmp::v4(), m_IP, "");
-				auto iter = m_Resolver.resolve(query);
-				m_Endpoint = *iter;
-
-				//
-				//	Async resolve/connect based on http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/example/icmp/ping.cpp
-				//
-				m_Resolver.async_resolve(query, [this](auto &&err, auto i) { handleAsyncResolve(err, i); });
+				m_Resolver.async_resolve(boost::asio::ip::icmp::v4(), m_IP, "",
+					[this](auto &&err, auto endpoints) {
+						handleAsyncResolve(err, endpoints);
+					}
+				);
 			}
 			else
 			{
diff --git hardware/plugins/PluginTransports.h hardware/plugins/PluginTransports.h
index c1cc1e3..79d5725 100644
--- hardware/plugins/PluginTransports.h
+++ hardware/plugins/PluginTransports.h
@@ -6,7 +6,7 @@
 
 namespace Plugins {
 
-	extern boost::asio::io_service ios;
+	extern boost::asio::io_context ios;
 
 	class CPluginTransport
 	{
@@ -85,8 +85,8 @@ namespace Plugins {
 		  , m_Socket(nullptr){};
 	  bool handleConnect() override;
 	  bool handleListen() override;
-	  virtual void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
-	  virtual void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator);
+	  virtual void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::tcp::resolver::results_type endpoints);
+	  virtual void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint);
 	  virtual void handleAsyncAccept(boost::asio::ip::tcp::socket *pSocket, const boost::system::error_code &error);
 	  void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override;
 	  void handleWrite(const std::vector<byte> &pMessage) override;
@@ -111,7 +111,7 @@ namespace Plugins {
 		  : CPluginTransportTCP(HwdID, pConnection, Address, Port)
 		  , m_Context(nullptr)
 		  , m_TLSSock(nullptr){};
-	  void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::resolver::iterator &endpoint_iterator) override;
+	  void handleAsyncConnect(const boost::system::error_code &err, const boost::asio::ip::tcp::endpoint &endpoint) override;
 	  void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override;
 	  void handleWrite(const std::vector<byte> &pMessage) override;
 	  ~CPluginTransportTCPSecure() override;
@@ -151,7 +151,7 @@ namespace Plugins {
 		  , m_Socket(nullptr)
 		  , m_Timer(nullptr)
 		  , m_SequenceNo(-1){};
-	  void handleAsyncResolve(const boost::system::error_code &err, const boost::asio::ip::icmp::resolver::iterator &endpoint_iterator);
+	  void handleAsyncResolve(const boost::system::error_code &err, boost::asio::ip::icmp::resolver::results_type endpoints);
 	  bool handleListen() override;
 	  void handleTimeout(const boost::system::error_code &) override;
 	  void handleRead(const boost::system::error_code &e, std::size_t bytes_transferred) override;
diff --git main/WebServerCmds.cpp main/WebServerCmds.cpp
index 7d4a9f2..3586373 100644
--- main/WebServerCmds.cpp
+++ main/WebServerCmds.cpp
@@ -1632,7 +1632,7 @@ namespace http
 			ExtraHeaders.push_back("App_Revision: " + std::to_string(iAppRevision));
 			ExtraHeaders.push_back("System_Name: " + systemname);
 			ExtraHeaders.push_back("Machine: " + machine);
-			ExtraHeaders.push_back("Type: " + (!bIsBetaChannel) ? "Stable" : "Beta");
+			ExtraHeaders.push_back("Type: " + std::string(!bIsBetaChannel ? "Stable" : "Beta"));
 
 			if (!HTTPClient::GET(szHistoryURL, ExtraHeaders, historyfile))
 			{
diff --git main/mainworker.cpp main/mainworker.cpp
index b5027eb..b8f8dc7 100644
--- main/mainworker.cpp
+++ main/mainworker.cpp
@@ -1318,7 +1318,7 @@ bool MainWorker::IsUpdateAvailable(const bool bIsForced)
 	ExtraHeaders.push_back("App_Revision: " + std::to_string(iAppRevision));
 	ExtraHeaders.push_back("System_Name: " + m_szSystemName);
 	ExtraHeaders.push_back("Machine: " + machine);
-	ExtraHeaders.push_back("Type: " + (!bIsBetaChannel) ? "Stable" : "Beta");
+	ExtraHeaders.push_back("Type: " + std::string(!bIsBetaChannel ? "Stable" : "Beta"));
 
 	if (!HTTPClient::GET(szURL, ExtraHeaders, revfile))
 		return false;
diff --git plugins/examples/Pinger.py plugins/examples/Pinger.py
index 6b54559..c7a776d 100644
--- plugins/examples/Pinger.py
+++ plugins/examples/Pinger.py
@@ -3,7 +3,7 @@
 #           Author:     Dnpwwo, 2017 - 2018
 #
 """
-<plugin key="ICMP" name="Pinger (ICMP)" author="dnpwwo" version="3.1.4">
+<plugin key="ICMP" name="Pinger (ICMP)" author="dnpwwo" version="3.1.5">
     <description>
 ICMP Pinger Plugin.<br/><br/>
 Specify comma delimted addresses (IP or DNS names) of devices that are to be pinged.<br/>
@@ -144,8 +144,9 @@ class BasePlugin:
             for Device in Devices:
                 if (("Name" in Devices[Device].Options) and (Devices[Device].Options["Name"] == Connection.Name)):
                     UpdateDevice(Device, 0, "Off", TimedOut)
-        self.icmpConn.Close()
-        self.icmpConn = None
+        if (self.icmpConn != None):
+            self.icmpConn.Close()
+            self.icmpConn = None
 
     def onHeartbeat(self):
         Domoticz.Debug("Heartbeating...")
diff --git push/MQTTPush.h push/MQTTPush.h
index 0773b43..d9f9332 100644
--- push/MQTTPush.h
+++ push/MQTTPush.h
@@ -14,7 +14,7 @@ public:
 	void on_message(const struct mosquitto_message* message) override;
 	void on_connect(int rc) override;
 	void on_disconnect(int rc) override;
-	void on_going_down();
+	void on_going_down() override;
 private:
 	struct _tPushItem
 	{
diff --git tcpserver/TCPClient.cpp tcpserver/TCPClient.cpp
index d55da10..3eee093 100644
--- tcpserver/TCPClient.cpp
+++ tcpserver/TCPClient.cpp
@@ -19,7 +19,7 @@ namespace tcp {
 			delete socket_;
 		}
 
-		CTCPClient::CTCPClient(boost::asio::io_service& ios, CTCPServerIntBase* pManager)
+		CTCPClient::CTCPClient(boost::asio::io_context& ios, CTCPServerIntBase* pManager)
 			: CTCPClientBase(pManager)
 		{
 			socket_ = new boost::asio::ip::tcp::socket(ios);
diff --git tcpserver/TCPClient.h tcpserver/TCPClient.h
index df4350d..e7a882b 100644
--- tcpserver/TCPClient.h
+++ tcpserver/TCPClient.h
@@ -38,7 +38,7 @@ class CTCPClient : public CTCPClientBase,
 	public std::enable_shared_from_this<CTCPClient>
 {
 public:
-	CTCPClient(boost::asio::io_service& ios, CTCPServerIntBase *pManager);
+	CTCPClient(boost::asio::io_context& ios, CTCPServerIntBase *pManager);
 	~CTCPClient() = default;
 	void start() override;
 	void stop() override;
diff --git tcpserver/TCPServer.cpp tcpserver/TCPServer.cpp
index 91fdc7e..57f8709 100644
--- tcpserver/TCPServer.cpp
+++ tcpserver/TCPServer.cpp
@@ -18,14 +18,14 @@ namespace tcp {
 
 		CTCPServerInt::CTCPServerInt(const std::string& address, const std::string& port, CTCPServer* pRoot) :
 			CTCPServerIntBase(pRoot),
-			io_service_(),
-			acceptor_(io_service_)
+			io_context_(),
+			acceptor_(io_context_)
 		{
 			// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
-			boost::asio::ip::tcp::resolver resolver(io_service_);
-			boost::asio::ip::tcp::resolver::query query(address, port);
-			boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
-			acceptor_.open(endpoint.protocol());
+			boost::asio::ip::tcp::resolver resolver(io_context_);
+			boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type endpoints = resolver.resolve(address, port);
+			auto endpoint = *endpoints.begin();
+			acceptor_.open(endpoint.endpoint().protocol());
 			acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
 			// bind to both ipv6 and ipv4 sockets for the "::" address only
 			if (address == "::")
@@ -35,7 +35,7 @@ namespace tcp {
 			acceptor_.bind(endpoint);
 			acceptor_.listen();
 
-			new_connection_ = std::make_shared<CTCPClient>(io_service_, this);
+			new_connection_ = std::make_shared<CTCPClient>(io_context_, this);
 			if (new_connection_ == nullptr)
 			{
 				_log.Log(LOG_ERROR, "Error creating new client!");
@@ -47,24 +47,24 @@ namespace tcp {
 
 		void CTCPServerInt::start()
 		{
-			// The io_service::run() call will block until all asynchronous operations
+			// The io_context::run() call will block until all asynchronous operations
 			// have finished. While the server is running, there is always at least one
 			// asynchronous operation outstanding: the asynchronous accept call waiting
 			// for new incoming connections.
-			io_service_.run();
+			io_context_.run();
 		}
 
 		void CTCPServerInt::stop()
 		{
 			// Post a call to the stop function so that server::stop() is safe to call
 			// from any thread.
-			io_service_.post([this] { handle_stop(); });
+			boost::asio::post([this] { handle_stop(); });
 		}
 
 		void CTCPServerInt::handle_stop()
 		{
 			// The server is stopped by cancelling all outstanding asynchronous
-			// operations. Once all operations have finished the io_service::run() call
+			// operations. Once all operations have finished the io_context::run() call
 			// will exit.
 			acceptor_.close();
 			stopAllClients();
@@ -88,7 +88,7 @@ namespace tcp {
 			connections_.insert(new_connection_);
 			new_connection_->start();
 
-			new_connection_.reset(new CTCPClient(io_service_, this));
+			new_connection_.reset(new CTCPClient(io_context_, this));
 
 			acceptor_.async_accept(*(new_connection_->socket()), [this](auto&& err) { handleAccept(err); });
 		}
diff --git tcpserver/TCPServer.h tcpserver/TCPServer.h
index ca611b1..17284ca 100644
--- tcpserver/TCPServer.h
+++ tcpserver/TCPServer.h
@@ -70,8 +70,8 @@ private:
 	/// Handle a request to stop the server.
 	void handle_stop();
 
-	/// The io_service used to perform asynchronous operations.
-	boost::asio::io_service io_service_;
+	/// The io_context used to perform asynchronous operations.
+	boost::asio::io_context io_context_;
 
 	boost::asio::ip::tcp::acceptor acceptor_;
 
diff --git webserver/cWebem.cpp webserver/cWebem.cpp
index 57d9683..c0d292d 100644
--- webserver/cWebem.cpp
+++ webserver/cWebem.cpp
@@ -47,13 +47,13 @@ namespace http {
 			, myRequestHandler(doc_root, this)
 			// Rene, make sure we initialize m_sessions first, before starting a server
 			, myServer(server_factory::create(settings, myRequestHandler))
-			, m_io_service()
-			, m_session_clean_timer(m_io_service, boost::posix_time::minutes(1))
+			, m_io_context()
+			, m_session_clean_timer(m_io_context, boost::posix_time::minutes(1))
 		{
 			// associate handler to timer and schedule the first iteration
 			m_session_clean_timer.async_wait([this](auto &&) { CleanSessions(); });
-			m_io_service_thread = std::make_shared<std::thread>([p = &m_io_service] { p->run(); });
-			SetThreadName(m_io_service_thread->native_handle(), "Webem_ssncleaner");
+			m_io_context_thread = std::make_shared<std::thread>([p = &m_io_context] { p->run(); });
+			SetThreadName(m_io_context_thread->native_handle(), "Webem_ssncleaner");
 		}
 
 		cWebem::~cWebem()
@@ -93,14 +93,14 @@ namespace http {
 			// Stop session cleaner
 			try
 			{
-				if (!m_io_service.stopped())
+				if (!m_io_context.stopped())
 				{
-					m_io_service.stop();
+					m_io_context.stop();
 				}
-				if (m_io_service_thread)
+				if (m_io_context_thread)
 				{
-					m_io_service_thread->join();
-					m_io_service_thread.reset();
+					m_io_context_thread->join();
+					m_io_context_thread.reset();
 				}
 			}
 			catch (...)
diff --git webserver/cWebem.h webserver/cWebem.h
index 6e3b899..7905c45 100644
--- webserver/cWebem.h
+++ webserver/cWebem.h
@@ -259,9 +259,9 @@ namespace http
 			std::string m_webRoot;
 			/// sessions management
 			std::mutex m_sessionsMutex;
-			boost::asio::io_service m_io_service;
+			boost::asio::io_context m_io_context;
 			boost::asio::deadline_timer m_session_clean_timer;
-			std::shared_ptr<std::thread> m_io_service_thread;
+			std::shared_ptr<std::thread> m_io_context_thread;
 		};
 
 	} // namespace server
diff --git webserver/connection.cpp webserver/connection.cpp
index 40f9788..3a70924 100644
--- webserver/connection.cpp
+++ webserver/connection.cpp
@@ -22,13 +22,13 @@ namespace http {
 		extern time_t last_write_time(const std::string& path);
 
 		// this is the constructor for plain connections
-		connection::connection(boost::asio::io_service &io_service, connection_manager &manager, request_handler &handler, int read_timeout)
+		connection::connection(boost::asio::io_context &io_context, connection_manager &manager, request_handler &handler, int read_timeout)
 			: send_buffer_(nullptr)
 			, read_timeout_(read_timeout)
-			, read_timer_(io_service, boost::posix_time::seconds(read_timeout))
+			, read_timer_(io_context, boost::posix_time::seconds(read_timeout))
 			, default_abandoned_timeout_(20 * 60)
 			// 20mn before stopping abandoned connection
-			, abandoned_timer_(io_service, boost::posix_time::seconds(default_abandoned_timeout_))
+			, abandoned_timer_(io_context, boost::posix_time::seconds(default_abandoned_timeout_))
 			, connection_manager_(manager)
 			, request_handler_(handler)
 			, status_(INITIALIZING)
@@ -39,18 +39,18 @@ namespace http {
 			keepalive_ = false;
 			write_in_progress = false;
 			connection_type = ConnectionType::connection_http;
-			socket_ = std::make_unique<boost::asio::ip::tcp::socket>(io_service);
+			socket_ = std::make_unique<boost::asio::ip::tcp::socket>(io_context);
 		}
 
 #ifdef WWW_ENABLE_SSL
 		// this is the constructor for secure connections
-		connection::connection(boost::asio::io_service &io_service, connection_manager &manager, request_handler &handler, int read_timeout, boost::asio::ssl::context &context)
+		connection::connection(boost::asio::io_context &io_context, connection_manager &manager, request_handler &handler, int read_timeout, boost::asio::ssl::context &context)
 			: send_buffer_(nullptr)
 			, read_timeout_(read_timeout)
-			, read_timer_(io_service, boost::posix_time::seconds(read_timeout))
+			, read_timer_(io_context, boost::posix_time::seconds(read_timeout))
 			, default_abandoned_timeout_(20 * 60)
 			// 20mn before stopping abandoned connection
-			, abandoned_timer_(io_service, boost::posix_time::seconds(default_abandoned_timeout_))
+			, abandoned_timer_(io_context, boost::posix_time::seconds(default_abandoned_timeout_))
 			, connection_manager_(manager)
 			, request_handler_(handler)
 			, status_(INITIALIZING)
@@ -62,7 +62,7 @@ namespace http {
 			write_in_progress = false;
 			connection_type = ConnectionType::connection_http;
 			socket_ = nullptr;
-			sslsocket_ = std::make_unique<ssl_socket>(io_service, context);
+			sslsocket_ = std::make_unique<ssl_socket>(io_context, context);
 		}
 #endif
 
@@ -152,9 +152,9 @@ namespace http {
 			if (error != boost::asio::error::operation_aborted) {
 				switch (connection_type) {
 				case ConnectionType::connection_http:
-					// Timers should be cancelled before stopping to remove tasks from the io_service.
-					// The io_service will stop naturally when every tasks are removed.
-					// If timers are not cancelled, the exception ERROR_ABANDONED_WAIT_0 is thrown up to the io_service::run() caller.
+					// Timers should be cancelled before stopping to remove tasks from the io_context.
+					// The io_context will stop naturally when every tasks are removed.
+					// If timers are not cancelled, the exception ERROR_ABANDONED_WAIT_0 is thrown up to the io_context::run() caller.
 					cancel_abandoned_timeout();
 					cancel_read_timeout();
 
@@ -372,7 +372,7 @@ namespace http {
 				switch (connection_type)
 				{
 				case ConnectionType::connection_http:
-					begin = boost::asio::buffer_cast<const char*>(_buf.data());
+					begin = static_cast<const char*>(_buf.data().data());
 					try
 					{
 						request_parser_.reset();
@@ -404,7 +404,7 @@ namespace http {
 							newt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
 						}
 
-						size_t sizeread = begin - boost::asio::buffer_cast<const char*>(_buf.data());
+						size_t sizeread = begin - static_cast<const char*>(_buf.data().data());
 						_buf.consume(sizeread);
 						reply_.reset();
 						const char* pConnection = request_.get_req_header(&request_, "Connection");
@@ -520,7 +520,7 @@ namespace http {
 					break;
 				case ConnectionType::connection_websocket:
 				case ConnectionType::connection_websocket_closing:
-					begin = boost::asio::buffer_cast<const char*>(_buf.data());
+					begin = static_cast<const char*>(_buf.data().data());
 					result = websocket_parser.parse((const unsigned char*)begin, _buf.size(), bytes_consumed, keepalive_);
 					_buf.consume(bytes_consumed);
 					if (result) {
diff --git webserver/connection.hpp webserver/connection.hpp
index ce452b5..c1a82c5 100644
--- webserver/connection.hpp
+++ webserver/connection.hpp
@@ -43,11 +43,11 @@ namespace http {
 				std::string host_local_endpoint_port_;
 				std::string host_last_request_uri_;
 			};
-			/// Construct a connection with the given io_service.
-			explicit connection(boost::asio::io_service& io_service,
+			/// Construct a connection with the given io_context.
+			explicit connection(boost::asio::io_context& io_context,
 				connection_manager& manager, request_handler& handler, int timeout);
 #ifdef WWW_ENABLE_SSL
-			explicit connection(boost::asio::io_service& io_service,
+			explicit connection(boost::asio::io_context& io_context,
 				connection_manager& manager, request_handler& handler, int timeout, boost::asio::ssl::context& context);
 #endif
 			~connection() = default;
diff --git webserver/server.cpp webserver/server.cpp
index da15887..8bdfc13 100644
--- webserver/server.cpp
+++ webserver/server.cpp
@@ -13,15 +13,15 @@ namespace http {
 namespace server {
 
 	server_base::server_base(const server_settings &settings, request_handler &user_request_handler)
-		: io_service_()
-		, acceptor_(io_service_)
+		: io_context_()
+		, acceptor_(io_context_)
 		, request_handler_(user_request_handler)
 		, settings_(settings)
 		, timeout_(20)
 		, // default read timeout in seconds
 		is_running(false)
 		, is_stop_complete(false)
-		, m_heartbeat_timer(io_service_)
+		, m_heartbeat_timer(io_context_)
 	{
 		if (!settings.is_enabled())
 		{
@@ -39,10 +39,10 @@ namespace server {
 		}
 
 		// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
-		boost::asio::ip::tcp::resolver resolver(io_service_);
-		boost::asio::ip::tcp::resolver::query query(settings_.listening_address, settings_.listening_port);
-		boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
-		acceptor_.open(endpoint.protocol());
+		boost::asio::ip::tcp::resolver resolver(io_context_);
+		boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::results_type endpoints = resolver.resolve(settings_.listening_address, settings_.listening_port);
+		auto endpoint = *endpoints.begin();
+		acceptor_.open(endpoint.endpoint().protocol());
 		acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
 		// bind to both ipv6 and ipv4 sockets for the "::" address only
 		if (settings_.listening_address == "::")
@@ -59,28 +59,28 @@ namespace server {
 	}
 
 void server_base::run() {
-	// The io_service::run() call will block until all asynchronous operations
+	// The io_context::run() call will block until all asynchronous operations
 	// have finished. While the server is running, there is always at least one
 	// asynchronous operation outstanding: the asynchronous accept call waiting
 	// for new incoming connections.
 	try {
 		is_running = true;
 		heart_beat(boost::system::error_code());
-		io_service_.run();
+		io_context_.run();
 		is_running = false;
 	} catch (std::exception& e) {
 		_log.Log(LOG_ERROR, "[web:%s] exception occurred : '%s' (need to run again)", settings_.listening_port.c_str(), e.what());
 		is_running = false;
 		// Note: if acceptor is up everything is OK, we can call run() again
 		//       but if the exception has broken the acceptor we cannot stop/start it and the next run() will exit immediatly.
-		io_service_.reset(); // this call is needed before calling run() again
+		io_context_.restart(); // this call is needed before calling run() again
 		throw;
 	} catch (...) {
 		_log.Log(LOG_ERROR, "[web:%s] unknown exception occurred (need to run again)", settings_.listening_port.c_str());
 		is_running = false;
 		// Note: if acceptor is up everything is OK, we can call run() again
 		//       but if the exception has broken the acceptor we cannot stop/start it and the next run() will exit immediatly.
-		io_service_.reset(); // this call is needed before calling run() again
+		io_context_.restart(); // this call is needed before calling run() again
 		throw;
 	}
 }
@@ -89,12 +89,12 @@ void server_base::run() {
 void server_base::stop() {
 	if (is_running) {
 		// Post a call to the stop function so that server_base::stop() is safe to call from any thread.
-		// Rene, set is_running to false, because the following is an io_service call, which makes is_running
+		// Rene, set is_running to false, because the following is an io_context call, which makes is_running
 		// never set to false whilst in the call itself
 		is_running = false;
-		io_service_.post([this] { handle_stop(); });
+		boost::asio::post(io_context_, [this] { handle_stop(); });
 	} else {
-		// if io_service is not running then the post call will not be performed
+		// if io_context is not running then the post call will not be performed
 		handle_stop();
 	}
 
@@ -112,7 +112,7 @@ void server_base::stop() {
 		}
 		sleep_milliseconds(500);
 	}
-	io_service_.stop();
+	io_context_.stop();
 
 	// Deregister heartbeat
 	m_mainworker.HeartbeatRemove(std::string("WebServer:") + settings_.listening_port);
@@ -136,7 +136,7 @@ void server_base::heart_beat(const boost::system::error_code& error)
 		m_mainworker.HeartbeatUpdate(std::string("WebServer:") + settings_.listening_port);
 
 		// Schedule next heartbeat
-		m_heartbeat_timer.expires_from_now(std::chrono::seconds(4));
+		m_heartbeat_timer.expires_after(std::chrono::seconds(4));
 		m_heartbeat_timer.async_wait([this](auto &&err) { heart_beat(err); });
 	}
 }
@@ -148,7 +148,7 @@ server::server(const server_settings &settings, request_handler &user_request_ha
 }
 
 void server::init_connection() {
-	new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_));
+	new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_));
 }
 
 /**
@@ -157,7 +157,7 @@ void server::init_connection() {
 void server::handle_accept(const boost::system::error_code& e) {
 	if (!e) {
 		connection_manager_.start(new_connection_);
-		new_connection_.reset(new connection(io_service_,
+		new_connection_.reset(new connection(io_context_,
 				connection_manager_, request_handler_, timeout_));
 		// listen for a subsequent request
 		acceptor_.async_accept(new_connection_->socket(), [this](auto &&err) { handle_accept(err); });
@@ -267,7 +267,7 @@ void ssl_server::init_connection() {
 	} else {
 		_log.Log(LOG_ERROR, "[web:%s] missing SSL DH parameters file %s!", settings_.listening_port.c_str(), settings_.tmp_dh_file_path.c_str());
 	}
-	new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_, context_));
+	new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_, context_));
 }
 
 void ssl_server::reinit_connection()
@@ -305,7 +305,7 @@ void ssl_server::reinit_connection()
 			_log.Log(LOG_ERROR, "[web:%s] missing SSL DH parameters from file %s", settings_.listening_port.c_str(), settings_.tmp_dh_file_path.c_str());
 		}
 	}
-	new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_, timeout_, context_));
+	new_connection_.reset(new connection(io_context_, connection_manager_, request_handler_, timeout_, context_));
 }
 
 /**
diff --git webserver/server.hpp webserver/server.hpp
index f9e71c5..bd7132a 100644
--- webserver/server.hpp
+++ webserver/server.hpp
@@ -31,7 +31,7 @@ namespace http
 			explicit server_base(const server_settings &settings, request_handler &user_request_handler);
 			virtual ~server_base() = default;
 
-			/// Run the server's io_service loop.
+			/// Run the server's io_context loop.
 			void run();
 
 			/// Stop the server.
@@ -46,8 +46,8 @@ namespace http
 		      protected:
 			void init(const init_connectionhandler_func &init_connection_handler, accept_handler_func accept_handler);
 
-			/// The io_service used to perform asynchronous operations.
-			boost::asio::io_service io_service_;
+			/// The io_context used to perform asynchronous operations.
+			boost::asio::io_context io_context_;
 
 			/// Acceptor used to listen for incoming connections.
 			boost::asio::ip::tcp::acceptor acceptor_;
