/* * SensorGroupTemplate.h * * Created on: 03.08.2018 * Author: Micha Mueller */ #ifndef SENSORGROUPTEMPLATE_H_ #define SENSORGROUPTEMPLATE_H_ #include "SensorGroupInterface.h" #include "timestamp.h" #include #include template class SensorGroupTemplate : public SensorGroupInterface { //the template shall only be instantiated for classes which derive from SensorBase static_assert(std::is_base_of::value, "S must derive from SensorBase!"); protected: using S_Ptr = std::shared_ptr; public: SensorGroupTemplate(const std::string groupName) : SensorGroupInterface(groupName) {} SensorGroupTemplate(const SensorGroupTemplate& other) : SensorGroupInterface(other) { for(auto s : other._sensors) { S_Ptr sensor = std::make_shared(*s); _sensors.push_back(sensor); _baseSensors.push_back(sensor); } } virtual ~SensorGroupTemplate() { _sensors.clear(); _baseSensors.clear(); } SensorGroupTemplate& operator=(const SensorGroupTemplate& other) { SensorGroupInterface::operator=(other); _sensors.clear(); _baseSensors.clear(); for(auto s : other._sensors) { S_Ptr sensor = std::make_shared(*s); _sensors.push_back(sensor); _baseSensors.push_back(sensor); } return *this; } virtual void pushBackSensor(SBasePtr s) override { //check if dynamic cast returns nullptr if (S_Ptr dSensor = std::dynamic_pointer_cast(s)) { _sensors.push_back(dSensor); _baseSensors.push_back(s); } else { LOG(warning) << "Group " << _groupName << ": Type mismatch when storing sensor! Sensor omitted"; } } virtual std::vector& getSensors() override { return _baseSensors; } virtual void init(boost::asio::io_service& io) override { SensorGroupInterface::init(io); for(auto s : _sensors) { s->initSensor(_interval); } } virtual void printConfig(LOG_LEVEL ll) override { LOG_VAR(ll) << " Sensors:"; for(auto s : _sensors) { s->SensorBase::printConfig(ll, lg); s->printConfig(ll, lg); } } protected: /** Calculate timestamp for the next reading * @return Timestamp in the future to wait for */ uint64_t nextReadingTime() { uint64_t now = getTimestamp(); uint64_t next; if (_sync) { uint64_t interval64 = static_cast(_interval); uint64_t now_ms = now / 1000 / 1000; uint64_t waitToStart = interval64 - (now_ms%interval64); //synchronize all measurements with other sensors if(!waitToStart ){ // less than 1 ms seconds is too small, so we wait the entire interval for the next measurement return (now_ms + interval64)*1000*1000; } return (now_ms + waitToStart)*1000*1000; } else { return now + MS_TO_NS(_interval); } } std::vector _sensors; std::vector _baseSensors; }; #endif /* SENSORGROUPTEMPLATE_H_ */