skeleton
This commit is contained in:
parent
10c36bc30c
commit
9d138b0045
@ -10,9 +10,50 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
set(BOOST_ROOT /usr/local)
|
set(BOOST_ROOT /usr/local)
|
||||||
find_package(Boost REQUIRED COMPONENTS system json)
|
find_package(Boost REQUIRED COMPONENTS system json)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
|
# Create a Boost-style interface target for a header-only library
|
||||||
|
function(create_boost_header_only_target target_name)
|
||||||
|
string(TOLOWER ${target_name} target_key)
|
||||||
|
set(interface_target ${target_key}_interface)
|
||||||
|
set(header_subdir ${target_key})
|
||||||
|
|
||||||
|
if(NOT TARGET Boost::${target_name})
|
||||||
|
message(STATUS "Creating Boost::${target_name} as header-only interface target")
|
||||||
|
|
||||||
|
add_library(${interface_target} INTERFACE)
|
||||||
|
|
||||||
|
# Add include dir if not explicitly set
|
||||||
|
if(DEFINED Boost_INCLUDE_DIRS)
|
||||||
|
target_include_directories(${interface_target} INTERFACE ${Boost_INCLUDE_DIRS})
|
||||||
|
else()
|
||||||
|
message(WARNING "Boost_INCLUDE_DIRS not defined when creating Boost::${target_name}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Optional preprocessor tweaks per library
|
||||||
|
if(${target_name} STREQUAL "asio")
|
||||||
|
target_compile_definitions(${interface_target} INTERFACE BOOST_ASIO_NO_DEPRECATED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create alias for consistency with imported targets
|
||||||
|
add_library(Boost::${target_name} ALIAS ${interface_target})
|
||||||
|
else()
|
||||||
|
message(STATUS "Boost::${target_name} already exists")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
create_boost_header_only_target(asio)
|
||||||
|
create_boost_header_only_target(assert)
|
||||||
|
create_boost_header_only_target(core)
|
||||||
|
create_boost_header_only_target(endian)
|
||||||
|
create_boost_header_only_target(fusion)
|
||||||
|
create_boost_header_only_target(optional)
|
||||||
|
create_boost_header_only_target(random)
|
||||||
|
create_boost_header_only_target(range)
|
||||||
|
create_boost_header_only_target(smart_ptr)
|
||||||
|
create_boost_header_only_target(spirit)
|
||||||
|
create_boost_header_only_target(type_traits)
|
||||||
|
|
||||||
# spdlog
|
# spdlog
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
spdlog
|
spdlog
|
||||||
@ -45,4 +86,4 @@ set(MQTT_BUILD_EXAMPLES OFF)
|
|||||||
set(async-mqtt5_INCLUDES_WITH_SYSTEM OFF)
|
set(async-mqtt5_INCLUDES_WITH_SYSTEM OFF)
|
||||||
FetchContent_MakeAvailable(asyncmqtt5)
|
FetchContent_MakeAvailable(asyncmqtt5)
|
||||||
|
|
||||||
add_subdirectory(floorheat_hub)
|
add_subdirectory(services)
|
||||||
|
|||||||
@ -1,88 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
import "ACPowerInternal.proto";
|
|
||||||
|
|
||||||
package acpowercontrol;
|
|
||||||
|
|
||||||
message Error{
|
|
||||||
///todo change to enum
|
|
||||||
string details = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ResetWatchdodRequest {
|
|
||||||
uint32 channel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ResetWatchdodResponse {
|
|
||||||
uint32 channel = 1;
|
|
||||||
optional Error error = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main control message that can include one of the above actions
|
|
||||||
message SetChannelRequest {
|
|
||||||
uint32 channel = 1;
|
|
||||||
oneof power {
|
|
||||||
acpowercontrol.internal.ACPowerSwitchBinary switch = 2;
|
|
||||||
acpowercontrol.internal.ACPowerToggle toggle = 3;
|
|
||||||
acpowercontrol.internal.ACPowerModulation modulation = 4;
|
|
||||||
acpowercontrol.internal.ACPowerSwipe swipe = 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetChannelResponse {
|
|
||||||
uint32 channel = 1;
|
|
||||||
optional Error error = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetChannelRequest {
|
|
||||||
uint32 channel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetChannelResponse{
|
|
||||||
uint32 channel = 1;
|
|
||||||
oneof resp{
|
|
||||||
uint32 current_power = 2;
|
|
||||||
Error error = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetChannelConfigRequest {
|
|
||||||
uint32 channel = 1;
|
|
||||||
acpowercontrol.internal.ChannelConfig config = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetChannelConfigResponse {
|
|
||||||
uint32 channel = 1;
|
|
||||||
optional Error error = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetChannelConfigRequest {
|
|
||||||
uint32 channel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetChannelConfigResponse {
|
|
||||||
uint32 channel = 1;
|
|
||||||
oneof resp {
|
|
||||||
acpowercontrol.internal.ChannelConfig config = 2;
|
|
||||||
Error error = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message ACPower{
|
|
||||||
oneof data{
|
|
||||||
ResetWatchdodRequest reset_wtchdod_request= 1;
|
|
||||||
ResetWatchdodResponse reset_wtchdod_response= 2;
|
|
||||||
|
|
||||||
SetChannelRequest set_channel_request = 3;
|
|
||||||
SetChannelResponse set_channel_response = 4;
|
|
||||||
|
|
||||||
GetChannelRequest get_channel_request = 5;
|
|
||||||
GetChannelResponse get_channel_response = 6;
|
|
||||||
|
|
||||||
SetChannelConfigRequest set_channel_config_request = 7;
|
|
||||||
SetChannelConfigResponse set_channel_config_response= 8;
|
|
||||||
|
|
||||||
GetChannelConfigRequest get_channel_config_request = 9;
|
|
||||||
GetChannelConfigResponse get_channel_config_response = 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package acpowercontrol.internal;
|
|
||||||
|
|
||||||
// channel configuration
|
|
||||||
message ChannelConfig{
|
|
||||||
uint32 faze_nr = 1;
|
|
||||||
uint32 default_watchdog_s = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message to represent basic on/off control
|
|
||||||
message ACPowerSwitchBinary {
|
|
||||||
bool on = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message to represent power toggle
|
|
||||||
message ACPowerToggle {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message to represent AC phase control (e.g., 30% of sine wave)
|
|
||||||
message ACPowerModulation {
|
|
||||||
// Phase percentage in i/10 of percent (value 123 rtanslates to 12.3%, typically 100.0)
|
|
||||||
uint32 phase_percentage = 1;
|
|
||||||
|
|
||||||
// number of sinusoids taken to control (2 is a full sinus cycle, default 1)
|
|
||||||
optional uint32 phaseGroup = 3; // if not present, assumed 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message to represent a soft start
|
|
||||||
message ACPowerSwipe {
|
|
||||||
enum Function{
|
|
||||||
Linear = 0;
|
|
||||||
Quadratic = 1; // Power increases exponentially over time, starting slow and speeding up.
|
|
||||||
Logarithmic = 2; // Power increases logarithmically, starting fast and slowing down as it approaches the end.
|
|
||||||
EaseInOut = 3; // This function starts and ends smoothly with a rapid change in the middle.
|
|
||||||
}
|
|
||||||
// Start percentage in i/10 of percent (value 123 rtanslates to 12.3%, typically 100.0)
|
|
||||||
optional uint32 start_percentage = 1;
|
|
||||||
|
|
||||||
// End percentage in i/10 of percent (value 123 rtanslates to 12.3%, typically 100.0)
|
|
||||||
uint32 end_percentage = 3;
|
|
||||||
|
|
||||||
// Duration in milliseconds
|
|
||||||
uint32 duration_ms = 5;
|
|
||||||
|
|
||||||
// function used
|
|
||||||
Function function=6;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
message FixedPoint {
|
|
||||||
int32 integer_part = 1;
|
|
||||||
uint32 fractional_part = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message x {
|
|
||||||
uint32 ch = 1;
|
|
||||||
bool state = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message FloatingPoint{
|
|
||||||
float val = 2;
|
|
||||||
}
|
|
||||||
message SingleFazeData {
|
|
||||||
float Voltage = 1;
|
|
||||||
float Current = 2;
|
|
||||||
float ActivePower = 3;
|
|
||||||
float ApparentPower = 4;
|
|
||||||
float PowerFactor = 5;
|
|
||||||
float ReActivePower = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message EnergymeterSensorData {
|
|
||||||
int32 sensor_id = 1;
|
|
||||||
SingleFazeData L1 = 2;
|
|
||||||
SingleFazeData L2 = 3;
|
|
||||||
SingleFazeData L3 = 4;
|
|
||||||
float TotalActivePower = 5;
|
|
||||||
float TotalPowerFactor = 6;
|
|
||||||
float TotalApparentePower = 7;
|
|
||||||
float TotalReActivePower = 8;
|
|
||||||
float GridFrequency = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
message can_frame {
|
|
||||||
uint32 left = 1;
|
|
||||||
bytes data = 2;
|
|
||||||
}
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
|
|
||||||
// internal
|
|
||||||
// channel configuration
|
|
||||||
message ChannelConfig{
|
|
||||||
uint32 faze = 1;
|
|
||||||
uint32 default_watchdog_s = 2;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message to represent basic on/off control
|
|
||||||
message ACPowerBinary {
|
|
||||||
bool on = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message to represent power toggle
|
|
||||||
message ACPowerToggle {}
|
|
||||||
|
|
||||||
// Message to represent AC phase control (e.g., 30% of sine wave)
|
|
||||||
message ACPowerProcentage {
|
|
||||||
// Phase percentage from 0 to 100
|
|
||||||
uint32 phase_percentage = 1;
|
|
||||||
uint32 phase_percentageFraction = 2;
|
|
||||||
|
|
||||||
// number of sinusoids taken to control (2 is a full sinus cycle, default 1)
|
|
||||||
optional uint32 phaseGroup = 3; // if not present, assumed 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message to represent a soft start
|
|
||||||
message ACPowerSwipe {
|
|
||||||
enum Function{
|
|
||||||
Linear = 0;
|
|
||||||
Quadratic = 1; // Power increases exponentially over time, starting slow and speeding up.
|
|
||||||
Logarithmic = 2; // Power increases logarithmically, starting fast and slowing down as it approaches the end.
|
|
||||||
EaseInOut = 3; // This function starts and ends smoothly with a rapid change in the middle.
|
|
||||||
}
|
|
||||||
// Start percentage (typically 0)
|
|
||||||
optional uint32 start_percentage = 1;
|
|
||||||
// Start percentage fraction (as 1/100 part of percentage) (typically 0)
|
|
||||||
uint32 start_percentage_fraction = 2;
|
|
||||||
|
|
||||||
// End percentage (typically 100)
|
|
||||||
uint32 end_percentage = 3;
|
|
||||||
// End percentage fraction (as 1/100 part of percentage) (typically 0)
|
|
||||||
uint32 end_percentage_fraction = 4;
|
|
||||||
|
|
||||||
// Duration in milliseconds
|
|
||||||
uint32 duration_ms = 5;
|
|
||||||
|
|
||||||
// function used
|
|
||||||
Function function=6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ACPowerControl{
|
|
||||||
oneof control_type {
|
|
||||||
ACPowerBinary binary = 5;
|
|
||||||
ACPowerProcentage procentage = 6;
|
|
||||||
ACPowerSwipe swipe = 7;
|
|
||||||
ACPowerToggle toggle = 8; // revert previous action
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message ACPowerResetWatchdod{
|
|
||||||
repeated uint32 channel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main control message that can include one of the above actions
|
|
||||||
message SetACPowerChannelControl {
|
|
||||||
uint32 channel = 1;
|
|
||||||
|
|
||||||
ACPowerControl power = 2;
|
|
||||||
|
|
||||||
// seconds after which output will be turned off (in case of lack of control messages) 0 -> uses default
|
|
||||||
uint32 watchdog_s = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetAcPowerChannelControl {
|
|
||||||
uint32 channel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetACPowerChannelConfig {
|
|
||||||
uint32 channel = 1;
|
|
||||||
ChannelConfig config = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetACPowerChannelConfig {
|
|
||||||
uint32 channel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum HeatingMessagesId{
|
|
||||||
ACPowerResetWatchdodID = 0;
|
|
||||||
|
|
||||||
SetACPowerChannelControlID = 1;
|
|
||||||
GetAcPowerChannelControlID = 2;
|
|
||||||
SetACPowerChannelConfigID = 3;
|
|
||||||
GetACPowerChannelConfigID = 4;
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
// single part of message
|
|
||||||
message Frame{
|
|
||||||
// frames left, 0 for End Of Stream
|
|
||||||
uint32 parts = 1; // parts left
|
|
||||||
|
|
||||||
// encapsulated message
|
|
||||||
bytes data = 2;
|
|
||||||
|
|
||||||
// type of message being encapsulated,only one of parts need to contain this information
|
|
||||||
uint32 type = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message PrintfArgument {
|
|
||||||
oneof arg_type {
|
|
||||||
int32 int_val = 1;
|
|
||||||
float float_val = 2;
|
|
||||||
double double_val = 3;
|
|
||||||
string string_val = 4;
|
|
||||||
bool bool_val = 5;
|
|
||||||
bytes bytes_val = 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message PrintfMessage {
|
|
||||||
string format_string = 1;
|
|
||||||
uint32 severity = 2;
|
|
||||||
repeated PrintfArgument arguments = 3;
|
|
||||||
}
|
|
||||||
1
services/CMakeLists.txt
Normal file
1
services/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
add_subdirectory(floorheat_hub)
|
||||||
@ -1,10 +1,3 @@
|
|||||||
# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS
|
|
||||||
# ../proto/message.proto
|
|
||||||
# ../proto/heating.proto
|
|
||||||
# ../proto/ACPower.proto
|
|
||||||
# ../proto/ACPowerInternal.proto
|
|
||||||
# )
|
|
||||||
|
|
||||||
add_executable(ranczo-io_floorheating
|
add_executable(ranczo-io_floorheating
|
||||||
main.cpp
|
main.cpp
|
||||||
heater.cpp
|
heater.cpp
|
||||||
@ -22,7 +15,7 @@ target_include_directories(ranczo-io_floorheating
|
|||||||
target_link_libraries(ranczo-io_floorheating
|
target_link_libraries(ranczo-io_floorheating
|
||||||
PUBLIC
|
PUBLIC
|
||||||
# ${Protobuf_LIBRARIES}
|
# ${Protobuf_LIBRARIES}
|
||||||
Async::MQTT5
|
Boost::mqtt5
|
||||||
Boost::system
|
Boost::system
|
||||||
Boost::json
|
Boost::json
|
||||||
spdlog::spdlog
|
spdlog::spdlog
|
||||||
@ -2,6 +2,7 @@
|
|||||||
#include <boost/asio/associated_executor.hpp>
|
#include <boost/asio/associated_executor.hpp>
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/detached.hpp>
|
#include <boost/asio/detached.hpp>
|
||||||
|
#include <boost/asio/io_context.hpp>
|
||||||
#include <boost/asio/this_coro.hpp>
|
#include <boost/asio/this_coro.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <memory_resource>
|
#include <memory_resource>
|
||||||
@ -131,7 +132,7 @@ boost::asio::awaitable<void> spawn(ranczo::AsyncMqttClient & c1){
|
|||||||
int main() {
|
int main() {
|
||||||
spdlog::set_level(spdlog::level::trace);
|
spdlog::set_level(spdlog::level::trace);
|
||||||
std::vector< std::unique_ptr< ranczo::IHeater > > _heaters;
|
std::vector< std::unique_ptr< ranczo::IHeater > > _heaters;
|
||||||
boost::asio::io_service io_service;
|
boost::asio::io_context io_service;
|
||||||
|
|
||||||
/// Strand powoduje ¿e zadania do niego przypisane zostaj± wykonane sekwencyjnie,
|
/// Strand powoduje ¿e zadania do niego przypisane zostaj± wykonane sekwencyjnie,
|
||||||
/// get_executor pobrany z io_service nie daje takiej mo¿liwo¶ci i wtedy mo¿na wykonywaæ zadania równloegle
|
/// get_executor pobrany z io_service nie daje takiej mo¿liwo¶ci i wtedy mo¿na wykonywaæ zadania równloegle
|
||||||
@ -153,7 +154,9 @@ int main() {
|
|||||||
// xes.emplace_back(std::allocate_shared< X >(alloc, io_executor, 2, "home/utilityRoom/floor/temperature"));
|
// xes.emplace_back(std::allocate_shared< X >(alloc, io_executor, 2, "home/utilityRoom/floor/temperature"));
|
||||||
// xes.emplace_back(std::allocate_shared< X >(alloc, io_executor, 3, "home/wardrobe/floor/temperature"));
|
// xes.emplace_back(std::allocate_shared< X >(alloc, io_executor, 3, "home/wardrobe/floor/temperature"));
|
||||||
|
|
||||||
boost::asio::io_service::work work(io_service);
|
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work_guard =
|
||||||
|
boost::asio::make_work_guard(io_service);
|
||||||
|
|
||||||
io_service.run();
|
io_service.run();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -6,12 +6,12 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <async_mqtt5.hpp>
|
#include <boost/mqtt5.hpp>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace ranczo {
|
namespace ranczo {
|
||||||
constexpr auto use_nothrow_awaitable = boost::asio::as_tuple(boost::asio::use_awaitable);
|
constexpr auto use_nothrow_awaitable = boost::asio::as_tuple(boost::asio::use_awaitable);
|
||||||
using client_type = async_mqtt5::mqtt_client< boost::asio::ip::tcp::socket >;
|
using client_type = boost::mqtt5::mqtt_client< boost::asio::ip::tcp::socket >;
|
||||||
|
|
||||||
struct AsyncMqttClient::AsyncMqttClientImpl {
|
struct AsyncMqttClient::AsyncMqttClientImpl {
|
||||||
const boost::asio::any_io_executor & _executor;
|
const boost::asio::any_io_executor & _executor;
|
||||||
@ -34,17 +34,17 @@ struct AsyncMqttClient::AsyncMqttClientImpl {
|
|||||||
|
|
||||||
boost::asio::awaitable< bool > subscribe(std::string_view topic) {
|
boost::asio::awaitable< bool > subscribe(std::string_view topic) {
|
||||||
// Configure the request to subscribe to a Topic.
|
// Configure the request to subscribe to a Topic.
|
||||||
async_mqtt5::subscribe_topic sub_topic = async_mqtt5::subscribe_topic{topic.data(),
|
boost::mqtt5::subscribe_topic sub_topic = boost::mqtt5::subscribe_topic{topic.data(),
|
||||||
async_mqtt5::subscribe_options{
|
boost::mqtt5::subscribe_options{
|
||||||
async_mqtt5::qos_e::exactly_once, // All messages will arrive at QoS 2.
|
boost::mqtt5::qos_e::exactly_once, // All messages will arrive at QoS 2.
|
||||||
async_mqtt5::no_local_e::no, // Forward message from Clients with same ID.
|
boost::mqtt5::no_local_e::no, // Forward message from Clients with same ID.
|
||||||
async_mqtt5::retain_as_published_e::retain, // Keep the original RETAIN flag.
|
boost::mqtt5::retain_as_published_e::retain, // Keep the original RETAIN flag.
|
||||||
async_mqtt5::retain_handling_e::send // Send retained messages when the subscription is established.
|
boost::mqtt5::retain_handling_e::send // Send retained messages when the subscription is established.
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// Subscribe to a single Topic.
|
// Subscribe to a single Topic.
|
||||||
auto && [ec, sub_codes, sub_props] =
|
auto && [ec, sub_codes, sub_props] =
|
||||||
co_await _mqtt_client.async_subscribe(sub_topic, async_mqtt5::subscribe_props{}, use_nothrow_awaitable);
|
co_await _mqtt_client.async_subscribe(sub_topic, boost::mqtt5::subscribe_props{}, use_nothrow_awaitable);
|
||||||
// Note: you can subscribe to multiple Topics in one mqtt_client::async_subscribe call.
|
// Note: you can subscribe to multiple Topics in one mqtt_client::async_subscribe call.
|
||||||
|
|
||||||
// An error can occur as a result of:
|
// An error can occur as a result of:
|
||||||
@ -65,7 +65,7 @@ struct AsyncMqttClient::AsyncMqttClientImpl {
|
|||||||
// Receive an Appplication Message from the subscribed Topic(s).
|
// Receive an Appplication Message from the subscribed Topic(s).
|
||||||
auto && [ec, topic, payload, publish_props] = co_await _mqtt_client.async_receive(use_nothrow_awaitable);
|
auto && [ec, topic, payload, publish_props] = co_await _mqtt_client.async_receive(use_nothrow_awaitable);
|
||||||
|
|
||||||
if(ec == async_mqtt5::client::error::session_expired) {
|
if(ec == boost::mqtt5::client::error::session_expired) {
|
||||||
/// TODO connect first, then subscribe to all topics
|
/// TODO connect first, then subscribe to all topics
|
||||||
// The Client has reconnected, and the prior session has expired.
|
// The Client has reconnected, and the prior session has expired.
|
||||||
// As a result, any previous subscriptions have been lost and must be reinstated.
|
// As a result, any previous subscriptions have been lost and must be reinstated.
|
||||||
Loading…
Reference in New Issue
Block a user