|
UniSet
2.6.0
|
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 IOController_H_ 00023 #define IOController_H_ 00024 //--------------------------------------------------------------------------- 00025 #include <unordered_map> 00026 #include <list> 00027 #include <sigc++/sigc++.h> 00028 #include "IOController_i.hh" 00029 #include "UniSetTypes.h" 00030 #include "UniSetManager.h" 00031 #include "Configuration.h" 00032 #include "Mutex.h" 00033 //--------------------------------------------------------------------------- 00034 namespace uniset 00035 { 00037 class IOController: 00038 public UniSetManager, 00039 public POA_IOController_i 00040 { 00041 public: 00042 00043 IOController( const std::string& name, const std::string& section ); 00044 IOController( const uniset::ObjectId id ); 00045 virtual ~IOController(); 00046 00047 virtual uniset::ObjectType getType() override 00048 { 00049 return uniset::ObjectType("IOController"); 00050 } 00051 00052 virtual uniset::SimpleInfo* getInfo( const char* userparam = "" ) override; 00053 00054 virtual CORBA::Long getValue( uniset::ObjectId sid ) override; 00055 00056 // -------------------- !!!!!!!!! --------------------------------- 00057 // Реализуются конкретным i/o контроллером 00058 // Не забывайте писать реализацию этих функций 00059 virtual void setValue( uniset::ObjectId sid, CORBA::Long value, 00060 uniset::ObjectId sup_id = uniset::DefaultObjectId ) override; 00061 00062 // ---------------------------------------------------------------- 00063 virtual void setUndefinedState( uniset::ObjectId sid, 00064 CORBA::Boolean undefined, 00065 uniset::ObjectId sup_id = uniset::DefaultObjectId ) override; 00066 00067 00068 virtual IOController_i::SensorInfoSeq* getSensorSeq( const uniset::IDSeq& lst ) override; 00069 virtual uniset::IDSeq* setOutputSeq( const IOController_i::OutSeq& lst, uniset::ObjectId sup_id ) override; 00070 00071 // ---------------------------------------------------------------- 00072 virtual UniversalIO::IOType getIOType( uniset::ObjectId sid ) override; 00073 00074 virtual IOController_i::SensorInfoSeq* getSensorsMap() override; 00075 virtual IOController_i::SensorIOInfo getSensorIOInfo( uniset::ObjectId sid ) override; 00076 00077 virtual CORBA::Long getRawValue( uniset::ObjectId sid ) override; 00078 virtual void calibrate( uniset::ObjectId sid, 00079 const IOController_i::CalibrateInfo& ci, 00080 uniset::ObjectId adminId ) override; 00081 00082 IOController_i::CalibrateInfo getCalibrateInfo( uniset::ObjectId sid ) override; 00083 00084 inline IOController_i::SensorInfo SensorInfo( const uniset::ObjectId sid, 00085 const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode()) 00086 { 00087 IOController_i::SensorInfo si; 00088 si.id = sid; 00089 si.node = node; 00090 return si; 00091 }; 00092 00093 uniset::Message::Priority getPriority( const uniset::ObjectId id ); 00094 00095 virtual IOController_i::ShortIOInfo getTimeChange( const uniset::ObjectId id ) override; 00096 00097 virtual IOController_i::ShortMapSeq* getSensors() override; 00098 00099 #ifndef DISABLE_REST_API 00100 // http API 00101 virtual Poco::JSON::Object::Ptr httpHelp( const Poco::URI::QueryParameters& p ) override; 00102 virtual Poco::JSON::Object::Ptr httpRequest( const std::string& req, const Poco::URI::QueryParameters& p ) override; 00103 #endif 00104 00105 public: 00106 00107 // предварительное объявление.. 00108 struct USensorInfo; 00109 typedef std::unordered_map<uniset::ObjectId, std::shared_ptr<USensorInfo>> IOStateList; 00110 00111 // ================== Достпуные сигналы ================= 00117 typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeSignal; 00118 typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeUndefinedStateSignal; 00119 00120 // signal по изменению определённого датчика 00121 ChangeSignal signal_change_value( uniset::ObjectId sid ); 00122 00123 // signal по изменению любого датчика 00124 ChangeSignal signal_change_value(); 00125 00126 // сигналы по изменению флага "неопределённое состояние" (обрыв датчика например) 00127 ChangeUndefinedStateSignal signal_change_undefined_state( uniset::ObjectId sid ); 00128 ChangeUndefinedStateSignal signal_change_undefined_state(); 00129 // ----------------------------------------------------------------------------------------- 00130 // полнейшее нарушение икапсуляции 00131 // но пока, это попытка оптимизировать работу с IOController через указатель. 00132 // Т.е. работая с датчиками через итераторы.. 00133 inline IOStateList::iterator ioBegin() 00134 { 00135 return ioList.begin(); 00136 } 00137 inline IOStateList::iterator ioEnd() 00138 { 00139 return ioList.end(); 00140 } 00141 inline IOStateList::iterator find( uniset::ObjectId k ) 00142 { 00143 return ioList.find(k); 00144 } 00145 inline int ioCount() const 00146 { 00147 return ioList.size(); 00148 } 00149 00150 protected: 00151 00152 // доступ к элементам через итератор 00153 // return итоговое значение 00154 virtual long localSetValueIt( IOStateList::iterator& it, const uniset::ObjectId sid, 00155 CORBA::Long value, uniset::ObjectId sup_id ); 00156 00157 virtual long localGetValue( IOStateList::iterator& it, const uniset::ObjectId sid ); 00158 00163 virtual void localSetUndefinedState( IOStateList::iterator& it, bool undefined, 00164 const uniset::ObjectId sid ); 00165 00166 // -- работа через указатель --- 00167 virtual long localSetValue( std::shared_ptr<USensorInfo>& usi, CORBA::Long value, uniset::ObjectId sup_id ); 00168 long localGetValue( std::shared_ptr<USensorInfo>& usi) ; 00169 00170 #ifndef DISABLE_REST_API 00171 // http API 00172 virtual Poco::JSON::Object::Ptr request_get( const std::string& req, const Poco::URI::QueryParameters& p ); 00173 virtual Poco::JSON::Object::Ptr request_sensors( const std::string& req, const Poco::URI::QueryParameters& p ); 00174 void getSensorInfo( Poco::JSON::Array::Ptr& jdata, std::shared_ptr<USensorInfo>& s , bool shortInfo = false ); 00175 #endif 00176 00177 // переопределяем для добавления вызова регистрации датчиков 00178 virtual bool deactivateObject() override; 00179 virtual bool activateObject() override; 00180 00182 virtual void activateInit(); 00183 00185 virtual void sensorsRegistration() {}; 00187 virtual void sensorsUnregistration(); 00188 00189 typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> InitSignal; 00190 00191 // signal по изменению определённого датчика 00192 InitSignal signal_init(); 00193 00197 void ioRegistration(std::shared_ptr<USensorInfo>& usi, bool force = false ); 00198 00200 void ioUnRegistration( const uniset::ObjectId sid ); 00201 00202 // ------------------------------ 00203 inline IOController_i::SensorIOInfo 00204 SensorIOInfo(long v, UniversalIO::IOType t, const IOController_i::SensorInfo& si, 00205 uniset::Message::Priority p = uniset::Message::Medium, 00206 long defval = 0, IOController_i::CalibrateInfo* ci = 0, 00207 uniset::ObjectId sup_id = uniset::DefaultObjectId ) 00208 { 00209 IOController_i::SensorIOInfo ai; 00210 ai.si = si; 00211 ai.type = t; 00212 ai.value = v; 00213 ai.priority = p; 00214 ai.default_val = defval; 00215 ai.real_value = v; 00216 ai.blocked = false; 00217 ai.supplier = sup_id; 00218 00219 if( ci != 0 ) 00220 ai.ci = *ci; 00221 else 00222 { 00223 ai.ci.minRaw = 0; 00224 ai.ci.maxRaw = 0; 00225 ai.ci.minCal = 0; 00226 ai.ci.maxCal = 0; 00227 ai.ci.precision = 0; 00228 } 00229 00230 return std::move(ai); 00231 }; 00232 00234 virtual void logging( uniset::SensorMessage& sm ); 00235 00237 virtual void dumpToDB(); 00238 00239 IOController(); 00240 00241 // доступ к списку c изменением только для своих 00242 IOStateList::iterator myioBegin(); 00243 IOStateList::iterator myioEnd(); 00244 IOStateList::iterator myiofind( uniset::ObjectId id ); 00245 size_t ioCount(); 00246 // -------------------------- 00247 00248 private: 00249 friend class NCRestorer; 00250 friend class SMInterface; 00251 00252 std::mutex siganyMutex; 00253 ChangeSignal sigAnyChange; 00254 00255 std::mutex siganyundefMutex; 00256 ChangeSignal sigAnyUndefChange; 00257 InitSignal sigInit; 00258 00259 IOStateList ioList; 00260 uniset::uniset_rwmutex ioMutex; 00262 bool isPingDBServer; // флаг связи с DBServer-ом 00263 00264 std::mutex loggingMutex; 00266 public: 00267 struct USensorInfo: 00268 public IOController_i::SensorIOInfo 00269 { 00270 USensorInfo( const USensorInfo& ) = delete; 00271 const USensorInfo& operator=(const USensorInfo& ) = delete; 00272 USensorInfo( USensorInfo&& ) = default; 00273 USensorInfo& operator=(USensorInfo&& ) = default; 00274 00275 USensorInfo(): d_value(1), d_off_value(0) 00276 { 00277 d_si.id = uniset::DefaultObjectId; 00278 d_si.node = uniset::DefaultObjectId; 00279 default_val = 0; 00280 value = default_val; 00281 real_value = default_val; 00282 dbignore = false; 00283 undefined = false; 00284 blocked = false; 00285 supplier = uniset::DefaultObjectId; 00286 } 00287 00288 virtual ~USensorInfo() {} 00289 00290 USensorInfo(IOController_i::SensorIOInfo& r); 00291 USensorInfo(IOController_i::SensorIOInfo* r); 00292 USensorInfo(const IOController_i::SensorIOInfo& r); 00293 00294 USensorInfo& operator=(IOController_i::SensorIOInfo& r); 00295 const USensorInfo& operator=(const IOController_i::SensorIOInfo& r); 00296 USensorInfo& operator=(IOController_i::SensorIOInfo* r); 00297 00298 // Дополнительные (вспомогательные поля) 00299 uniset::uniset_rwmutex val_lock; 00301 static const size_t MaxUserData = 4; 00302 void* userdata[MaxUserData] = { nullptr, nullptr, nullptr, nullptr }; 00304 // сигнал для реализации механизма зависимостией.. 00305 // (все зависимые датчики подключаются к нему (см. NCRestorer::init_depends_signals) 00306 uniset::uniset_rwmutex changeMutex; 00307 ChangeSignal sigChange; 00308 00309 uniset::uniset_rwmutex undefMutex; 00310 ChangeUndefinedStateSignal sigUndefChange; 00311 00312 IOController_i::SensorInfo d_si = { uniset::DefaultObjectId, uniset::DefaultObjectId }; 00313 long d_value = { 1 }; 00314 long d_off_value = { 0 }; 00315 std::shared_ptr<USensorInfo> d_usi; // shared_ptr на датчик от которого зависит этот. 00316 00317 size_t nchanges = { 0 }; // количество изменений датчика 00318 00319 // функция обработки информации об изменении состояния датчика, от которого зависит данный 00320 void checkDepend( std::shared_ptr<USensorInfo>& d_usi, IOController* ); 00321 00322 void init( const IOController_i::SensorIOInfo& s ); 00323 00324 inline IOController_i::SensorIOInfo makeSensorIOInfo() 00325 { 00326 uniset::uniset_rwmutex_rlock lock(val_lock); 00327 IOController_i::SensorIOInfo s(*this); 00328 return std::move(s); 00329 } 00330 00331 inline uniset::SensorMessage makeSensorMessage() 00332 { 00333 uniset::SensorMessage sm; 00334 sm.id = si.id; 00335 sm.node = si.node; // uniset_conf()->getLocalNode()? 00336 sm.sensor_type = type; 00337 sm.priority = (uniset::Message::Priority)priority; 00338 00339 // лочим только изменяемые поля 00340 { 00341 uniset::uniset_rwmutex_rlock lock(val_lock); 00342 sm.value = value; 00343 sm.sm_tv.tv_sec = tv_sec; 00344 sm.sm_tv.tv_nsec = tv_nsec; 00345 sm.ci = ci; 00346 sm.supplier = supplier; 00347 sm.undefined = undefined; 00348 } 00349 00350 return std::move(sm); 00351 } 00352 }; 00353 }; 00354 // ------------------------------------------------------------------------- 00355 } // end of uniset namespace 00356 // -------------------------------------------------------------------------- 00357 #endif 00358 // --------------------------------------------------------------------------
1.7.6.1