ranczo-io/floorheat_hub/main.cpp
2024-11-05 10:41:40 +01:00

161 lines
4.8 KiB
C++

#include "timer.hpp"
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/this_coro.hpp>
#include <memory>
#include <memory_resource>
#include <spdlog/spdlog.h>
#include <boost/asio.hpp>
#include <boost/asio/any_io_executor.hpp>
#include <boost/asio/basic_repeating_timer.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/strand.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/system/error_code.hpp>
#include <vector>
namespace ranczo {
class IHeater {
public:
virtual ~IHeater() = default;
};
class HeaterBase : public IHeater {
private:
boost::asio::repeating_timer timer;
protected:
double _targetTemperature;
double _histeresis;
public:
virtual void tick() {
spdlog::info("ping");
};
HeaterBase(boost::asio::any_io_executor & io_executor) : timer{io_executor} {
timer.start(boost::posix_time::seconds{1}, [&](const boost::system::error_code & e) {
// TODO error handling
spdlog::debug("Running timer");
this->tick();
});
}
};
class IRelay {
public:
virtual ~IRelay() = default;
virtual void setState(bool on) = 0;
virtual void state() = 0;
};
class ResistiveFloorHeater : public HeaterBase {};
class ModbusRelay : public IRelay {};
/// TODO
/// * Przypisanie prze³±cznika do maty grzewczej
/// * Zapis danych w DB
/// * Zapis ustawieñ
/// * Nas³uchiwanie na MQTT
} // namespace ranczo
// Modified completion token that will prevent co_await from throwing exceptions.
using namespace std::chrono_literals;
using boost::asio::yield_context;
using timer = boost::asio::steady_timer;
static auto now = timer::clock_type::now;
// struct X : private boost::noncopyable {
// int _id;
// boost::asio::any_io_executor _executor;
// std::string _topic;
// X(boost::asio::any_io_executor io_executor, int id, std::string topic) : _executor{io_executor}, _c{_executor}, _id{id}, _topic{topic} {
// spdlog::info("X for id/topic {}/{} created", _id, _topic);
// spdlog::info("timer for id {} start", _id);
// co_spawn(_executor, run_timer_id(), boost::asio::detached);
// spdlog::info("mqtt for id/topic {}/{} start", _id, _topic);
// co_spawn(_executor, subscribe_and_receive(_c, _topic), boost::asio::detached);
// }
// ~X() {
// spdlog::info("X {} destroyed", _id);
// }
// boost::asio::awaitable< void > run_timer_id() {
// auto executor = co_await boost::asio::this_coro::executor;
// int counter{0};
// boost::asio::steady_timer timer{executor};
// while(true) {
// timer.expires_after(std::chrono::seconds(1));
// co_await timer.async_wait(boost::asio::use_awaitable);
// spdlog::info("Hello from {}:{}", counter++, _id);
// }
// co_return;
// }
// };
#include "mqtt_client.hpp"
#include <boost/json.hpp>
boost::asio::awaitable<void> spawn(ranczo::AsyncMqttClient & c1){
spdlog::info("SPAWN subscribe");
co_await c1.subscribe("home/corridor/floor/temperature",[](const boost::json::value &){
spdlog::info("cb called");
});
spdlog::info("SPAWN listen");
co_await c1.listen();
spdlog::info("SPAWN return");
co_return;
}
int main() {
spdlog::set_level(spdlog::level::trace);
std::vector< std::unique_ptr< ranczo::IHeater > > _heaters;
boost::asio::io_service io_service;
/// 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
// boost::asio::any_io_executor io_executor = io_service.get_executor();
boost::asio::any_io_executor io_executor = boost::asio::make_strand(io_service);
char buffer[2048];
std::pmr::monotonic_buffer_resource mbr(buffer, 2048, std::pmr::null_memory_resource());
// "home/corridor/floor/temperature"
// "home/utilityRoom/floor/temperature"
// "home/wardrobe/floor/temperature"
// ranczo::AsyncMqttClient c1{io_executor};
// c1.add_subscribtion("home/corridor/floor/temperature", [](const boost::json::value &) { spdlog::info("cb called"); });
ranczo::PeriodicTimer timer{io_executor, std::chrono::seconds{1}, []() { spdlog::info("timer called"); }};
// xes.emplace_back(std::allocate_shared< X >(alloc, io_executor, 1, "home/corridor/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"));
boost::asio::io_service::work work(io_service);
io_service.run();
return 0;
}