UniSet  2.6.0
IONotifyController.h
00001 /*
00002  * Copyright (c) 2015 Pavel Vainerman.
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as
00006  * published by the Free Software Foundation, version 2.1.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00011  * Lesser General Lesser Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 // --------------------------------------------------------------------------
00021 // --------------------------------------------------------------------------
00022 #ifndef IONotifyController_H_
00023 #define IONotifyController_H_
00024 //---------------------------------------------------------------------------
00025 #include <memory>
00026 #include <unordered_map>
00027 #include <list>
00028 #include <string>
00029 
00030 #include "UniSetTypes.h"
00031 #include "IOController_i.hh"
00032 #include "IOController.h"
00033 
00034 //---------------------------------------------------------------------------
00035 namespace uniset
00036 {
00037 class NCRestorer;
00038 //---------------------------------------------------------------------------
00121 //---------------------------------------------------------------------------
00131 class IONotifyController:
00132     public IOController,
00133     public POA_IONotifyController_i
00134 {
00135     public:
00136 
00137         IONotifyController(const std::string& name, const std::string& section, std::shared_ptr<NCRestorer> dumper = nullptr );
00138         IONotifyController(const uniset::ObjectId id, std::shared_ptr<NCRestorer> dumper = nullptr );
00139 
00140         virtual ~IONotifyController();
00141 
00142         virtual uniset::ObjectType getType() override
00143         {
00144             return uniset::ObjectType("IONotifyController");
00145         }
00146 
00147         virtual uniset::SimpleInfo* getInfo( const char* userparam = 0 ) override;
00148 
00149         virtual void askSensor(const uniset::ObjectId sid, const uniset::ConsumerInfo& ci, UniversalIO::UIOCommand cmd) override;
00150 
00151         virtual void askThreshold(const uniset::ObjectId sid, const uniset::ConsumerInfo& ci,
00152                                   uniset::ThresholdId tid,
00153                                   CORBA::Long lowLimit, CORBA::Long hiLimit, CORBA::Boolean invert,
00154                                   UniversalIO::UIOCommand cmd ) override;
00155 
00156         virtual IONotifyController_i::ThresholdInfo getThresholdInfo( const uniset::ObjectId sid, uniset::ThresholdId tid ) override;
00157         virtual IONotifyController_i::ThresholdList* getThresholds(const uniset::ObjectId sid ) override;
00158         virtual IONotifyController_i::ThresholdsListSeq* getThresholdsList() override;
00159 
00160         virtual uniset::IDSeq* askSensorsSeq(const uniset::IDSeq& lst,
00161                                              const uniset::ConsumerInfo& ci, UniversalIO::UIOCommand cmd) override;
00162 
00163         // --------------------------------------------
00164 
00165 #ifndef DISABLE_REST_API
00166         // http API
00167         virtual Poco::JSON::Object::Ptr httpHelp( const Poco::URI::QueryParameters& p ) override;
00168         Poco::JSON::Object::Ptr httpRequest( const string& req, const Poco::URI::QueryParameters& p );
00169 #endif
00170 
00171         // --------------------------------------------
00173         struct ConsumerInfoExt:
00174             public uniset::ConsumerInfo
00175         {
00176             ConsumerInfoExt( const uniset::ConsumerInfo& ci,
00177                              UniSetObject_i_ptr ref = 0, size_t maxAttemtps = 10 ):
00178                 uniset::ConsumerInfo(ci),
00179                 ref(ref), attempt(maxAttemtps) {}
00180 
00181             UniSetObject_i_var ref;
00182             size_t attempt;
00183             size_t lostEvents = { 0 }; // количество потерянных сообщений (не смогли послать)
00184             size_t smCount = { 0 }; // количество посланных SensorMessage
00185 
00186             ConsumerInfoExt( const ConsumerInfoExt& ) = default;
00187             ConsumerInfoExt& operator=( const ConsumerInfoExt& ) = default;
00188             ConsumerInfoExt( ConsumerInfoExt&& ) = default;
00189             ConsumerInfoExt& operator=(ConsumerInfoExt&& ) = default;
00190         };
00191 
00192         typedef std::list<ConsumerInfoExt> ConsumerList;
00193 
00194         struct ConsumerListInfo
00195         {
00196             ConsumerListInfo(): mut("ConsumerInfoMutex") {}
00197             ConsumerList clst;
00198             uniset::uniset_rwmutex mut;
00199 
00200             ConsumerListInfo( const ConsumerListInfo& ) = delete;
00201             ConsumerListInfo& operator=( const ConsumerListInfo& ) = delete;
00202             ConsumerListInfo( ConsumerListInfo&& ) = default;
00203             ConsumerListInfo& operator=(ConsumerListInfo&& ) = default;
00204         };
00205 
00207         typedef std::unordered_map<uniset::ObjectId, ConsumerListInfo> AskMap;
00208 
00210         struct ThresholdInfoExt:
00211             public IONotifyController_i::ThresholdInfo
00212         {
00213             ThresholdInfoExt( uniset::ThresholdId tid, CORBA::Long low, CORBA::Long hi, bool inv,
00214                               uniset::ObjectId _sid = uniset::DefaultObjectId ):
00215                 sid(_sid),
00216                 invert(inv)
00217             {
00218                 id       = tid;
00219                 hilimit  = hi;
00220                 lowlimit = low;
00221                 state    = IONotifyController_i::NormalThreshold;
00222             }
00223 
00224             ConsumerListInfo clst; 
00227             uniset::ObjectId sid;
00228 
00230             IOController::IOStateList::iterator sit;
00231 
00233             bool invert;
00234 
00235             inline bool operator== ( const ThresholdInfo& r ) const
00236             {
00237                 return ((id == r.id) &&
00238                         (hilimit == r.hilimit) &&
00239                         (lowlimit == r.lowlimit) &&
00240                         (invert == r.invert) );
00241             }
00242 
00243             operator IONotifyController_i::ThresholdInfo()
00244             {
00245                 IONotifyController_i::ThresholdInfo r;
00246                 r.id = id;
00247                 r.hilimit = hilimit;
00248                 r.lowlimit = lowlimit;
00249                 r.invert = invert;
00250                 r.tv_sec = tv_sec;
00251                 r.tv_nsec = tv_nsec;
00252                 r.state = state;
00253                 return r;
00254             }
00255 
00256             ThresholdInfoExt( const ThresholdInfoExt& ) = delete;
00257             ThresholdInfoExt& operator=( const ThresholdInfoExt& ) = delete;
00258             ThresholdInfoExt( ThresholdInfoExt&& ) = default;
00259             ThresholdInfoExt& operator=(ThresholdInfoExt&& ) = default;
00260         };
00261 
00263         typedef std::list<ThresholdInfoExt> ThresholdExtList;
00264 
00265         struct ThresholdsListInfo
00266         {
00267             ThresholdsListInfo() {}
00268             ThresholdsListInfo( const IOController_i::SensorInfo& si, ThresholdExtList&& list,
00269                                 UniversalIO::IOType t = UniversalIO::AI ):
00270                 si(si), type(t), list( std::move(list) ) {}
00271 
00272             uniset::uniset_rwmutex mut;
00273 
00274             IOController_i::SensorInfo si = { uniset::DefaultObjectId, uniset::DefaultObjectId };
00275             std::shared_ptr<USensorInfo> usi;
00276             UniversalIO::IOType type = { UniversalIO::AI };
00277             ThresholdExtList list;   
00278         };
00279 
00281         typedef std::unordered_map<uniset::ObjectId, ThresholdsListInfo> AskThresholdMap;
00282 
00283     protected:
00284         IONotifyController();
00285         virtual bool activateObject() override;
00286         virtual void initItem(std::shared_ptr<USensorInfo>& usi, IOController* ic );
00287 
00289         virtual void send( ConsumerListInfo& lst, const uniset::SensorMessage& sm );
00290 
00292         virtual void checkThreshold( std::shared_ptr<USensorInfo>& usi, bool send = true );
00293         virtual void checkThreshold(IOController::IOStateList::iterator& li, const uniset::ObjectId sid, bool send_msg = true );
00294 
00296         ThresholdExtList::iterator findThreshold( const uniset::ObjectId sid, const uniset::ThresholdId tid );
00297 
00301         virtual void dumpOrdersList( const uniset::ObjectId sid, const IONotifyController::ConsumerListInfo& lst );
00302 
00306         virtual void dumpThresholdList( const uniset::ObjectId sid, const IONotifyController::ThresholdExtList& lst );
00307 
00309         virtual void readDump();
00310 
00311         std::shared_ptr<NCRestorer> restorer;
00312 
00313         void onChangeUndefinedState( std::shared_ptr<USensorInfo>& usi, IOController* ic );
00314 
00315         // функция для работы напрямую с указателем (оптимизация)
00316         virtual long localSetValue( std::shared_ptr<USensorInfo>& usi,
00317                                     CORBA::Long value, uniset::ObjectId sup_id ) override;
00318 
00320         // идентификаторы данные в userdata (см. USensorInfo::userdata)
00321         enum UserDataID
00322         {
00323             udataConsumerList = 0,
00324             udataThresholdList = 1
00325         };
00326 
00327 #ifndef DISABLE_REST_API
00328         // http api
00329         Poco::JSON::Object::Ptr request_consumers( const std::string& req, const Poco::URI::QueryParameters& p );
00330         Poco::JSON::Object::Ptr request_lost( const string& req, const Poco::URI::QueryParameters& p );
00331         Poco::JSON::Object::Ptr getConsumers(uniset::ObjectId sid, ConsumerListInfo& clist, bool ifNotEmpty = true );
00332 #endif
00333                 
00334     private:
00335         friend class NCRestorer;
00336 
00337         //----------------------
00338         bool addConsumer(ConsumerListInfo& lst, const uniset::ConsumerInfo& cons );     
00339         bool removeConsumer(ConsumerListInfo& lst, const uniset::ConsumerInfo& cons );  
00340 
00342         void ask(AskMap& askLst, const uniset::ObjectId sid,
00343                  const uniset::ConsumerInfo& ci, UniversalIO::UIOCommand cmd);
00344 
00346         bool addThreshold(ThresholdExtList& lst, ThresholdInfoExt&& ti, const uniset::ConsumerInfo& ci);
00348         bool removeThreshold(ThresholdExtList& lst, ThresholdInfoExt& ti, const uniset::ConsumerInfo& ci);
00349 
00350         AskMap askIOList; 
00351         AskThresholdMap askTMap; 
00354         uniset::uniset_rwmutex askIOMutex;
00356         uniset::uniset_rwmutex trshMutex;
00357 
00358         sigc::connection conInit;
00359         sigc::connection conUndef;
00360 
00361         int maxAttemtps; 
00362         int sendAttemtps; 
00364         std::mutex lostConsumersMutex;
00365 
00366         struct LostConsumerInfo
00367         {
00368             size_t count = { 0 }; // количество "пропаданий"
00369             bool lost = { false }; // флаг означающий что "заказчик пропал"
00370             // lost нужен чтобы в count не увеличивать, на send() по каждому датчику, если заказчик заказывал больше одного датчика)
00371             // флаг сбрасывается при перезаказе датчика..
00372         };
00373 
00379         std::unordered_map<uniset::ObjectId, LostConsumerInfo> lostConsumers;
00380 };
00381 // -------------------------------------------------------------------------
00382 } // end of uniset namespace
00383 // --------------------------------------------------------------------------
00384 #endif
00385 // --------------------------------------------------------------------------