commit d08fe76884b713620d4648d878237f82c1da0198 Author: zonetest Date: Tue Jul 11 09:18:32 2017 -0400 Premier commit suite au crash du repo le 10 juillet 2017 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b0795ff --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +/LOG/LogZT.txt +/ING/IngLog.txt +/sources/TKGenerator.cpp.autosave +/.svn +*.o +ZT.pro.user +/Debug +/Release +moc_*.* +/Trains +*.Autosave diff --git a/ChangeOwner b/ChangeOwner new file mode 100755 index 0000000..6cb84a6 --- /dev/null +++ b/ChangeOwner @@ -0,0 +1,2 @@ +#!/bin/bash +sudo chown -R zonetest:zonetest ./* diff --git a/Configuration/ZT.cfg b/Configuration/ZT.cfg new file mode 100644 index 0000000..8c3fb09 --- /dev/null +++ b/Configuration/ZT.cfg @@ -0,0 +1,81 @@ +################################################################# +# Fichier de configuration de la Zone Tests # +# # +# Ce fichier doit être adapté en fonction # +# de la configuration particulière de chaque # +# Zone Tests # +# # +# CHAQUE LIGNE VALIDE DOIT SE TERMINER PAR UN # +# "ENTER". NE PAS METTRE DE COMMENTAIRES À LA # +# FIN D'UNE LIGNE. NE PAS METTRE D'ESPACE AVANT # +# OU APRÈS LE CARACTÈRE '=' # +# # +################################################################# + + +##################### Paramètres d'ingénierie ######################## + +#paramètres des modules d'entrées/sorties externes + +#L'adresse IP du module maître. +EXTIO_MASTER_IP=192.168.0.51 +#DATAQ_IP=192.168.0.103 + +#--------------------------------- +#Paramètres des différents modules installés. L'identification des +#différents modules est importante, le _n à la fin doit correspondre +#au "Module ID" qui est définit dans le code source de l'application. +#C'est cette identification qui indique au programme ce qui est branché +#sur le module. Il est donc possible de changer l'adresse physique d'un +#module en changeant la configuration ici. +#Ex.: EXTIO_430_MOD_PHYS_ADDR_n=x + +EXTIO_430_MOD_PHYS_ADDR_1=2 +EXTIO_440_MOD_PHYS_ADDR_1=3 +#EXTIO_470_MOD_PHYS_ADDR_1=4 + +#---------------------------------- +#Configuration des ports série des sondes Lazer. +#L'identification est importante, le _n à la fin doit correspondre +#au "LazerProbe ID" qui est définit dans le code source de l'application. +#Dans les stations normales où il n'y a que 2 sondes, le ID est "1". +#Ex.: SONDE_LASER_INT_1=x + +SONDE_LASER_INT_1=ttyS2 +SONDE_LASER_EXT_1=ttyS0 + +#---------------------------------- +#Changer cette valeur à OUI ou NON pour sélectionner la communication Modbus +#avec la CC +UTILISER_MODBUS_CC=NON +#Adresse modbus de la ZT +MODBUS_CC_DEVID=9 +#Port Modbus/TCP +MODBUS_CC_PORT=2182 + +#---------------------------------- +#Changer cette valeur à OUI ou NON pour activer le +SIMULATEUR=OUI + +#--------------------------------- +#Commenter cette ligne pour désactiver le log d'igénierie +#Sinon, fixer la verbosité entre 1 et 3, 3 étant un log très détaillé. +ENGLOG=3 + + + + +######################### Paramètres de la station ################ +#Une seule station doit être sélectionnée + +#STATION=HONORE_BEAUGRAND +#STATION=ANGRIGNON +#STATION=HENRI_BOURASSA +#STATION=COTE_VERTU +STATION=BERRI_UQAM +#STATION=LONGUEIL +#STATION=SAINT_MICHEL +#STATION=SNOWDON_L5 +#STATION=MONTMORENCY +#STATION=MONTMORENCY_10_12 +#STATION=MONTMORENCY_10_22 diff --git a/Configuration/ZT.pwd b/Configuration/ZT.pwd new file mode 100644 index 0000000..af3a00c --- /dev/null +++ b/Configuration/ZT.pwd @@ -0,0 +1 @@ +zonetest diff --git a/Configuration/ZTSettings.ztc b/Configuration/ZTSettings.ztc new file mode 100644 index 0000000..8a86c07 Binary files /dev/null and b/Configuration/ZTSettings.ztc differ diff --git a/Configuration/test.png b/Configuration/test.png new file mode 100644 index 0000000..21529e9 Binary files /dev/null and b/Configuration/test.png differ diff --git a/Escape.ZT b/Escape.ZT new file mode 100644 index 0000000..a3abe50 --- /dev/null +++ b/Escape.ZT @@ -0,0 +1 @@ +exit diff --git a/FTPGetSources.sh b/FTPGetSources.sh new file mode 100644 index 0000000..5ee1b6b --- /dev/null +++ b/FTPGetSources.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# + +set -x + +cd ../down +rm -rf ./ZT + +sftp -r zonetest@192.168.0.101 << END_SCRIPT +zonetest +cd /home/zonetest/DevZT/ZT +rm ./Debug/* +rm ./Release/* +rm ./Trains/* +cd .. +get ./ZT +quit +END_SCRIPT + +cd ZT + +rm -rf Configuration +rm -f ZT.pro.* +#rm setztexecutable +rm -rf ./LOG/* +rm -rf ./ING/* + +cd /home/zonetest/DevZT/down +mkdir bak +cp -rf ../ZT/Configuration ./bak +cp -rf ../ZT/ZT.pro.* ./bak +#cp -rf ../ZT/setztexecutable ./bak +#cp -rf ../ZT/GetSources ./bak + +rm -rf ../ZT/* + +cp -rf ./ZT/* ../ZT + +cp -rf ./bak/* ../ZT/ + +sudo chmod 777 ../ZT/setztexecutable +sudo chmod 777 ../ZT/GetSources.sh + +rm -rf ./bak + +exit diff --git a/GetSources.sh b/GetSources.sh new file mode 100755 index 0000000..6d87bcb --- /dev/null +++ b/GetSources.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# + +set -x + +cd /home/zonetest/DevZT/ + +rsync -av --exclude 'ZT.pro.*' --exclude 'Debug/*' --exclude 'Release/*' --exclude 'Trains/*' --exclude '.svn' zonetest@$1:/home/zonetest/DevZT/ZT ./ + +#clean up local object code +rm -rf ./ZT/Debug/* +rm -rf ./ZT/Release/* + +exit diff --git a/Images/GuiBackground.jpg b/Images/GuiBackground.jpg new file mode 100644 index 0000000..956c2bb Binary files /dev/null and b/Images/GuiBackground.jpg differ diff --git a/Images/Play Normal.png b/Images/Play Normal.png new file mode 100644 index 0000000..616f42b Binary files /dev/null and b/Images/Play Normal.png differ diff --git a/Images/Save-icon.png b/Images/Save-icon.png new file mode 100755 index 0000000..b4e12d2 Binary files /dev/null and b/Images/Save-icon.png differ diff --git a/Images/Slider_Green.png b/Images/Slider_Green.png new file mode 100644 index 0000000..147bf7c Binary files /dev/null and b/Images/Slider_Green.png differ diff --git a/Images/Slider_Red.png b/Images/Slider_Red.png new file mode 100644 index 0000000..8902069 Binary files /dev/null and b/Images/Slider_Red.png differ diff --git a/Images/green-led-off-md.png b/Images/green-led-off-md.png new file mode 100644 index 0000000..1b01178 Binary files /dev/null and b/Images/green-led-off-md.png differ diff --git a/Images/green-led-on-md.png b/Images/green-led-on-md.png new file mode 100755 index 0000000..fa2b488 Binary files /dev/null and b/Images/green-led-on-md.png differ diff --git a/Images/log.png b/Images/log.png new file mode 100644 index 0000000..d3ba041 Binary files /dev/null and b/Images/log.png differ diff --git a/Images/open-file-icon.png b/Images/open-file-icon.png new file mode 100755 index 0000000..6b7fae2 Binary files /dev/null and b/Images/open-file-icon.png differ diff --git a/Images/pushbutton-green.png b/Images/pushbutton-green.png new file mode 100644 index 0000000..49666d8 Binary files /dev/null and b/Images/pushbutton-green.png differ diff --git a/Images/red-led-off-md.png b/Images/red-led-off-md.png new file mode 100755 index 0000000..187f46f Binary files /dev/null and b/Images/red-led-off-md.png differ diff --git a/Images/red-led-on-md.png b/Images/red-led-on-md.png new file mode 100755 index 0000000..f0bc2f5 Binary files /dev/null and b/Images/red-led-on-md.png differ diff --git a/Images/tools.png b/Images/tools.png new file mode 100644 index 0000000..69ada22 Binary files /dev/null and b/Images/tools.png differ diff --git a/LicTemplate.txt b/LicTemplate.txt new file mode 100644 index 0000000..a0338b2 --- /dev/null +++ b/LicTemplate.txt @@ -0,0 +1,26 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6805478 --- /dev/null +++ b/Makefile @@ -0,0 +1,1496 @@ +############################################################################# +# Makefile for building: ZT +# Generated by qmake (2.01a) (Qt 4.8.3) on: Tue Mar 25 07:58:00 2014 +# Project: ZT.pro +# Template: app +# Command: /usr/local/Trolltech/Qt-4.8.3/bin/qmake -spec /usr/local/Trolltech/Qt-4.8.3/mkspecs/linux-g++ CONFIG+=release -o Makefile ZT.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +DEFINES = -D_TTY_POSIX_ -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED +CFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES) +CXXFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES) +INCPATH = -I/usr/local/Trolltech/Qt-4.8.3/mkspecs/linux-g++ -I. -I/usr/local/Trolltech/Qt-4.8.3/include/QtCore -I/usr/local/Trolltech/Qt-4.8.3/include/QtGui -I/usr/local/Trolltech/Qt-4.8.3/include -I. -ISeaMaxLinux -Isources/ExtModules -Isources -Isources/Stations -Isources/PCIIO -Isources/GuiElements -Isources/SerialPort -Isources/Simulator -Isources/QCustomPlot -I. +LINK = g++ +LFLAGS = -Wl,-O1 -Wl,-rpath,/usr/local/Trolltech/Qt-4.8.3/lib +LIBS = $(SUBLIBS) -L/usr/local/Trolltech/Qt-4.8.3/lib /usr/local/lib/libseamax.a -lcomedi /home/zonetest/DevZT/ZT/sources/SerialPort/libqextserialport.a -lQtGui -L/usr/local/Trolltech/Qt-4.8.3/lib -L/usr/X11R6/lib -lQtCore -lpthread +AR = ar cqs +RANLIB = +QMAKE = /usr/local/Trolltech/Qt-4.8.3/bin/qmake +TAR = tar -cf +COMPRESS = gzip -9f +COPY = cp -f +SED = sed +COPY_FILE = $(COPY) +COPY_DIR = $(COPY) -r +STRIP = strip +INSTALL_FILE = install -m 644 -p +INSTALL_DIR = $(COPY_DIR) +INSTALL_PROGRAM = install -m 755 -p +DEL_FILE = rm -f +SYMLINK = ln -f -s +DEL_DIR = rmdir +MOVE = mv -f +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p + +####### Output directory + +OBJECTS_DIR = ./ + +####### Files + +SOURCES = sources/main.cpp \ + sources/MainPanel.cpp \ + sources/Station.cpp \ + sources/ZTconfigmgr.cpp \ + sources/Zonetest.cpp \ + sources/EngLog.cpp \ + sources/GuiElements/GuiPage.cpp \ + sources/GuiElements/WelcomePage.cpp \ + sources/GuiElements/SimpleTextBoxWidget.cpp \ + sources/Stations/Angrignon.cpp \ + sources/Stations/HonoreBeaugrand.cpp \ + sources/Stations/HenriBourassa.cpp \ + sources/Stations/CoteVertu.cpp \ + sources/Stations/BerriUQAM.cpp \ + sources/Stations/Longueuil.cpp \ + sources/Stations/SaintMichel.cpp \ + sources/Stations/Snowdon.cpp \ + sources/Stations/Montmorency.cpp \ + sources/GuiElements/ZTPage.cpp \ + sources/LazerProbe.cpp \ + sources/LazerProbesMgr.cpp \ + sources/ZTLog.cpp \ + sources/GuiElements/PushButton.cpp \ + sources/ZTStateMachine.cpp \ + sources/ZTData.cpp \ + sources/Simulator/ZTSimulator.cpp \ + sources/GuiElements/CDVItem.cpp \ + sources/IOManager.cpp \ + sources/IOModule.cpp \ + sources/InputModule.cpp \ + sources/OutputModule.cpp \ + sources/MixedModule.cpp \ + sources/Simulator/SimulatorIOManager.cpp \ + sources/Simulator/SimulatorInputModule.cpp \ + sources/Simulator/SImulatorOutputModule.cpp \ + sources/Simulator/SimulatorMixedModule.cpp \ + sources/CDV.cpp \ + sources/AbstractLazerProbeMgr.cpp \ + sources/AbstractLazerProbe.cpp \ + sources/Simulator/SimulatorLazerProbe.cpp \ + sources/Simulator/SimulatorLazerProbesMgr.cpp \ + sources/PCIIOMgr.cpp \ + sources/Simulator/SimulatorPCIIO.cpp \ + sources/GuiElements/ToggleTextButtonWidget.cpp \ + sources/GuiElements/TextButtonWidget.cpp \ + sources/ZT1AnalysisThread.cpp \ + sources/GuiElements/StatusBar.cpp \ + sources/GuiElements/ZT1EquipmentWidget.cpp \ + sources/GuiElements/ZT1StatsZone.cpp \ + sources/Simulator/SimulationScenario.cpp \ + sources/GuiElements/OptionsPage.cpp \ + sources/GuiElements/FunctionSelectionPage.cpp \ + sources/GuiElements/ToggleButtonWidget.cpp \ + sources/GuiElements/EventsBar.cpp \ + sources/GuiElements/EventItem.cpp \ + sources/Event.cpp \ + sources/EventMgr.cpp \ + sources/TrainLogFileMgr.cpp \ + sources/LogMgr.cpp \ + sources/GuiElements/LogsListPage.cpp \ + sources/GuiElements/LogViewPage.cpp \ + sources/GuiElements/GraphItem.cpp \ + sources/GuiElements/GraphCursorWidget.cpp \ + sources/GuiElements/GraphRulerWidget.cpp \ + sources/GuiElements/AnalogGraphItem.cpp \ + sources/ZTSettings.cpp \ + sources/GuiElements/ZT2EquipmentWidget.cpp \ + sources/ZT2AnalysisThread.cpp \ + sources/GuiElements/ZT2StatsZone.cpp \ + sources/TKGenerator.cpp \ + sources/GuiElements/LedWidget.cpp \ + sources/GuiElements/RankRulerWidget.cpp \ + sources/GuiElements/EngineeringPage.cpp \ + sources/GuiElements/PasswordPrompt.cpp \ + sources/GuiElements/EventsRulerWidget.cpp \ + sources/USBDriveInterface.cpp \ + sources/GuiElements/MaintenancePage.cpp \ + sources/Simulator/SimulatorThread.cpp \ + sources/GuiElements/GeneralSettingsPage.cpp \ + sources/GuiElements/ONOFFStatusWidget.cpp \ + sources/GuiElements/ZTLogViewerPage.cpp \ + sources/SwitchCDV.cpp \ + sources/GuiElements/SwitchCDVItem.cpp \ + sources/RamMonitor.cpp \ + sources/ExtModules/Externaliomodule.cpp \ + sources/ExtModules/Seaio430driver.cpp \ + sources/ExtModules/Seaio440driver.cpp \ + sources/ExtModules/Seaio470driver.cpp \ + sources/ExtModules/Seaiolibinterface.cpp \ + sources/PCIIO/Comedilibinterface.cpp \ + sources/ExtModules/ExternalIOMgr.cpp moc_MainPanel.cpp \ + moc_Zonetest.cpp \ + moc_Guipage.cpp \ + moc_WelcomePage.cpp \ + moc_SimpleTextBoxWidget.cpp \ + moc_ZTPage.cpp \ + moc_LazerProbe.cpp \ + moc_LazerProbesMgr.cpp \ + moc_PushButton.cpp \ + moc_ZTStateMachine.cpp \ + moc_ZTSimulator.cpp \ + moc_CDVItem.cpp \ + moc_SimulatorLazerProbe.cpp \ + moc_ToggleTextButtonWidget.cpp \ + moc_TextButtonWidget.cpp \ + moc_ZT1AnalysisThread.cpp \ + moc_StatusBar.cpp \ + moc_ZT1EquipmentWidget.cpp \ + moc_ZT1StatsZone.cpp \ + moc_SimulationScenario.cpp \ + moc_OptionsPage.cpp \ + moc_FunctionSelectionPage.cpp \ + moc_ToggleButtonWidget.cpp \ + moc_EventsBar.cpp \ + moc_EventItem.cpp \ + moc_LogsListPage.cpp \ + moc_LogViewPage.cpp \ + moc_GraphItem.cpp \ + moc_GraphCursorWidget.cpp \ + moc_GraphRulerWidget.cpp \ + moc_AnalogGraphItem.cpp \ + moc_ZT2EquipmentWidget.cpp \ + moc_ZT2AnalysisThread.cpp \ + moc_ZT2StatsZone.cpp \ + moc_TKGenerator.cpp \ + moc_LedWidget.cpp \ + moc_RankRulerWidget.cpp \ + moc_EngineeringPage.cpp \ + moc_PasswordPrompt.cpp \ + moc_EventsRulerWidget.cpp \ + moc_USBDriveInterface.cpp \ + moc_MaintenancePage.cpp \ + moc_SimulatorThread.cpp \ + moc_GeneralSettingsPage.cpp \ + moc_ONOFFStatusWidget.cpp \ + moc_ZTLogViewerPage.cpp \ + moc_SwitchCDVItem.cpp \ + moc_RamMonitor.cpp +OBJECTS = main.o \ + MainPanel.o \ + Station.o \ + ZTconfigmgr.o \ + Zonetest.o \ + EngLog.o \ + GuiPage.o \ + WelcomePage.o \ + SimpleTextBoxWidget.o \ + Angrignon.o \ + HonoreBeaugrand.o \ + HenriBourassa.o \ + CoteVertu.o \ + BerriUQAM.o \ + Longueuil.o \ + SaintMichel.o \ + Snowdon.o \ + Montmorency.o \ + ZTPage.o \ + LazerProbe.o \ + LazerProbesMgr.o \ + ZTLog.o \ + PushButton.o \ + ZTStateMachine.o \ + ZTData.o \ + ZTSimulator.o \ + CDVItem.o \ + IOManager.o \ + IOModule.o \ + InputModule.o \ + OutputModule.o \ + MixedModule.o \ + SimulatorIOManager.o \ + SimulatorInputModule.o \ + SImulatorOutputModule.o \ + SimulatorMixedModule.o \ + CDV.o \ + AbstractLazerProbeMgr.o \ + AbstractLazerProbe.o \ + SimulatorLazerProbe.o \ + SimulatorLazerProbesMgr.o \ + PCIIOMgr.o \ + SimulatorPCIIO.o \ + ToggleTextButtonWidget.o \ + TextButtonWidget.o \ + ZT1AnalysisThread.o \ + StatusBar.o \ + ZT1EquipmentWidget.o \ + ZT1StatsZone.o \ + SimulationScenario.o \ + OptionsPage.o \ + FunctionSelectionPage.o \ + ToggleButtonWidget.o \ + EventsBar.o \ + EventItem.o \ + Event.o \ + EventMgr.o \ + TrainLogFileMgr.o \ + LogMgr.o \ + LogsListPage.o \ + LogViewPage.o \ + GraphItem.o \ + GraphCursorWidget.o \ + GraphRulerWidget.o \ + AnalogGraphItem.o \ + ZTSettings.o \ + ZT2EquipmentWidget.o \ + ZT2AnalysisThread.o \ + ZT2StatsZone.o \ + TKGenerator.o \ + LedWidget.o \ + RankRulerWidget.o \ + EngineeringPage.o \ + PasswordPrompt.o \ + EventsRulerWidget.o \ + USBDriveInterface.o \ + MaintenancePage.o \ + SimulatorThread.o \ + GeneralSettingsPage.o \ + ONOFFStatusWidget.o \ + ZTLogViewerPage.o \ + SwitchCDV.o \ + SwitchCDVItem.o \ + RamMonitor.o \ + Externaliomodule.o \ + Seaio430driver.o \ + Seaio440driver.o \ + Seaio470driver.o \ + Seaiolibinterface.o \ + Comedilibinterface.o \ + ExternalIOMgr.o \ + moc_MainPanel.o \ + moc_Zonetest.o \ + moc_Guipage.o \ + moc_WelcomePage.o \ + moc_SimpleTextBoxWidget.o \ + moc_ZTPage.o \ + moc_LazerProbe.o \ + moc_LazerProbesMgr.o \ + moc_PushButton.o \ + moc_ZTStateMachine.o \ + moc_ZTSimulator.o \ + moc_CDVItem.o \ + moc_SimulatorLazerProbe.o \ + moc_ToggleTextButtonWidget.o \ + moc_TextButtonWidget.o \ + moc_ZT1AnalysisThread.o \ + moc_StatusBar.o \ + moc_ZT1EquipmentWidget.o \ + moc_ZT1StatsZone.o \ + moc_SimulationScenario.o \ + moc_OptionsPage.o \ + moc_FunctionSelectionPage.o \ + moc_ToggleButtonWidget.o \ + moc_EventsBar.o \ + moc_EventItem.o \ + moc_LogsListPage.o \ + moc_LogViewPage.o \ + moc_GraphItem.o \ + moc_GraphCursorWidget.o \ + moc_GraphRulerWidget.o \ + moc_AnalogGraphItem.o \ + moc_ZT2EquipmentWidget.o \ + moc_ZT2AnalysisThread.o \ + moc_ZT2StatsZone.o \ + moc_TKGenerator.o \ + moc_LedWidget.o \ + moc_RankRulerWidget.o \ + moc_EngineeringPage.o \ + moc_PasswordPrompt.o \ + moc_EventsRulerWidget.o \ + moc_USBDriveInterface.o \ + moc_MaintenancePage.o \ + moc_SimulatorThread.o \ + moc_GeneralSettingsPage.o \ + moc_ONOFFStatusWidget.o \ + moc_ZTLogViewerPage.o \ + moc_SwitchCDVItem.o \ + moc_RamMonitor.o +DIST = /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/unix.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/linux.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/gcc-base.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/gcc-base-unix.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/g++-base.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/g++-unix.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/qconfig.pri \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/modules/qt_webkit_version.pri \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt_functions.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt_config.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/exclusive_builds.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/default_pre.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/release.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/default_post.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/unix/gdb_dwarf_index.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/warn_on.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/unix/thread.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/moc.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/resources.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/uic.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/yacc.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/lex.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/include_source_dir.prf \ + ZT.pro +QMAKE_TARGET = ZT +DESTDIR = +TARGET = ZT + +first: all +####### Implicit rules + +.SUFFIXES: .o .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" + +####### Build rules + +all: Makefile $(TARGET) + +$(TARGET): $(OBJECTS) + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) + +Makefile: ZT.pro /usr/local/Trolltech/Qt-4.8.3/mkspecs/linux-g++/qmake.conf /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/unix.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/linux.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/gcc-base.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/gcc-base-unix.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/g++-base.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/common/g++-unix.conf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/qconfig.pri \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/modules/qt_webkit_version.pri \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt_functions.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt_config.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/exclusive_builds.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/default_pre.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/release.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/default_post.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/unix/gdb_dwarf_index.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/warn_on.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/unix/thread.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/moc.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/resources.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/uic.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/yacc.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/lex.prf \ + /usr/local/Trolltech/Qt-4.8.3/mkspecs/features/include_source_dir.prf \ + /usr/local/Trolltech/Qt-4.8.3/lib/libQtGui.prl \ + /usr/local/Trolltech/Qt-4.8.3/lib/libQtCore.prl + $(QMAKE) -spec /usr/local/Trolltech/Qt-4.8.3/mkspecs/linux-g++ CONFIG+=release -o Makefile ZT.pro +/usr/local/Trolltech/Qt-4.8.3/mkspecs/common/unix.conf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/common/linux.conf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/common/gcc-base.conf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/common/gcc-base-unix.conf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/common/g++-base.conf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/common/g++-unix.conf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/qconfig.pri: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/modules/qt_webkit_version.pri: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt_functions.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt_config.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/exclusive_builds.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/default_pre.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/release.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/default_post.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/unix/gdb_dwarf_index.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/warn_on.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/qt.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/unix/thread.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/moc.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/resources.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/uic.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/yacc.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/lex.prf: +/usr/local/Trolltech/Qt-4.8.3/mkspecs/features/include_source_dir.prf: +/usr/local/Trolltech/Qt-4.8.3/lib/libQtGui.prl: +/usr/local/Trolltech/Qt-4.8.3/lib/libQtCore.prl: +qmake: FORCE + @$(QMAKE) -spec /usr/local/Trolltech/Qt-4.8.3/mkspecs/linux-g++ CONFIG+=release -o Makefile ZT.pro + +dist: + @$(CHK_DIR_EXISTS) .tmp/ZT1.0.0 || $(MKDIR) .tmp/ZT1.0.0 + $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/ZT1.0.0/ && $(COPY_FILE) --parents sources/MainPanel.h sources/GlobalDefine.h sources/Station.h sources/ExtModules/Externaliomodule.h sources/ExtModules/Seaio430driver.h sources/ExtModules/Seaio440driver.h sources/ExtModules/Seaio470driver.h sources/ZTconfigmgr.h sources/Zonetest.h sources/ExtModules/Seaiolibinterface.h sources/PCIIO/Comedilibinterface.h sources/PCIIO/PCI1756Definitions.h sources/EngLog.h sources/GuiElements/Guipage.h sources/GuiElements/WelcomePage.h sources/GuiElements/SimpleTextBoxWidget.h sources/Stations/Angrignon.h sources/Stations/HonoreBeaugrand.h sources/Stations/HenriBourassa.h sources/Stations/CoteVertu.h sources/Stations/BerriUQAM.h sources/Stations/Longueuil.h sources/Stations/SaintMichel.h sources/Stations/Snowdon.h sources/Stations/Montmorency.h sources/GuiElements/ZTPage.h sources/LazerProbe.h sources/LazerProbesMgr.h sources/ZTLog.h sources/GuiElements/PushButton.h sources/ZTStateMachine.h sources/ZTData.h sources/Simulator/ZTSimulator.h sources/GuiElements/CDVItem.h sources/ExtModules/ExternalIOMgr.h sources/IOManager.h sources/IOModule.h sources/InputModule.h sources/OutputModule.h sources/MixedModule.h sources/Simulator/SimulatorIOManager.h sources/Simulator/SimulatorInputModule.h sources/Simulator/SImulatorOutputModule.h sources/Simulator/SimulatorMixedModule.h sources/CDV.h sources/AbstractLazerProbeMgr.h sources/AbstractLazerProbe.h sources/Simulator/SimulatorLazerProbe.h sources/Simulator/SimulatorLazerProbesMgr.h sources/PCIIOMgr.h sources/Simulator/SimulatorPCIIO.h sources/GuiElements/ToggleTextButtonWidget.h sources/GuiElements/TextButtonWidget.h sources/ZT1AnalysisThread.h sources/GuiElements/StatusBar.h sources/GuiElements/ZT1EquipmentWidget.h sources/GuiElements/ZT1StatsZone.h sources/Simulator/SimulationScenario.h sources/GuiElements/OptionsPage.h sources/GuiElements/FunctionSelectionPage.h sources/GuiElements/ToggleButtonWidget.h sources/GuiElements/EventsBar.h sources/GuiElements/EventItem.h sources/Event.h sources/EventMgr.h sources/TrainLogFileMgr.h sources/LogMgr.h sources/GuiElements/LogsListPage.h sources/GuiElements/LogViewPage.h sources/GuiElements/GraphItem.h sources/GuiElements/GraphCursorWidget.h sources/GuiElements/GraphRulerWidget.h sources/GuiElements/AnalogGraphItem.h sources/ZTSettings.h sources/GuiElements/ZT2EquipmentWidget.h sources/ZT2AnalysisThread.h sources/GuiElements/ZT2StatsZone.h sources/TKGenerator.h sources/GuiElements/LedWidget.h sources/GuiElements/RankRulerWidget.h sources/GuiElements/EngineeringPage.h sources/GuiElements/PasswordPrompt.h sources/GuiElements/EventsRulerWidget.h sources/USBDriveInterface.h sources/GuiElements/MaintenancePage.h sources/Simulator/SimulatorThread.h sources/GuiElements/GeneralSettingsPage.h sources/ZTVersion.h sources/GuiElements/ONOFFStatusWidget.h sources/GuiElements/ZTLogViewerPage.h sources/SwitchCDV.h sources/GuiElements/SwitchCDVItem.h sources/RamMonitor.h .tmp/ZT1.0.0/ && $(COPY_FILE) --parents sources/main.cpp sources/MainPanel.cpp sources/Station.cpp sources/ZTconfigmgr.cpp sources/Zonetest.cpp sources/EngLog.cpp sources/GuiElements/GuiPage.cpp sources/GuiElements/WelcomePage.cpp sources/GuiElements/SimpleTextBoxWidget.cpp sources/Stations/Angrignon.cpp sources/Stations/HonoreBeaugrand.cpp sources/Stations/HenriBourassa.cpp sources/Stations/CoteVertu.cpp sources/Stations/BerriUQAM.cpp sources/Stations/Longueuil.cpp sources/Stations/SaintMichel.cpp sources/Stations/Snowdon.cpp sources/Stations/Montmorency.cpp sources/GuiElements/ZTPage.cpp sources/LazerProbe.cpp sources/LazerProbesMgr.cpp sources/ZTLog.cpp sources/GuiElements/PushButton.cpp sources/ZTStateMachine.cpp sources/ZTData.cpp sources/Simulator/ZTSimulator.cpp sources/GuiElements/CDVItem.cpp sources/IOManager.cpp sources/IOModule.cpp sources/InputModule.cpp sources/OutputModule.cpp sources/MixedModule.cpp sources/Simulator/SimulatorIOManager.cpp sources/Simulator/SimulatorInputModule.cpp sources/Simulator/SImulatorOutputModule.cpp sources/Simulator/SimulatorMixedModule.cpp sources/CDV.cpp sources/AbstractLazerProbeMgr.cpp sources/AbstractLazerProbe.cpp sources/Simulator/SimulatorLazerProbe.cpp sources/Simulator/SimulatorLazerProbesMgr.cpp sources/PCIIOMgr.cpp sources/Simulator/SimulatorPCIIO.cpp sources/GuiElements/ToggleTextButtonWidget.cpp sources/GuiElements/TextButtonWidget.cpp sources/ZT1AnalysisThread.cpp sources/GuiElements/StatusBar.cpp sources/GuiElements/ZT1EquipmentWidget.cpp sources/GuiElements/ZT1StatsZone.cpp sources/Simulator/SimulationScenario.cpp sources/GuiElements/OptionsPage.cpp sources/GuiElements/FunctionSelectionPage.cpp sources/GuiElements/ToggleButtonWidget.cpp sources/GuiElements/EventsBar.cpp sources/GuiElements/EventItem.cpp sources/Event.cpp sources/EventMgr.cpp sources/TrainLogFileMgr.cpp sources/LogMgr.cpp sources/GuiElements/LogsListPage.cpp sources/GuiElements/LogViewPage.cpp sources/GuiElements/GraphItem.cpp sources/GuiElements/GraphCursorWidget.cpp sources/GuiElements/GraphRulerWidget.cpp sources/GuiElements/AnalogGraphItem.cpp sources/ZTSettings.cpp sources/GuiElements/ZT2EquipmentWidget.cpp sources/ZT2AnalysisThread.cpp sources/GuiElements/ZT2StatsZone.cpp sources/TKGenerator.cpp sources/GuiElements/LedWidget.cpp sources/GuiElements/RankRulerWidget.cpp sources/GuiElements/EngineeringPage.cpp sources/GuiElements/PasswordPrompt.cpp sources/GuiElements/EventsRulerWidget.cpp sources/USBDriveInterface.cpp sources/GuiElements/MaintenancePage.cpp sources/Simulator/SimulatorThread.cpp sources/GuiElements/GeneralSettingsPage.cpp sources/GuiElements/ONOFFStatusWidget.cpp sources/GuiElements/ZTLogViewerPage.cpp sources/SwitchCDV.cpp sources/GuiElements/SwitchCDVItem.cpp sources/RamMonitor.cpp sources/ExtModules/Externaliomodule.cpp sources/ExtModules/Seaio430driver.cpp sources/ExtModules/Seaio440driver.cpp sources/ExtModules/Seaio470driver.cpp sources/ExtModules/Seaiolibinterface.cpp sources/PCIIO/Comedilibinterface.cpp sources/ExtModules/ExternalIOMgr.cpp .tmp/ZT1.0.0/ && (cd `dirname .tmp/ZT1.0.0` && $(TAR) ZT1.0.0.tar ZT1.0.0 && $(COMPRESS) ZT1.0.0.tar) && $(MOVE) `dirname .tmp/ZT1.0.0`/ZT1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/ZT1.0.0 + + +clean:compiler_clean + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +####### Sub-libraries + +distclean: clean + -$(DEL_FILE) $(TARGET) + -$(DEL_FILE) Makefile + + +check: first + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +compiler_moc_header_make_all: moc_MainPanel.cpp moc_Zonetest.cpp moc_Guipage.cpp moc_WelcomePage.cpp moc_SimpleTextBoxWidget.cpp moc_ZTPage.cpp moc_LazerProbe.cpp moc_LazerProbesMgr.cpp moc_PushButton.cpp moc_ZTStateMachine.cpp moc_ZTSimulator.cpp moc_CDVItem.cpp moc_SimulatorLazerProbe.cpp moc_ToggleTextButtonWidget.cpp moc_TextButtonWidget.cpp moc_ZT1AnalysisThread.cpp moc_StatusBar.cpp moc_ZT1EquipmentWidget.cpp moc_ZT1StatsZone.cpp moc_SimulationScenario.cpp moc_OptionsPage.cpp moc_FunctionSelectionPage.cpp moc_ToggleButtonWidget.cpp moc_EventsBar.cpp moc_EventItem.cpp moc_LogsListPage.cpp moc_LogViewPage.cpp moc_GraphItem.cpp moc_GraphCursorWidget.cpp moc_GraphRulerWidget.cpp moc_AnalogGraphItem.cpp moc_ZT2EquipmentWidget.cpp moc_ZT2AnalysisThread.cpp moc_ZT2StatsZone.cpp moc_TKGenerator.cpp moc_LedWidget.cpp moc_RankRulerWidget.cpp moc_EngineeringPage.cpp moc_PasswordPrompt.cpp moc_EventsRulerWidget.cpp moc_USBDriveInterface.cpp moc_MaintenancePage.cpp moc_SimulatorThread.cpp moc_GeneralSettingsPage.cpp moc_ONOFFStatusWidget.cpp moc_ZTLogViewerPage.cpp moc_SwitchCDVItem.cpp moc_RamMonitor.cpp +compiler_moc_header_clean: + -$(DEL_FILE) moc_MainPanel.cpp moc_Zonetest.cpp moc_Guipage.cpp moc_WelcomePage.cpp moc_SimpleTextBoxWidget.cpp moc_ZTPage.cpp moc_LazerProbe.cpp moc_LazerProbesMgr.cpp moc_PushButton.cpp moc_ZTStateMachine.cpp moc_ZTSimulator.cpp moc_CDVItem.cpp moc_SimulatorLazerProbe.cpp moc_ToggleTextButtonWidget.cpp moc_TextButtonWidget.cpp moc_ZT1AnalysisThread.cpp moc_StatusBar.cpp moc_ZT1EquipmentWidget.cpp moc_ZT1StatsZone.cpp moc_SimulationScenario.cpp moc_OptionsPage.cpp moc_FunctionSelectionPage.cpp moc_ToggleButtonWidget.cpp moc_EventsBar.cpp moc_EventItem.cpp moc_LogsListPage.cpp moc_LogViewPage.cpp moc_GraphItem.cpp moc_GraphCursorWidget.cpp moc_GraphRulerWidget.cpp moc_AnalogGraphItem.cpp moc_ZT2EquipmentWidget.cpp moc_ZT2AnalysisThread.cpp moc_ZT2StatsZone.cpp moc_TKGenerator.cpp moc_LedWidget.cpp moc_RankRulerWidget.cpp moc_EngineeringPage.cpp moc_PasswordPrompt.cpp moc_EventsRulerWidget.cpp moc_USBDriveInterface.cpp moc_MaintenancePage.cpp moc_SimulatorThread.cpp moc_GeneralSettingsPage.cpp moc_ONOFFStatusWidget.cpp moc_ZTLogViewerPage.cpp moc_SwitchCDVItem.cpp moc_RamMonitor.cpp +moc_MainPanel.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/MainPanel.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/MainPanel.h -o moc_MainPanel.cpp + +moc_Zonetest.cpp: sources/MainPanel.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/ZTStateMachine.h \ + sources/PCIIOMgr.h \ + sources/ZT1AnalysisThread.h \ + sources/ZT2AnalysisThread.h \ + sources/TKGenerator.h \ + sources/LogMgr.h \ + sources/EventMgr.h \ + sources/Event.h \ + sources/ZTSettings.h \ + sources/USBDriveInterface.h \ + sources/Zonetest.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/Zonetest.h -o moc_Zonetest.cpp + +moc_Guipage.cpp: sources/GuiElements/Guipage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/Guipage.h -o moc_Guipage.cpp + +moc_WelcomePage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/SimpleTextBoxWidget.h \ + sources/GuiElements/WelcomePage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/WelcomePage.h -o moc_WelcomePage.cpp + +moc_SimpleTextBoxWidget.cpp: sources/GuiElements/SimpleTextBoxWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/SimpleTextBoxWidget.h -o moc_SimpleTextBoxWidget.cpp + +moc_ZTPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/CDVItem.h \ + sources/GuiElements/StatusBar.h \ + sources/GuiElements/ZT1EquipmentWidget.h \ + sources/GuiElements/ZT1StatsZone.h \ + sources/GuiElements/EventsBar.h \ + sources/GuiElements/EventItem.h \ + sources/GuiElements/ZT2EquipmentWidget.h \ + sources/GuiElements/ZT2StatsZone.h \ + sources/GuiElements/PasswordPrompt.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/ZTPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ZTPage.h -o moc_ZTPage.cpp + +moc_LazerProbe.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/AbstractLazerProbe.h \ + sources/LazerProbe.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/LazerProbe.h -o moc_LazerProbe.cpp + +moc_LazerProbesMgr.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/LazerProbesMgr.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/LazerProbesMgr.h -o moc_LazerProbesMgr.cpp + +moc_PushButton.cpp: sources/GuiElements/PushButton.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/PushButton.h -o moc_PushButton.cpp + +moc_ZTStateMachine.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZTData.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/PCIIOMgr.h \ + sources/ZT1AnalysisThread.h \ + sources/ZT2AnalysisThread.h \ + sources/TKGenerator.h \ + sources/LogMgr.h \ + sources/ZTStateMachine.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/ZTStateMachine.h -o moc_ZTStateMachine.cpp + +moc_ZTSimulator.cpp: sources/Simulator/SimulatorIOManager.h \ + sources/Simulator/SimulatorInputModule.h \ + sources/Simulator/SImulatorOutputModule.h \ + sources/Simulator/SimulatorMixedModule.h \ + sources/Simulator/SimulatorLazerProbesMgr.h \ + sources/Simulator/SimulatorLazerProbe.h \ + sources/Simulator/SimulatorPCIIO.h \ + sources/Simulator/SimulationScenario.h \ + sources/Simulator/SimulatorThread.h \ + sources/Simulator/ZTSimulator.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/Simulator/ZTSimulator.h -o moc_ZTSimulator.cpp + +moc_CDVItem.cpp: sources/GuiElements/CDVItem.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/CDVItem.h -o moc_CDVItem.cpp + +moc_SimulatorLazerProbe.cpp: sources/Simulator/SimulatorLazerProbe.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/Simulator/SimulatorLazerProbe.h -o moc_SimulatorLazerProbe.cpp + +moc_ToggleTextButtonWidget.cpp: sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/ToggleTextButtonWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ToggleTextButtonWidget.h -o moc_ToggleTextButtonWidget.cpp + +moc_TextButtonWidget.cpp: sources/GuiElements/TextButtonWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/TextButtonWidget.h -o moc_TextButtonWidget.cpp + +moc_ZT1AnalysisThread.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/ZT1AnalysisThread.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/ZT1AnalysisThread.h -o moc_ZT1AnalysisThread.cpp + +moc_StatusBar.cpp: sources/GuiElements/StatusBar.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/StatusBar.h -o moc_StatusBar.cpp + +moc_ZT1EquipmentWidget.cpp: sources/GuiElements/ZT1EquipmentWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ZT1EquipmentWidget.h -o moc_ZT1EquipmentWidget.cpp + +moc_ZT1StatsZone.cpp: sources/GuiElements/ZT1StatsZone.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ZT1StatsZone.h -o moc_ZT1StatsZone.cpp + +moc_SimulationScenario.cpp: sources/Simulator/SimulationScenario.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/Simulator/SimulationScenario.h -o moc_SimulationScenario.cpp + +moc_OptionsPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/OptionsPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/OptionsPage.h -o moc_OptionsPage.cpp + +moc_FunctionSelectionPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/ToggleButtonWidget.h \ + sources/GuiElements/FunctionSelectionPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/FunctionSelectionPage.h -o moc_FunctionSelectionPage.cpp + +moc_ToggleButtonWidget.cpp: sources/GuiElements/ToggleButtonWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ToggleButtonWidget.h -o moc_ToggleButtonWidget.cpp + +moc_EventsBar.cpp: sources/GuiElements/EventItem.h \ + sources/GuiElements/EventsBar.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/EventsBar.h -o moc_EventsBar.cpp + +moc_EventItem.cpp: sources/GuiElements/EventItem.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/EventItem.h -o moc_EventItem.cpp + +moc_LogsListPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/LogsListPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/LogsListPage.h -o moc_LogsListPage.cpp + +moc_LogViewPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/GraphItem.h \ + sources/GuiElements/GraphCursorWidget.h \ + sources/GuiElements/GraphRulerWidget.h \ + sources/GuiElements/AnalogGraphItem.h \ + sources/GuiElements/RankRulerWidget.h \ + sources/GuiElements/EventsRulerWidget.h \ + sources/GuiElements/LogViewPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/LogViewPage.h -o moc_LogViewPage.cpp + +moc_GraphItem.cpp: sources/GuiElements/GraphItem.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/GraphItem.h -o moc_GraphItem.cpp + +moc_GraphCursorWidget.cpp: sources/GuiElements/GraphCursorWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/GraphCursorWidget.h -o moc_GraphCursorWidget.cpp + +moc_GraphRulerWidget.cpp: sources/GuiElements/GraphRulerWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/GraphRulerWidget.h -o moc_GraphRulerWidget.cpp + +moc_AnalogGraphItem.cpp: sources/GuiElements/AnalogGraphItem.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/AnalogGraphItem.h -o moc_AnalogGraphItem.cpp + +moc_ZT2EquipmentWidget.cpp: sources/GuiElements/ZT2EquipmentWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ZT2EquipmentWidget.h -o moc_ZT2EquipmentWidget.cpp + +moc_ZT2AnalysisThread.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/ZT2AnalysisThread.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/ZT2AnalysisThread.h -o moc_ZT2AnalysisThread.cpp + +moc_ZT2StatsZone.cpp: sources/GuiElements/ZT2StatsZone.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ZT2StatsZone.h -o moc_ZT2StatsZone.cpp + +moc_TKGenerator.cpp: sources/Station.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/TKGenerator.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/TKGenerator.h -o moc_TKGenerator.cpp + +moc_LedWidget.cpp: sources/GuiElements/LedWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/LedWidget.h -o moc_LedWidget.cpp + +moc_RankRulerWidget.cpp: sources/GuiElements/RankRulerWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/RankRulerWidget.h -o moc_RankRulerWidget.cpp + +moc_EngineeringPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/PasswordPrompt.h \ + sources/GuiElements/ToggleButtonWidget.h \ + sources/GuiElements/EngineeringPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/EngineeringPage.h -o moc_EngineeringPage.cpp + +moc_PasswordPrompt.cpp: sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/PasswordPrompt.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/PasswordPrompt.h -o moc_PasswordPrompt.cpp + +moc_EventsRulerWidget.cpp: sources/GuiElements/EventsRulerWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/EventsRulerWidget.h -o moc_EventsRulerWidget.cpp + +moc_USBDriveInterface.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/USBDriveInterface.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/USBDriveInterface.h -o moc_USBDriveInterface.cpp + +moc_MaintenancePage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/ToggleButtonWidget.h \ + sources/GuiElements/ONOFFStatusWidget.h \ + sources/GuiElements/MaintenancePage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/MaintenancePage.h -o moc_MaintenancePage.cpp + +moc_SimulatorThread.cpp: sources/Simulator/SimulatorInputModule.h \ + sources/Simulator/SImulatorOutputModule.h \ + sources/Simulator/SimulatorPCIIO.h \ + sources/Simulator/SimulatorLazerProbe.h \ + sources/Simulator/SimulatorThread.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/Simulator/SimulatorThread.h -o moc_SimulatorThread.cpp + +moc_GeneralSettingsPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/GeneralSettingsPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/GeneralSettingsPage.h -o moc_GeneralSettingsPage.cpp + +moc_ONOFFStatusWidget.cpp: sources/GuiElements/ONOFFStatusWidget.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ONOFFStatusWidget.h -o moc_ONOFFStatusWidget.cpp + +moc_ZTLogViewerPage.cpp: sources/GuiElements/Guipage.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/ZTLogViewerPage.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/ZTLogViewerPage.h -o moc_ZTLogViewerPage.cpp + +moc_SwitchCDVItem.cpp: sources/GuiElements/CDVItem.h \ + sources/GuiElements/SwitchCDVItem.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/GuiElements/SwitchCDVItem.h -o moc_SwitchCDVItem.cpp + +moc_RamMonitor.cpp: sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/RamMonitor.h + /usr/local/Trolltech/Qt-4.8.3/bin/moc $(DEFINES) $(INCPATH) sources/RamMonitor.h -o moc_RamMonitor.cpp + +compiler_rcc_make_all: +compiler_rcc_clean: +compiler_image_collection_make_all: qmake_image_collection.cpp +compiler_image_collection_clean: + -$(DEL_FILE) qmake_image_collection.cpp +compiler_moc_source_make_all: +compiler_moc_source_clean: +compiler_uic_make_all: +compiler_uic_clean: +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: compiler_moc_header_clean + +####### Compile + +main.o: sources/main.cpp sources/Zonetest.h \ + sources/MainPanel.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/ZTStateMachine.h \ + sources/PCIIOMgr.h \ + sources/ZT1AnalysisThread.h \ + sources/ZT2AnalysisThread.h \ + sources/TKGenerator.h \ + sources/LogMgr.h \ + sources/EventMgr.h \ + sources/Event.h \ + sources/ZTSettings.h \ + sources/USBDriveInterface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o sources/main.cpp + +MainPanel.o: sources/MainPanel.cpp sources/MainPanel.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZTconfigmgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/LazerProbesMgr.h \ + sources/AbstractLazerProbeMgr.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o MainPanel.o sources/MainPanel.cpp + +Station.o: sources/Station.cpp sources/Station.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Station.o sources/Station.cpp + +ZTconfigmgr.o: sources/ZTconfigmgr.cpp sources/ZTconfigmgr.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/LazerProbesMgr.h \ + sources/AbstractLazerProbeMgr.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTconfigmgr.o sources/ZTconfigmgr.cpp + +Zonetest.o: sources/Zonetest.cpp sources/Zonetest.h \ + sources/MainPanel.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/ZTStateMachine.h \ + sources/PCIIOMgr.h \ + sources/ZT1AnalysisThread.h \ + sources/ZT2AnalysisThread.h \ + sources/TKGenerator.h \ + sources/LogMgr.h \ + sources/EventMgr.h \ + sources/Event.h \ + sources/ZTSettings.h \ + sources/USBDriveInterface.h \ + sources/ZTconfigmgr.h \ + sources/ZTLog.h \ + sources/RamMonitor.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Zonetest.o sources/Zonetest.cpp + +EngLog.o: sources/EngLog.cpp sources/EngLog.h \ + sources/GlobalDefine.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EngLog.o sources/EngLog.cpp + +GuiPage.o: sources/GuiElements/GuiPage.cpp sources/GuiElements/Guipage.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o GuiPage.o sources/GuiElements/GuiPage.cpp + +WelcomePage.o: sources/GuiElements/WelcomePage.cpp sources/GuiElements/WelcomePage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/SimpleTextBoxWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o WelcomePage.o sources/GuiElements/WelcomePage.cpp + +SimpleTextBoxWidget.o: sources/GuiElements/SimpleTextBoxWidget.cpp sources/GuiElements/SimpleTextBoxWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimpleTextBoxWidget.o sources/GuiElements/SimpleTextBoxWidget.cpp + +Angrignon.o: sources/Stations/Angrignon.cpp sources/Stations/Angrignon.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Angrignon.o sources/Stations/Angrignon.cpp + +HonoreBeaugrand.o: sources/Stations/HonoreBeaugrand.cpp sources/Stations/HonoreBeaugrand.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o HonoreBeaugrand.o sources/Stations/HonoreBeaugrand.cpp + +HenriBourassa.o: sources/Stations/HenriBourassa.cpp sources/Stations/HenriBourassa.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o HenriBourassa.o sources/Stations/HenriBourassa.cpp + +CoteVertu.o: sources/Stations/CoteVertu.cpp sources/Stations/CoteVertu.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o CoteVertu.o sources/Stations/CoteVertu.cpp + +BerriUQAM.o: sources/Stations/BerriUQAM.cpp sources/Stations/BerriUQAM.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o BerriUQAM.o sources/Stations/BerriUQAM.cpp + +Longueuil.o: sources/Stations/Longueuil.cpp sources/Stations/Longueuil.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Longueuil.o sources/Stations/Longueuil.cpp + +SaintMichel.o: sources/Stations/SaintMichel.cpp sources/Stations/SaintMichel.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SaintMichel.o sources/Stations/SaintMichel.cpp + +Snowdon.o: sources/Stations/Snowdon.cpp sources/Stations/Snowdon.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Snowdon.o sources/Stations/Snowdon.cpp + +Montmorency.o: sources/Stations/Montmorency.cpp sources/Stations/Montmorency.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Montmorency.o sources/Stations/Montmorency.cpp + +ZTPage.o: sources/GuiElements/ZTPage.cpp sources/GuiElements/ZTPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/CDVItem.h \ + sources/GuiElements/StatusBar.h \ + sources/GuiElements/ZT1EquipmentWidget.h \ + sources/GuiElements/ZT1StatsZone.h \ + sources/GuiElements/EventsBar.h \ + sources/GuiElements/EventItem.h \ + sources/GuiElements/ZT2EquipmentWidget.h \ + sources/GuiElements/ZT2StatsZone.h \ + sources/GuiElements/PasswordPrompt.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/SwitchCDVItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTPage.o sources/GuiElements/ZTPage.cpp + +LazerProbe.o: sources/LazerProbe.cpp sources/LazerProbe.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/AbstractLazerProbe.h \ + sources/LazerProbesMgr.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o LazerProbe.o sources/LazerProbe.cpp + +LazerProbesMgr.o: sources/LazerProbesMgr.cpp sources/LazerProbesMgr.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTconfigmgr.h \ + sources/ZTLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o LazerProbesMgr.o sources/LazerProbesMgr.cpp + +ZTLog.o: sources/ZTLog.cpp sources/ZTLog.h \ + sources/GlobalDefine.h \ + sources/EngLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTLog.o sources/ZTLog.cpp + +PushButton.o: sources/GuiElements/PushButton.cpp sources/GuiElements/PushButton.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o PushButton.o sources/GuiElements/PushButton.cpp + +ZTStateMachine.o: sources/ZTStateMachine.cpp sources/ZTStateMachine.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZTData.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/PCIIOMgr.h \ + sources/ZT1AnalysisThread.h \ + sources/ZT2AnalysisThread.h \ + sources/TKGenerator.h \ + sources/LogMgr.h \ + sources/ZTLog.h \ + sources/RamMonitor.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTStateMachine.o sources/ZTStateMachine.cpp + +ZTData.o: sources/ZTData.cpp sources/ZTData.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTData.o sources/ZTData.cpp + +ZTSimulator.o: sources/Simulator/ZTSimulator.cpp sources/Simulator/ZTSimulator.h \ + sources/Simulator/SimulatorIOManager.h \ + sources/Simulator/SimulatorInputModule.h \ + sources/Simulator/SImulatorOutputModule.h \ + sources/Simulator/SimulatorMixedModule.h \ + sources/Simulator/SimulatorLazerProbesMgr.h \ + sources/Simulator/SimulatorLazerProbe.h \ + sources/Simulator/SimulatorPCIIO.h \ + sources/Simulator/SimulationScenario.h \ + sources/Simulator/SimulatorThread.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTSimulator.o sources/Simulator/ZTSimulator.cpp + +CDVItem.o: sources/GuiElements/CDVItem.cpp sources/GuiElements/CDVItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o CDVItem.o sources/GuiElements/CDVItem.cpp + +IOManager.o: sources/IOManager.cpp sources/IOManager.h \ + sources/IOModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o IOManager.o sources/IOManager.cpp + +IOModule.o: sources/IOModule.cpp sources/IOModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o IOModule.o sources/IOModule.cpp + +InputModule.o: sources/InputModule.cpp sources/InputModule.h \ + sources/IOModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o InputModule.o sources/InputModule.cpp + +OutputModule.o: sources/OutputModule.cpp sources/OutputModule.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/IOModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o OutputModule.o sources/OutputModule.cpp + +MixedModule.o: sources/MixedModule.cpp sources/MixedModule.h \ + sources/IOModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o MixedModule.o sources/MixedModule.cpp + +SimulatorIOManager.o: sources/Simulator/SimulatorIOManager.cpp sources/Simulator/SimulatorIOManager.h \ + sources/Simulator/SimulatorInputModule.h \ + sources/Simulator/SImulatorOutputModule.h \ + sources/Simulator/SimulatorMixedModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulatorIOManager.o sources/Simulator/SimulatorIOManager.cpp + +SimulatorInputModule.o: sources/Simulator/SimulatorInputModule.cpp sources/Simulator/SimulatorInputModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulatorInputModule.o sources/Simulator/SimulatorInputModule.cpp + +SImulatorOutputModule.o: sources/Simulator/SImulatorOutputModule.cpp sources/Simulator/SImulatorOutputModule.h \ + sources/Simulator/ZTSimulator.h \ + sources/Simulator/SimulatorIOManager.h \ + sources/Simulator/SimulatorInputModule.h \ + sources/Simulator/SimulatorMixedModule.h \ + sources/Simulator/SimulatorLazerProbesMgr.h \ + sources/Simulator/SimulatorLazerProbe.h \ + sources/Simulator/SimulatorPCIIO.h \ + sources/Simulator/SimulationScenario.h \ + sources/Simulator/SimulatorThread.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SImulatorOutputModule.o sources/Simulator/SImulatorOutputModule.cpp + +SimulatorMixedModule.o: sources/Simulator/SimulatorMixedModule.cpp sources/Simulator/SimulatorMixedModule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulatorMixedModule.o sources/Simulator/SimulatorMixedModule.cpp + +CDV.o: sources/CDV.cpp sources/CDV.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZTData.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o CDV.o sources/CDV.cpp + +AbstractLazerProbeMgr.o: sources/AbstractLazerProbeMgr.cpp sources/AbstractLazerProbeMgr.h \ + sources/AbstractLazerProbe.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o AbstractLazerProbeMgr.o sources/AbstractLazerProbeMgr.cpp + +AbstractLazerProbe.o: sources/AbstractLazerProbe.cpp sources/AbstractLazerProbe.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o AbstractLazerProbe.o sources/AbstractLazerProbe.cpp + +SimulatorLazerProbe.o: sources/Simulator/SimulatorLazerProbe.cpp sources/Simulator/SimulatorLazerProbe.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulatorLazerProbe.o sources/Simulator/SimulatorLazerProbe.cpp + +SimulatorLazerProbesMgr.o: sources/Simulator/SimulatorLazerProbesMgr.cpp sources/Simulator/SimulatorLazerProbesMgr.h \ + sources/Simulator/SimulatorLazerProbe.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulatorLazerProbesMgr.o sources/Simulator/SimulatorLazerProbesMgr.cpp + +PCIIOMgr.o: sources/PCIIOMgr.cpp sources/PCIIOMgr.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o PCIIOMgr.o sources/PCIIOMgr.cpp + +SimulatorPCIIO.o: sources/Simulator/SimulatorPCIIO.cpp sources/Simulator/SimulatorPCIIO.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulatorPCIIO.o sources/Simulator/SimulatorPCIIO.cpp + +ToggleTextButtonWidget.o: sources/GuiElements/ToggleTextButtonWidget.cpp sources/GuiElements/TextButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ToggleTextButtonWidget.o sources/GuiElements/ToggleTextButtonWidget.cpp + +TextButtonWidget.o: sources/GuiElements/TextButtonWidget.cpp sources/GuiElements/TextButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o TextButtonWidget.o sources/GuiElements/TextButtonWidget.cpp + +ZT1AnalysisThread.o: sources/ZT1AnalysisThread.cpp sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZT1AnalysisThread.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/PCIIOMgr.h \ + sources/ZTconfigmgr.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZT1AnalysisThread.o sources/ZT1AnalysisThread.cpp + +StatusBar.o: sources/GuiElements/StatusBar.cpp sources/GuiElements/StatusBar.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o StatusBar.o sources/GuiElements/StatusBar.cpp + +ZT1EquipmentWidget.o: sources/GuiElements/ZT1EquipmentWidget.cpp sources/GuiElements/ZT1EquipmentWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZT1EquipmentWidget.o sources/GuiElements/ZT1EquipmentWidget.cpp + +ZT1StatsZone.o: sources/GuiElements/ZT1StatsZone.cpp sources/GuiElements/ZT1StatsZone.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZT1StatsZone.o sources/GuiElements/ZT1StatsZone.cpp + +SimulationScenario.o: sources/Simulator/SimulationScenario.cpp sources/Simulator/SimulationScenario.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulationScenario.o sources/Simulator/SimulationScenario.cpp + +OptionsPage.o: sources/GuiElements/OptionsPage.cpp sources/GuiElements/OptionsPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o OptionsPage.o sources/GuiElements/OptionsPage.cpp + +FunctionSelectionPage.o: sources/GuiElements/FunctionSelectionPage.cpp sources/GuiElements/FunctionSelectionPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/ToggleButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o FunctionSelectionPage.o sources/GuiElements/FunctionSelectionPage.cpp + +ToggleButtonWidget.o: sources/GuiElements/ToggleButtonWidget.cpp sources/GuiElements/ToggleButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ToggleButtonWidget.o sources/GuiElements/ToggleButtonWidget.cpp + +EventsBar.o: sources/GuiElements/EventsBar.cpp sources/GuiElements/EventsBar.h \ + sources/GuiElements/EventItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EventsBar.o sources/GuiElements/EventsBar.cpp + +EventItem.o: sources/GuiElements/EventItem.cpp sources/GuiElements/EventItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EventItem.o sources/GuiElements/EventItem.cpp + +Event.o: sources/Event.cpp sources/Event.h \ + sources/GlobalDefine.h \ + sources/EngLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Event.o sources/Event.cpp + +EventMgr.o: sources/EventMgr.cpp sources/EventMgr.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/Event.h \ + sources/ZTData.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EventMgr.o sources/EventMgr.cpp + +TrainLogFileMgr.o: sources/TrainLogFileMgr.cpp sources/TrainLogFileMgr.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZTData.h \ + sources/LogMgr.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o TrainLogFileMgr.o sources/TrainLogFileMgr.cpp + +LogMgr.o: sources/LogMgr.cpp sources/LogMgr.h \ + sources/ZTData.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/TrainLogFileMgr.h \ + sources/ZTLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o LogMgr.o sources/LogMgr.cpp + +LogsListPage.o: sources/GuiElements/LogsListPage.cpp sources/GuiElements/LogsListPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o LogsListPage.o sources/GuiElements/LogsListPage.cpp + +LogViewPage.o: sources/GuiElements/LogViewPage.cpp sources/GuiElements/LogViewPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/GraphItem.h \ + sources/GuiElements/GraphCursorWidget.h \ + sources/GuiElements/GraphRulerWidget.h \ + sources/GuiElements/AnalogGraphItem.h \ + sources/GuiElements/RankRulerWidget.h \ + sources/GuiElements/EventsRulerWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o LogViewPage.o sources/GuiElements/LogViewPage.cpp + +GraphItem.o: sources/GuiElements/GraphItem.cpp sources/GuiElements/GraphItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o GraphItem.o sources/GuiElements/GraphItem.cpp + +GraphCursorWidget.o: sources/GuiElements/GraphCursorWidget.cpp sources/GuiElements/GraphCursorWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o GraphCursorWidget.o sources/GuiElements/GraphCursorWidget.cpp + +GraphRulerWidget.o: sources/GuiElements/GraphRulerWidget.cpp sources/GuiElements/GraphRulerWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o GraphRulerWidget.o sources/GuiElements/GraphRulerWidget.cpp + +AnalogGraphItem.o: sources/GuiElements/AnalogGraphItem.cpp sources/GuiElements/AnalogGraphItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o AnalogGraphItem.o sources/GuiElements/AnalogGraphItem.cpp + +ZTSettings.o: sources/ZTSettings.cpp sources/ZTSettings.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZTData.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTSettings.o sources/ZTSettings.cpp + +ZT2EquipmentWidget.o: sources/GuiElements/ZT2EquipmentWidget.cpp sources/GuiElements/ZT2EquipmentWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZT2EquipmentWidget.o sources/GuiElements/ZT2EquipmentWidget.cpp + +ZT2AnalysisThread.o: sources/ZT2AnalysisThread.cpp sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/ZT2AnalysisThread.h \ + sources/Station.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h \ + sources/PCIIOMgr.h \ + sources/ZTconfigmgr.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZT2AnalysisThread.o sources/ZT2AnalysisThread.cpp + +ZT2StatsZone.o: sources/GuiElements/ZT2StatsZone.cpp sources/GuiElements/ZT2StatsZone.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZT2StatsZone.o sources/GuiElements/ZT2StatsZone.cpp + +TKGenerator.o: sources/TKGenerator.cpp sources/TKGenerator.h \ + sources/Station.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/InputModule.h \ + sources/IOModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/LazerProbesMgr.h \ + sources/LazerProbe.h \ + sources/AbstractLazerProbe.h \ + sources/AbstractLazerProbeMgr.h \ + sources/ZTData.h \ + sources/IOManager.h \ + sources/CDV.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o TKGenerator.o sources/TKGenerator.cpp + +LedWidget.o: sources/GuiElements/LedWidget.cpp sources/GuiElements/LedWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o LedWidget.o sources/GuiElements/LedWidget.cpp + +RankRulerWidget.o: sources/GuiElements/RankRulerWidget.cpp sources/GuiElements/RankRulerWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o RankRulerWidget.o sources/GuiElements/RankRulerWidget.cpp + +EngineeringPage.o: sources/GuiElements/EngineeringPage.cpp sources/GuiElements/EngineeringPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/PasswordPrompt.h \ + sources/GuiElements/ToggleButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EngineeringPage.o sources/GuiElements/EngineeringPage.cpp + +PasswordPrompt.o: sources/GuiElements/PasswordPrompt.cpp sources/GuiElements/PasswordPrompt.h \ + sources/GuiElements/TextButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o PasswordPrompt.o sources/GuiElements/PasswordPrompt.cpp + +EventsRulerWidget.o: sources/GuiElements/EventsRulerWidget.cpp sources/GuiElements/EventsRulerWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EventsRulerWidget.o sources/GuiElements/EventsRulerWidget.cpp + +USBDriveInterface.o: sources/USBDriveInterface.cpp sources/USBDriveInterface.h \ + sources/GlobalDefine.h \ + sources/EngLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o USBDriveInterface.o sources/USBDriveInterface.cpp + +MaintenancePage.o: sources/GuiElements/MaintenancePage.cpp sources/GuiElements/MaintenancePage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/GuiElements/ToggleButtonWidget.h \ + sources/GuiElements/ONOFFStatusWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o MaintenancePage.o sources/GuiElements/MaintenancePage.cpp + +SimulatorThread.o: sources/Simulator/SimulatorThread.cpp sources/Simulator/SimulatorThread.h \ + sources/Simulator/SimulatorInputModule.h \ + sources/Simulator/SImulatorOutputModule.h \ + sources/Simulator/SimulatorPCIIO.h \ + sources/Simulator/SimulatorLazerProbe.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SimulatorThread.o sources/Simulator/SimulatorThread.cpp + +GeneralSettingsPage.o: sources/GuiElements/GeneralSettingsPage.cpp sources/GuiElements/GeneralSettingsPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/PushButton.h \ + sources/GuiElements/TextButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o GeneralSettingsPage.o sources/GuiElements/GeneralSettingsPage.cpp + +ONOFFStatusWidget.o: sources/GuiElements/ONOFFStatusWidget.cpp sources/GuiElements/ONOFFStatusWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ONOFFStatusWidget.o sources/GuiElements/ONOFFStatusWidget.cpp + +ZTLogViewerPage.o: sources/GuiElements/ZTLogViewerPage.cpp sources/GuiElements/ZTLogViewerPage.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/TextButtonWidget.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ZTLogViewerPage.o sources/GuiElements/ZTLogViewerPage.cpp + +SwitchCDV.o: sources/SwitchCDV.cpp sources/SwitchCDV.h \ + sources/GlobalDefine.h \ + sources/EngLog.h \ + sources/CDV.h \ + sources/ZTData.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SwitchCDV.o sources/SwitchCDV.cpp + +SwitchCDVItem.o: sources/GuiElements/SwitchCDVItem.cpp sources/GuiElements/SwitchCDVItem.h \ + sources/GuiElements/CDVItem.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o SwitchCDVItem.o sources/GuiElements/SwitchCDVItem.cpp + +RamMonitor.o: sources/RamMonitor.cpp sources/RamMonitor.h \ + sources/GlobalDefine.h \ + sources/EngLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o RamMonitor.o sources/RamMonitor.cpp + +Externaliomodule.o: sources/ExtModules/Externaliomodule.cpp sources/ExtModules/Externaliomodule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Externaliomodule.o sources/ExtModules/Externaliomodule.cpp + +Seaio430driver.o: sources/ExtModules/Seaio430driver.cpp sources/ExtModules/Seaio430driver.h \ + sources/ExtModules/Externaliomodule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Seaio430driver.o sources/ExtModules/Seaio430driver.cpp + +Seaio440driver.o: sources/ExtModules/Seaio440driver.cpp sources/ExtModules/Seaio440driver.h \ + sources/ExtModules/Externaliomodule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Seaio440driver.o sources/ExtModules/Seaio440driver.cpp + +Seaio470driver.o: sources/ExtModules/Seaio470driver.cpp sources/ExtModules/Seaio470driver.h \ + sources/ExtModules/Externaliomodule.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Seaio470driver.o sources/ExtModules/Seaio470driver.cpp + +Seaiolibinterface.o: sources/ExtModules/Seaiolibinterface.cpp sources/ExtModules/Seaiolibinterface.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Seaiolibinterface.o sources/ExtModules/Seaiolibinterface.cpp + +Comedilibinterface.o: sources/PCIIO/Comedilibinterface.cpp sources/PCIIO/Comedilibinterface.h \ + sources/PCIIO/PCI1756Definitions.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o Comedilibinterface.o sources/PCIIO/Comedilibinterface.cpp + +ExternalIOMgr.o: sources/ExtModules/ExternalIOMgr.cpp sources/ExtModules/ExternalIOMgr.h \ + sources/ExtModules/Seaiolibinterface.h \ + sources/ExtModules/Externaliomodule.h \ + sources/ExtModules/Seaio430driver.h \ + sources/ExtModules/Seaio440driver.h \ + sources/ExtModules/Seaio470driver.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o ExternalIOMgr.o sources/ExtModules/ExternalIOMgr.cpp + +moc_MainPanel.o: moc_MainPanel.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_MainPanel.o moc_MainPanel.cpp + +moc_Zonetest.o: moc_Zonetest.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_Zonetest.o moc_Zonetest.cpp + +moc_Guipage.o: moc_Guipage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_Guipage.o moc_Guipage.cpp + +moc_WelcomePage.o: moc_WelcomePage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_WelcomePage.o moc_WelcomePage.cpp + +moc_SimpleTextBoxWidget.o: moc_SimpleTextBoxWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_SimpleTextBoxWidget.o moc_SimpleTextBoxWidget.cpp + +moc_ZTPage.o: moc_ZTPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZTPage.o moc_ZTPage.cpp + +moc_LazerProbe.o: moc_LazerProbe.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_LazerProbe.o moc_LazerProbe.cpp + +moc_LazerProbesMgr.o: moc_LazerProbesMgr.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_LazerProbesMgr.o moc_LazerProbesMgr.cpp + +moc_PushButton.o: moc_PushButton.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_PushButton.o moc_PushButton.cpp + +moc_ZTStateMachine.o: moc_ZTStateMachine.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZTStateMachine.o moc_ZTStateMachine.cpp + +moc_ZTSimulator.o: moc_ZTSimulator.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZTSimulator.o moc_ZTSimulator.cpp + +moc_CDVItem.o: moc_CDVItem.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_CDVItem.o moc_CDVItem.cpp + +moc_SimulatorLazerProbe.o: moc_SimulatorLazerProbe.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_SimulatorLazerProbe.o moc_SimulatorLazerProbe.cpp + +moc_ToggleTextButtonWidget.o: moc_ToggleTextButtonWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ToggleTextButtonWidget.o moc_ToggleTextButtonWidget.cpp + +moc_TextButtonWidget.o: moc_TextButtonWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_TextButtonWidget.o moc_TextButtonWidget.cpp + +moc_ZT1AnalysisThread.o: moc_ZT1AnalysisThread.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZT1AnalysisThread.o moc_ZT1AnalysisThread.cpp + +moc_StatusBar.o: moc_StatusBar.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_StatusBar.o moc_StatusBar.cpp + +moc_ZT1EquipmentWidget.o: moc_ZT1EquipmentWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZT1EquipmentWidget.o moc_ZT1EquipmentWidget.cpp + +moc_ZT1StatsZone.o: moc_ZT1StatsZone.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZT1StatsZone.o moc_ZT1StatsZone.cpp + +moc_SimulationScenario.o: moc_SimulationScenario.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_SimulationScenario.o moc_SimulationScenario.cpp + +moc_OptionsPage.o: moc_OptionsPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_OptionsPage.o moc_OptionsPage.cpp + +moc_FunctionSelectionPage.o: moc_FunctionSelectionPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_FunctionSelectionPage.o moc_FunctionSelectionPage.cpp + +moc_ToggleButtonWidget.o: moc_ToggleButtonWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ToggleButtonWidget.o moc_ToggleButtonWidget.cpp + +moc_EventsBar.o: moc_EventsBar.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_EventsBar.o moc_EventsBar.cpp + +moc_EventItem.o: moc_EventItem.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_EventItem.o moc_EventItem.cpp + +moc_LogsListPage.o: moc_LogsListPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_LogsListPage.o moc_LogsListPage.cpp + +moc_LogViewPage.o: moc_LogViewPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_LogViewPage.o moc_LogViewPage.cpp + +moc_GraphItem.o: moc_GraphItem.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_GraphItem.o moc_GraphItem.cpp + +moc_GraphCursorWidget.o: moc_GraphCursorWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_GraphCursorWidget.o moc_GraphCursorWidget.cpp + +moc_GraphRulerWidget.o: moc_GraphRulerWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_GraphRulerWidget.o moc_GraphRulerWidget.cpp + +moc_AnalogGraphItem.o: moc_AnalogGraphItem.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_AnalogGraphItem.o moc_AnalogGraphItem.cpp + +moc_ZT2EquipmentWidget.o: moc_ZT2EquipmentWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZT2EquipmentWidget.o moc_ZT2EquipmentWidget.cpp + +moc_ZT2AnalysisThread.o: moc_ZT2AnalysisThread.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZT2AnalysisThread.o moc_ZT2AnalysisThread.cpp + +moc_ZT2StatsZone.o: moc_ZT2StatsZone.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZT2StatsZone.o moc_ZT2StatsZone.cpp + +moc_TKGenerator.o: moc_TKGenerator.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_TKGenerator.o moc_TKGenerator.cpp + +moc_LedWidget.o: moc_LedWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_LedWidget.o moc_LedWidget.cpp + +moc_RankRulerWidget.o: moc_RankRulerWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_RankRulerWidget.o moc_RankRulerWidget.cpp + +moc_EngineeringPage.o: moc_EngineeringPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_EngineeringPage.o moc_EngineeringPage.cpp + +moc_PasswordPrompt.o: moc_PasswordPrompt.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_PasswordPrompt.o moc_PasswordPrompt.cpp + +moc_EventsRulerWidget.o: moc_EventsRulerWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_EventsRulerWidget.o moc_EventsRulerWidget.cpp + +moc_USBDriveInterface.o: moc_USBDriveInterface.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_USBDriveInterface.o moc_USBDriveInterface.cpp + +moc_MaintenancePage.o: moc_MaintenancePage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_MaintenancePage.o moc_MaintenancePage.cpp + +moc_SimulatorThread.o: moc_SimulatorThread.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_SimulatorThread.o moc_SimulatorThread.cpp + +moc_GeneralSettingsPage.o: moc_GeneralSettingsPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_GeneralSettingsPage.o moc_GeneralSettingsPage.cpp + +moc_ONOFFStatusWidget.o: moc_ONOFFStatusWidget.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ONOFFStatusWidget.o moc_ONOFFStatusWidget.cpp + +moc_ZTLogViewerPage.o: moc_ZTLogViewerPage.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_ZTLogViewerPage.o moc_ZTLogViewerPage.cpp + +moc_SwitchCDVItem.o: moc_SwitchCDVItem.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_SwitchCDVItem.o moc_SwitchCDVItem.cpp + +moc_RamMonitor.o: moc_RamMonitor.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_RamMonitor.o moc_RamMonitor.cpp + +####### Install + +install: FORCE + +uninstall: FORCE + +FORCE: + diff --git a/SeaMaxLinux/Makefile b/SeaMaxLinux/Makefile new file mode 100644 index 0000000..3647e20 --- /dev/null +++ b/SeaMaxLinux/Makefile @@ -0,0 +1,39 @@ +# +# $Id: Makefile,v 1.6 2007/01/12 20:20:05 thomasw Exp $ +# +# General build makefile. (Includes) + +INCLUDEDIR ?= /usr/local/include + +CP ?= /bin/cp +RM ?= /bin/rm + + +## ============================================================================ +FILES = seamaxlin.h cethernet.h + + +## ============================================================================ +all: $(FILES) + @echo " *Include dir is prepared." + @echo + +objs: $(FILES) + @echo " *Include dir is prepared." + @echo + +install: $(FILES) + @echo " *Installing header files to $(INCLUDEDIR)" + @for n in $(FILES); do $(CP) -r $$n $(INCLUDEDIR) || exit 1; done + @echo " Done installing header files." + @echo + +uninstall: + @echo " *Uninstalling header files from $(INCLUDEDIR)" + @for n in $(FILES); do $(RM) -rf ${INCLUDEDIR}/$$n || exit 1; done + @echo " Header files removed." + @echo + +clean: $(FILES) + @echo " *Nothing to clean in Include dir." + @echo diff --git a/SeaMaxLinux/SeaMAX_1.3.5.tar.gz b/SeaMaxLinux/SeaMAX_1.3.5.tar.gz new file mode 100644 index 0000000..08c929c Binary files /dev/null and b/SeaMaxLinux/SeaMAX_1.3.5.tar.gz differ diff --git a/SeaMaxLinux/cethernet.h b/SeaMaxLinux/cethernet.h new file mode 100644 index 0000000..8192a73 --- /dev/null +++ b/SeaMaxLinux/cethernet.h @@ -0,0 +1,122 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2008, Sealevel Systems +// +// For help please contact us by email at support@sealevel.com. +// +// $Id: cethernet.h,v 1.6 2008/09/24 13:47:40 thomasw Exp $ +// ---------------------------------------------------------------------------- + +#ifndef CETHERNET_H__ +#define CETHERNET_H__ + +// This is for inclusion by the C++ wrapper. +#ifdef __cplusplus + extern "C" { +#endif + +// ---------------------------------------------------------------------------- +// | Structs used in this library. | +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief The device type -- SeaIO_Ethernet or SeaLink_Dev. +/// In the windows version of this library, this function can find both types +/// of devices. To make things simpler, this version of CEthernet only works +/// with SeaIO_Ethernet devices. +// ---------------------------------------------------------------------------- +typedef enum ceth_device_type +{ + SeaIO_Ethernet = 1, ///< Ethernet enabled SeaIO devices. + SeaLink_Dev = 2, ///< Skeletal SeaLink device support. + Sealevel_All_Devices = 99 ///< Any type. +} ceth_device_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief The type of information to set with the set_information function. +/// You may optionally OR two of the commands together. You cannot OR SetDHCP +/// and SetIPAddress. If you do OR one of the IP related functions with +/// SetName, the name parameter should be the last parameter. +// ---------------------------------------------------------------------------- +typedef enum ceth_set_types +{ + SetIPAddress = 1, ///< Option to set a device's IP address. + SetName = 4, ///< Option to set the device's name. + SetDHCP = 2 ///< Option to enable DHCP mode. +} ceth_set_types; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief An IP, NetMask, or GateWay Address. +/// This is a union which will allow you to access the data in one of three +/// data type methods -- long (all 4 bytes at once), short (2 bytes at a time), +/// or char (1 byte at a time). If you access the data 1 byte at a time, through +/// the c array, each octet is the same as the human readable ip address. ie the +/// first octet (0) in the IP 192.168.0.1 can be accessed through +/// ceth_ip_addr.c[2]. +// ---------------------------------------------------------------------------- +typedef union ceth_ip_addr +{ + unsigned long i; ///< Access all 4 bytes at once. + unsigned short s[2]; ///< Access to two bytes at a time. + unsigned char c[4]; ///< Access to each individual byte. +} ceth_ip_addr; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief This is a MAC address storage struct. +/// This struct can only be accessed one byte at a time. +// ---------------------------------------------------------------------------- +typedef struct ceth_addr_info +{ + unsigned char c[6]; ///< The six byte of the MAC address. +} ceth_addr_info; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief This is the device info struct. +/// find_devices() expects a list of this structs. The data fields of this +/// struct are filled in in find_device(). Please note that the MAC address can +/// only be retrieved as a privileged user (RAW Sockets). +// ---------------------------------------------------------------------------- +typedef struct ceth_device +{ + ceth_device_type type; ///< SeaLink or SeaIO. + ceth_addr_info mac_address; ///< Device MAC address. + ceth_ip_addr ip_address; ///< IP address. + ceth_ip_addr net_mask; ///< Device Netmask. + ceth_ip_addr gateway; ///< Device Gateway. + char name[20]; ///< Device name (max 8 bytes). + unsigned char dhcp_enabled; ///< Is DHCP mode enabled? + struct ceth_device *next; ///< Pointer to next device. + void *prop_data; ///< Skeleton. Unused. +} ceth_device, *ceth_device_p; + +// ---------------------------------------------------------------------------- +// | The C library function prototypes. | +// ---------------------------------------------------------------------------- + +ceth_device *CEthernet_Alloc(int number); +void CEthernet_Free(ceth_device *list); +int CEthernet_find_devices(ceth_device_type type, int num, ceth_device *list); +int CEthernet_set_information(ceth_device *device, ceth_set_types command, ...); +int CEthernet_recover_module(ceth_device *device); + +// ---------------------------------------------------------------------------- +// | The C++ class! | +// ---------------------------------------------------------------------------- +#ifdef __cplusplus + } + +class CCEthernet { +public: + ceth_device *Alloc(int number); + void Free(ceth_device *list); + int find_devices(ceth_device_type type, int number, ceth_device *list); + int set_information(ceth_device *device, ceth_set_types command, ...); + int recover_module(ceth_device *device); +}; + +#endif //__cplusplus +#endif //CETHERNET_H__ diff --git a/SeaMaxLinux/seamaxlin.h b/SeaMaxLinux/seamaxlin.h new file mode 100644 index 0000000..0eea2b0 --- /dev/null +++ b/SeaMaxLinux/seamaxlin.h @@ -0,0 +1,586 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2008, Sealevel Systems +// +// For help please contact us by email at support@sealevel.com. +// +// $Id: seamaxlin.h,v 1.11 2009/07/13 19:49:55 kmoody Exp $ +// ---------------------------------------------------------------------------- +#ifndef PUBLIC_DOCUMENTATION +/*! \mainpage Linux SeaMax API Documentation + * \section warning Internal Disclaimer + * + * WARNING! This document is intended for internal use only. + */ +#else +/*! \mainpage Linux SeaMAX API Documentation + * + * \section intro_sec Introduction + * + * Sealevel digital and analog I/O modules supported by the SeaMAX software + * suite are designed to work with third party applications via the SeaMAX API. + * To help simplify application development, the following documentation + * details the functions of the SeaMAX API. To help you get started, example + * C and C++ source code is provided. + * + * \section start Getting Started + * + * There are three modules that are included in the SeaMAX API: + * + * \li \ref group_seamax_all
+ * The foundation of SeaMAX with functions for configuring, interfacing, + * and modifying supported Sealevel digital I/O modules and devices. + * \li \ref group_cethernet_all
+ * The Ethernet module contains functions related to the discovery and + * configuration of Sealevel I/O devices with an Ethernet interface. + * \li \ref modbusbreakdown
+ * The Modbus Specification contains detailed descriptions of all RTU + * and TCP Modbus commands applicable to SeaIO and SeaDAC modules. + * + * The 'Modules' tab above lists all SeaMAX modules and their functions. For + * additional information regarding legacy products and technical + * specifications, please refer to the 'Related Pages' tab above. + * + * \section questions Questions & Comments + * + * Send your questions and comments to Sealevel Systems. For technical + * assistance, please include your model or part number and any device + * settings that may apply. Technical support is available Monday to + * Friday from 8:00AM to 5:00PM (US Eastern Time Zone, UTC-6 hours) by + * email (support@sealevel.com) or by phone at +1 (864) 843.4343. + */ + + + +/// \defgroup group_seamax_all SeaMAX API +/// The SeaMAX API consists of the functions outline below, and provides an +/// interface for construction, transmission, and reception of Modbus RTU and +/// TCP commands. For more information, click a function name below for +/// detailed information on function use, parameter types, and return codes. +/// +/// \note Not every function below may apply to your specific Sealevel I/O +/// device. Refer to the \ref modbusbreakdown "modbus breakdown". + +/// \defgroup group_cethernet_all SeaMAX Ethernet Discovery/Configuration API +/// +/// The SeaMAX Ethernet Discover API includes functions used for configuration +/// and discovery of Ethernet enabled Sealevel I/O devices. For specifics, +/// click any of the function names below to view function use, parameters, and +/// return code information. + +/// \ingroup group_seamax_all +/// \defgroup group_seamax_oop Object-Oriented SeaMAX Modbus Interface +/// This is a C++ wrapper for the standard SeaMAX Modbus interface library. +/// This library is designed to aid in the construction, transmission, and +/// reception of Modbus RTU and TCP commands. This library is designed for use +/// with Sealevel SeaIO modules. +/// + +/// \ingroup group_seamax_all +/// \defgroup group_seamax_fun Functional SeaMAX Modbus Interface +/// This is a simple C library to aid in the construction, transmission, and +/// reception of Modbus RTU and TCP commands. This library is designed for use +/// with Sealevel SeaIO modules. +/// + +/// \ingroup group_cethernet_all +/// \defgroup group_cethernet_oop Object Oriented CEthernet Interface +/// This is a C++ wrapper for the standard CEthernet library. This library is +/// designed to aid in the discovery and configuration of Ethernet enabled +/// SeaIO modules. +/// + +/// \ingroup group_cethernet_all +/// \defgroup group_cethernet_fun Functional CEthernet Interface +/// This is a simple C library to aid in the discovery and configuration +/// of Ethernet enabled SeaIO modules. +/// +#endif + +#ifndef SEAMAXLIN_H__ +#define SEAMAXLIN_H__ + +#include "thirdparty/ftdi.h" + +// Sealevel vendor ID number +#define VENDOR 0x0c52 + +// This is used for proper inclusion when used with C++ +#ifdef __cplusplus + extern "C" { +#endif + + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef SeaMaxLin +/// Pointer to a SeaMax object. The data structure this points to is private +/// and should not be accessed directly, but through the function calls instead. +// ---------------------------------------------------------------------------- +typedef long SeaMaxLin; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef HANDLE +/// A handle or pointer to another data structure. +/// This particular pointer is used to pass the serial communications struct. +// ---------------------------------------------------------------------------- +typedef int HANDLE; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef slave_address_t +/// The slave ID of a device. This value can be from 1 to 247. +// ---------------------------------------------------------------------------- +typedef unsigned char slave_address_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef address_loc_t +/// An address specific to your device. Check read/write functions for +/// specific use. +// ---------------------------------------------------------------------------- +typedef unsigned short address_loc_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef address_range_t +/// The range of address to be used. Check read/write functions for specific +/// use. +// ---------------------------------------------------------------------------- +typedef unsigned short address_range_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The module connection type. +/// Currently there is only support for RTU and TCP type connections. +// ---------------------------------------------------------------------------- +typedef enum +{ + NO_CONNECT = 0, ///< Connection not open. + MODBUS_RTU = 1, ///< An RTU type connection. 232, 485, USB. + MODBUS_TCP = 2, ///< An ethernet connection. + FTDI_DIRECT = 3 ///< An ethernet connection. +} seaio_mode_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The current baud rate used by a RTU type module. +/// If the module is TCP type, then BR9600, the default, will be used. +/// Note these are not the same values used by the termios library. +// ---------------------------------------------------------------------------- +typedef enum +{ + BRNONE = 0, ///< Default value, no connection, or unkown baud rate. + BR1200 = 1, ///< 1200 baud. + BR2400 = 2, ///< 2400 baud. + BR4800 = 3, ///< 4800 baud. + BR9600 = 4, ///< 9600 baud. + BR14400 = 5, ///< 14400 baud. + BR19200 = 6, ///< 19200 baud. + BR28800 = 7, ///< 28800 baud. + BR38400 = 8, ///< 38400 baud. + BR57600 = 9, ///< 57600 baud. + BR115200 = 10 ///< 115200 baud. +} baud_rates_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The currently used parity. +/// Parity is a quick and simple method of checking for errors. It doesn't +/// work all the time, but it is very simple to implement. +// ---------------------------------------------------------------------------- +typedef enum +{ + P_NONE = 0, ///< No parity (Default). + P_ODD = 1, ///< Odd parity. + P_EVEN = 2 ///< Even parity. +} parity_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The type of read / write to preform. +/// Note that not all types can be written. For example an attempt to write to +/// D_INPUTS or INPUTREG would cause an EINVAL error. Also you can not directly +/// write to SETUPREGS, you must use an appropriate Ioctl. +// ---------------------------------------------------------------------------- +typedef enum +{ + COILS = 1, ///< Coils are any relay type outputs. + D_INPUTS = 2, ///< Digitial inputs. Single bit inputs. + HOLDINGREG = 3, ///< Configuration registers. + INPUTREG = 4, ///< Registers only used on A/D type devices. + SETUPREG = 5, ///< Advanced device configuration registers. + SEAMAXPIO = 6 ///< Programmable type I/O. +} seaio_type_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \ingroup group_seamax_all +/// \brief The type of IOCTL operation desired. +/// Read the manual carefully when using these. There are some specific +/// methods that must be followed to use correctly. +// ---------------------------------------------------------------------------- +typedef enum +{ + IOCTL_READ_COMM_PARAM = 1, ///< Read communication parameters. + IOCTL_SET_ADDRESS = 2, ///< Set device slave ID. + IOCTL_SET_COMM_PARAM = 3, ///< Set communication parameters. + IOCTL_GET_PIO = 4, ///< Get direction of programmable I/O. + IOCTL_SET_PIO = 5, ///< Set direction of programmable I/O. + IOCTL_GET_ADDA_CONFIG = 6, ///< Get A/D configuration information. + IOCTL_SET_ADDA_CONFIG = 7, ///< Set the A/D configuration. + IOCTL_GET_EXT_CONFIG = 8, ///< Extended module id (SeaDAC). + IOCTL_GET_ADDA_EXT_CONFIG = 9, ///< Information about D/A jumpers. +} IOCTL_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief 48 Bit pio configuration. +/// This struct is contained within the \a SeaMAX_PIO_ioctl_s struct. It is +/// used whenever retrieving or setting port direction on a PIO device with +/// 48 bits of I/O. +// ---------------------------------------------------------------------------- +typedef struct PIO48_config_s +{ + unsigned char channel1; ///< Bits 0-5 map ports 1-6. (0:O, 1:I) +} PIO48_config_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief 96 Bit pio configuration. +/// This struct is contained within the \a SeaMAX_PIO_ioctl_s struct. It is +/// used whenever retrieving or setting port direction on a PIO device with +/// 96 bits of I/O. +// ---------------------------------------------------------------------------- +typedef struct PIO96_config_s +{ + unsigned char channel1; ///< Bits 0-5 map ports 1-6. (0:O, 1:I) + unsigned char channel2; ///< Bits 0-5 map ports 7-12. (0:O, 1:I) +} PIO96_config_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief This struct is used to set the address of a particular device. +/// In this way, it becomes unnecessary to manually turn the screw terminal to +/// configure a particular SeaIO device. It also allows for more devices than +/// the physically selectable 15 addresses. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_address_s +{ + unsigned char new_address; ///< Address value from 1 to 247. +} seaio_ioctl_address_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief Communication parameters (desired) struct. +/// This struct can be used to set a desired communication configuration. +/// Note that you must first call get params before you attempt to set params, +/// or it will fail. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_comms_s +{ + baud_rates_t new_baud_rate; ///< Desire baud rate (/a baud_rates_t). + parity_t new_parity; ///< Desire parity (/a parity_t). +} seaio_ioctl_comms_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief Communication parameters (current) struct. +/// This struct can be used to store the current communication parameters. +/// Note that you will have call get params before you may set a configuration, +/// or it will fail. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_get_params_s +{ + unsigned short model; ///< Device model number (410, 462, ...) + unsigned char bridge_type; ///< Bridge type (M, E, U, S, or N). + baud_rates_t baud_rate; ///< The device's communication baud rate. + parity_t parity; ///< The device's communication parity. + unsigned char magic_cookie; ///< \internal Multithread saftey. +} seaio_ioctl_get_params_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief PIO data/setup struct. +/// This struct can be used to read data from a PIO device, or configure a PIO +/// device. +// ---------------------------------------------------------------------------- +typedef struct SeaMAX_PIO_ioctl_s +{ + unsigned short model; ///< Device model number (462, 463, ...) + union + { + PIO48_config_s PIO48; ///< PIO directions /a PIO48_config_s + PIO96_config_s PIO96; ///< PIO directions /a PIO96_config_s + } config_state; +} SeaMAX_PIO_ioctl_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief PIO data/setup struct. +/// This struct can be used to read data from a PIO device, or configure a PIO +/// device. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_ext_config +{ + unsigned short model; ///< Device model number (SeaDAC) +} seaio_ioctl_ext_config; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The IOCTL struct used in the majority of the IOCTL calls. +/// Every call except the three involving A/D and D/A converters use this +/// struct. This struct is actually the union of several smaller structs, so +/// that it can be used multiple times. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_s +{ + union + { + seaio_ioctl_address_s address; ///< IOCTL_SET_ADDRESS + seaio_ioctl_comms_s comms; ///< IOCTL_READ_COMM_PARAM + seaio_ioctl_get_params_s params; ///< IOCTL_SET_COMM_PARAM + SeaMAX_PIO_ioctl_s pio; ///< IOCTL_GET/SET_PIO + seaio_ioctl_ext_config config; ///< IOCTL_GET_EXT_CONFIG + } u; ///< Keep size down to largest struct inside. +} seaio_ioctl_s; + +// ---------------------------------------------------------------------------- +// | ADDA structs and types. | +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief ADDA conversion range configuration type. +/// This is the range of voltages that the A/D will convert into values from +/// 0x000 to 0xFFF (0-4095). Plus to minus conversions do use a sign bit, so +/// 4095 is not necessarily the highest value. +// ---------------------------------------------------------------------------- +typedef enum +{ + ZERO_TO_FIVE = 0, ///< 0-5V (0x000-0xFFF) + PLS_MIN_FIVE = 1, ///< -5-5V (0x800-0x7FF) + ZERO_TO_TEN = 2, ///< 0-10V (0x000-0xFFF) + PLS_MIN_TEN = 3 ///< -10-10V (0x800-0x7FF) +} channel_range_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// ADDA mode configuration type. +/// This is how the board is physically configured to read Analog signals. The +/// way to measure. You can either measure 16 signals with a single common +/// ground, 8 isolated signals, or the current pulled through internal resistors +/// from 8 separate signals. +// ---------------------------------------------------------------------------- +typedef enum +{ + SINGLE_ENDED = 0, ///< 16 common ground channels. + DIFFERENTIAL = 1, ///< 8 differential channels. + CURRENT_LOOP = 2 ///< 8 current loop measurements. +} channel_mode_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief ADDA reference type configuration. +/// This controls the mux that is in charge of input to the single A/D chip on +/// an A/D capable device. This provides some small A/D diagnostics if you +/// desire to use them. +// ---------------------------------------------------------------------------- +typedef enum +{ + ANALOG_OFFSET = 0, ///< The A/D inputs available on the device. + GND_OFFSET = 1, ///< A ground value. Should always read 0V. + AD_REF_OFFSET = 2, ///< A/D reference value. Should always read 0V. + DA_CHANNEL_1 = 4, ///< D/A channel one as input. + DA_CHANNEL_2 = 8 ///< D/A channel two as input. +} ad_reference_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The ADDA data struct used in the ADDA ioctl calls. +/// Contains information about device configuration. +// ---------------------------------------------------------------------------- +typedef struct adda_config +{ + /// Overall device settings. + struct + { + unsigned char reference_offset; ///< A/D Mux address. + unsigned char channel_mode; ///< Measurement mode. + + } device; + + /// Each channel uses 2 bits for configuration. + /// Each of the bytes in this struct uses the lowest + /// two bits for each channel configuration. + struct + { + unsigned char ch_1; + unsigned char ch_2; + unsigned char ch_3; + unsigned char ch_4; + unsigned char ch_5; + unsigned char ch_6; + unsigned char ch_7; + unsigned char ch_8; + unsigned char ch_9; + unsigned char ch_10; + unsigned char ch_11; + unsigned char ch_12; + unsigned char ch_13; + unsigned char ch_14; + unsigned char ch_15; + unsigned char ch_16; + + } channels; +} adda_config; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief Data struct returned by get ext adda ioctl. +/// Contains information about the physical jumper configuration of the device. +// ---------------------------------------------------------------------------- +typedef struct adda_ext_config +{ + unsigned char ad_multiplier_enabled; ///< A/D amplifier. + + channel_range_type da_channel_1_range; ///< D/A1 range. + channel_range_type da_channel_2_range; ///< D/A2 range +} adda_ext_config; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief SeaDAC Lite range configuration type. +/// This is the range of available SeaDAC products +// ---------------------------------------------------------------------------- +typedef enum +{ + SDL_8111 = 0x8111, ///< 4 inputs and 4 reed outputs + SDL_8112, ///< 4 inputs and 4 form-c outputs + SDL_8113, ///< 4 inputs + SDL_8114, ///< 4 reed outputs + SDL_8115, ///< 4 form-c outputs + SDL_8126 = 0x8126 ///< 32 TTL I/O +} sdl_range_type; + +typedef enum +{ + SCL = 0x01, SDA = 0x02, TDO = 0x04, CS = 0x08, + GPIO_0 = 0x01, GPIO_1 = 0x02, GPIO_2 = 0x04, GPIO_3 = 0x08, + GPIO_4 = 0x10, GPIO_5 = 0x20, GPIO_6 = 0x40, GPIO_7 = 0x80 +} sdl_i2c_type; + +// ---------------------------------------------------------------------------- +// SeaMaxModule struct. +// This structure is used internally to keep track of a module that open() has +// been called on. +// ---------------------------------------------------------------------------- +typedef struct seaMaxModule +{ + int throttle; //Throttling delay for RTU mode. + seaio_mode_t commMode; //Communication medium (RTU or TCP). + HANDLE hDevice; //Device comm interface. + int mutex; //Multithread (force sequential). + struct termios *initalConfig; //Original serial configuration. + struct ftdi_context ftdic; //For SeaDAC Lite modules + int deviceType; + +} seaMaxModule; + +// ---------------------------------------------------------------------------- +// | private prototypes | +// ---------------------------------------------------------------------------- +int InitializeI2C(seaMaxModule*); +void ExecuteQueue(seaMaxModule*); +void InitializeQueue(void); +void ExecuteQueue(seaMaxModule*); +void ReadRegister(unsigned char, unsigned char, unsigned char*); +void WriteRegister(unsigned char, unsigned char, unsigned char); +void SetGPIO(unsigned char, unsigned char); + +// ---------------------------------------------------------------------------- +// | API prototypes | +// ---------------------------------------------------------------------------- + +SeaMaxLin *SeaMaxLinCreate(void); +int SeaMaxLinDestroy(SeaMaxLin *SeaMaxPointer); +int SeaMaxLinOpen(SeaMaxLin *SeaMaxPointer, char *filename); +int SeaMaxLinClose(SeaMaxLin *SeaMaxPointer); + +int SeaMaxLinRead(SeaMaxLin *SeaMaxPointer, slave_address_t slaveId, + seaio_type_t type, address_loc_t starting_address, + address_range_t range, void *data); + +int SeaDacLinRead(SeaMaxLin *SeaMaxPointer, unsigned char *data, + int numBytes); + +int SeaMaxLinWrite(SeaMaxLin *SeaMaxPointer, slave_address_t slaveId, + seaio_type_t type, address_loc_t starting_address, + address_range_t range, unsigned char *data); + +int SeaDacLinWrite(SeaMaxLin *SeaMaxPointer, unsigned char *data, + int numBytes); + +int SeaMaxLinIoctl(SeaMaxLin *SeaMaxPointer, slave_address_t slaveId, + IOCTL_t which, void *data); + +int SeaMaxLinSetIMDelay(SeaMaxLin *SeaMaxPointer, int delay); + +int SeaDacGetPIO(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +int SeaDacSetPIO(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +int SeaDacSetPIODirection(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +int SeaDacGetPIODirection(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +HANDLE SeaMaxLinGetCommHandle(SeaMaxLin *SeaMaxPointer); + + + +// ---------------------------------------------------------------------------- +// | End of C library function calls. | +// ---------------------------------------------------------------------------- +#ifdef __cplusplus + } + +class CSeaMaxLin { +public: + + CSeaMaxLin(void); + ~CSeaMaxLin(void); + int Open(char *filename); + int Close(void); + + int Read(slave_address_t slaveId, seaio_type_t type, + address_loc_t starting_address, address_range_t range, + void *data); + + int Read(unsigned char *data, int length); + + int Write(slave_address_t slaveId, seaio_type_t type, + address_loc_t starting_address, + address_range_t range, unsigned char *data); + + int Write(unsigned char *data, int length); + + int Ioctl(slave_address_t slaveId, IOCTL_t which, void *data); + + int set_intermessage_delay(int delay); + + int GetPIO(unsigned char* data); + + int SetPIO(unsigned char* data); + + int SetPIODirection(unsigned char* data); + + int GetPIODirection(unsigned char* data); + + HANDLE getCommHandle(void); + +private: + SeaMaxLin *SeaMaxPointer; +}; + +#endif //__cplusplus +#endif //SEAMAXLIN_H__ diff --git a/SeaMaxLinux/thirdparty/ftdi.h b/SeaMaxLinux/thirdparty/ftdi.h new file mode 100644 index 0000000..45fb907 --- /dev/null +++ b/SeaMaxLinux/thirdparty/ftdi.h @@ -0,0 +1,356 @@ +/*************************************************************************** + ftdi.h - description + ------------------- + begin : Fri Apr 4 2003 + copyright : (C) 2003 by Intra2net AG + email : opensource@intra2net.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License * + * version 2.1 as published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef __libftdi_h__ +#define __libftdi_h__ + +#include + +#define FTDI_DEFAULT_EEPROM_SIZE 128 + +/** FTDI chip type */ +enum ftdi_chip_type { TYPE_AM=0, TYPE_BM=1, TYPE_2232C=2, TYPE_R=3, TYPE_2232H=4, TYPE_4232H=5 }; +/** Parity mode for ftdi_set_line_property() */ +enum ftdi_parity_type { NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4 }; +/** Number of stop bits for ftdi_set_line_property() */ +enum ftdi_stopbits_type { STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2 }; +/** Number of bits for ftdi_set_line_property() */ +enum ftdi_bits_type { BITS_7=7, BITS_8=8 }; +/** Break type for ftdi_set_line_property2() */ +enum ftdi_break_type { BREAK_OFF=0, BREAK_ON=1 }; + +/** MPSSE bitbang modes */ +enum ftdi_mpsse_mode +{ + BITMODE_RESET = 0x00, + BITMODE_BITBANG= 0x01, + BITMODE_MPSSE = 0x02, + BITMODE_SYNCBB = 0x04, + BITMODE_MCU = 0x08, + /* CPU-style fifo mode gets set via EEPROM */ + BITMODE_OPTO = 0x10, + BITMODE_CBUS = 0x20 +}; + +/** Port interface for FT2232C */ +enum ftdi_interface +{ + INTERFACE_ANY = 0, + INTERFACE_A = 1, + INTERFACE_B = 2, + INTERFACE_C = 3, + INTERFACE_D = 4 +}; + +/* Shifting commands IN MPSSE Mode*/ +#define MPSSE_WRITE_NEG 0x01 /* Write TDI/DO on negative TCK/SK edge*/ +#define MPSSE_BITMODE 0x02 /* Write bits, not bytes */ +#define MPSSE_READ_NEG 0x04 /* Sample TDO/DI on negative TCK/SK edge */ +#define MPSSE_LSB 0x08 /* LSB first */ +#define MPSSE_DO_WRITE 0x10 /* Write TDI/DO */ +#define MPSSE_DO_READ 0x20 /* Read TDO/DI */ +#define MPSSE_WRITE_TMS 0x40 /* Write TMS/CS */ + +/* FTDI MPSSE commands */ +#define SET_BITS_LOW 0x80 +/*BYTE DATA*/ +/*BYTE Direction*/ +#define SET_BITS_HIGH 0x82 +/*BYTE DATA*/ +/*BYTE Direction*/ +#define GET_BITS_LOW 0x81 +#define GET_BITS_HIGH 0x83 +#define LOOPBACK_START 0x84 +#define LOOPBACK_END 0x85 +#define TCK_DIVISOR 0x86 +/* Value Low */ +/* Value HIGH */ /*rate is 12000000/((1+value)*2) */ +#define DIV_VALUE(rate) (rate > 6000000)?0:((6000000/rate -1) > 0xffff)? 0xffff: (6000000/rate -1) + +/* Commands in MPSSE and Host Emulation Mode */ +#define SEND_IMMEDIATE 0x87 +#define WAIT_ON_HIGH 0x88 +#define WAIT_ON_LOW 0x89 + +/* Commands in Host Emulation Mode */ +#define READ_SHORT 0x90 +/* Address_Low */ +#define READ_EXTENDED 0x91 +/* Address High */ +/* Address Low */ +#define WRITE_SHORT 0x92 +/* Address_Low */ +#define WRITE_EXTENDED 0x93 +/* Address High */ +/* Address Low */ + +/* Definitions for flow control */ +#define SIO_RESET 0 /* Reset the port */ +#define SIO_MODEM_CTRL 1 /* Set the modem control register */ +#define SIO_SET_FLOW_CTRL 2 /* Set flow control register */ +#define SIO_SET_BAUD_RATE 3 /* Set baud rate */ +#define SIO_SET_DATA 4 /* Set the data characteristics of the port */ + +#define FTDI_DEVICE_OUT_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT) +#define FTDI_DEVICE_IN_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN) + +/* Requests */ +#define SIO_RESET_REQUEST SIO_RESET +#define SIO_SET_BAUDRATE_REQUEST SIO_SET_BAUD_RATE +#define SIO_SET_DATA_REQUEST SIO_SET_DATA +#define SIO_SET_FLOW_CTRL_REQUEST SIO_SET_FLOW_CTRL +#define SIO_SET_MODEM_CTRL_REQUEST SIO_MODEM_CTRL +#define SIO_POLL_MODEM_STATUS_REQUEST 0x05 +#define SIO_SET_EVENT_CHAR_REQUEST 0x06 +#define SIO_SET_ERROR_CHAR_REQUEST 0x07 +#define SIO_SET_LATENCY_TIMER_REQUEST 0x09 +#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A +#define SIO_SET_BITMODE_REQUEST 0x0B +#define SIO_READ_PINS_REQUEST 0x0C +#define SIO_READ_EEPROM_REQUEST 0x90 +#define SIO_WRITE_EEPROM_REQUEST 0x91 +#define SIO_ERASE_EEPROM_REQUEST 0x92 + + +#define SIO_RESET_SIO 0 +#define SIO_RESET_PURGE_RX 1 +#define SIO_RESET_PURGE_TX 2 + +#define SIO_DISABLE_FLOW_CTRL 0x0 +#define SIO_RTS_CTS_HS (0x1 << 8) +#define SIO_DTR_DSR_HS (0x2 << 8) +#define SIO_XON_XOFF_HS (0x4 << 8) + +#define SIO_SET_DTR_MASK 0x1 +#define SIO_SET_DTR_HIGH ( 1 | ( SIO_SET_DTR_MASK << 8)) +#define SIO_SET_DTR_LOW ( 0 | ( SIO_SET_DTR_MASK << 8)) +#define SIO_SET_RTS_MASK 0x2 +#define SIO_SET_RTS_HIGH ( 2 | ( SIO_SET_RTS_MASK << 8 )) +#define SIO_SET_RTS_LOW ( 0 | ( SIO_SET_RTS_MASK << 8 )) + +#define SIO_RTS_CTS_HS (0x1 << 8) + +/* marker for unused usb urb structures + (taken from libusb) */ +#define FTDI_URB_USERCONTEXT_COOKIE ((void *)0x1) + +/** + \brief Main context structure for all libftdi functions. + + Do not access directly if possible. +*/ +struct ftdi_context +{ + /* USB specific */ + /** libusb's usb_dev_handle */ + struct usb_dev_handle *usb_dev; + /** usb read timeout */ + int usb_read_timeout; + /** usb write timeout */ + int usb_write_timeout; + + /* FTDI specific */ + /** FTDI chip type */ + enum ftdi_chip_type type; + /** baudrate */ + int baudrate; + /** bitbang mode state */ + unsigned char bitbang_enabled; + /** pointer to read buffer for ftdi_read_data */ + unsigned char *readbuffer; + /** read buffer offset */ + unsigned int readbuffer_offset; + /** number of remaining data in internal read buffer */ + unsigned int readbuffer_remaining; + /** read buffer chunk size */ + unsigned int readbuffer_chunksize; + /** write buffer chunk size */ + unsigned int writebuffer_chunksize; + + /* FTDI FT2232C requirecments */ + /** FT2232C interface number: 0 or 1 */ + int interface; /* 0 or 1 */ + /** FT2232C index number: 1 or 2 */ + int index; /* 1 or 2 */ + /* Endpoints */ + /** FT2232C end points: 1 or 2 */ + int in_ep; + int out_ep; /* 1 or 2 */ + + /** Bitbang mode. 1: (default) Normal bitbang mode, 2: FT2232C SPI bitbang mode */ + unsigned char bitbang_mode; + + /** EEPROM size. Default is 128 bytes for 232BM and 245BM chips */ + int eeprom_size; + + /** String representation of last error */ + char *error_str; + + /** Buffer needed for async communication */ + char *async_usb_buffer; + /** Number of URB-structures we can buffer */ + unsigned int async_usb_buffer_size; +}; + +/** + \brief list of usb devices created by ftdi_usb_find_all() +*/ +struct ftdi_device_list +{ + /** pointer to next entry */ + struct ftdi_device_list *next; + /** pointer to libusb's usb_device */ + struct usb_device *dev; +}; + +/** + \brief FTDI eeprom structure +*/ +struct ftdi_eeprom +{ + /** vendor id */ + int vendor_id; + /** product id */ + int product_id; + + /** self powered */ + int self_powered; + /** remote wakeup */ + int remote_wakeup; + /** chip type */ + int BM_type_chip; + + /** input in isochronous transfer mode */ + int in_is_isochronous; + /** output in isochronous transfer mode */ + int out_is_isochronous; + /** suspend pull downs */ + int suspend_pull_downs; + + /** use serial */ + int use_serial; + /** fake usb version */ + int change_usb_version; + /** usb version */ + int usb_version; + /** maximum power */ + int max_power; + + /** manufacturer name */ + char *manufacturer; + /** product name */ + char *product; + /** serial number */ + char *serial; + + /** eeprom size in bytes. This doesn't get stored in the eeprom + but is the only way to pass it to ftdi_eeprom_build. */ + int size; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + + int ftdi_init(struct ftdi_context *ftdi); + struct ftdi_context *ftdi_new(); + int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface interface); + + void ftdi_deinit(struct ftdi_context *ftdi); + void ftdi_free(struct ftdi_context *ftdi); + void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usbdev); + + int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devlist, + int vendor, int product); + void ftdi_list_free(struct ftdi_device_list **devlist); + void ftdi_list_free2(struct ftdi_device_list *devlist); + int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct usb_device *dev, + char * manufacturer, int mnf_len, + char * description, int desc_len, + char * serial, int serial_len); + + int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product); + int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, + const char* description, const char* serial); + int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev); + + int ftdi_usb_close(struct ftdi_context *ftdi); + int ftdi_usb_reset(struct ftdi_context *ftdi); + int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi); + int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi); + int ftdi_usb_purge_buffers(struct ftdi_context *ftdi); + + int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate); + int ftdi_set_line_property(struct ftdi_context *ftdi, enum ftdi_bits_type bits, + enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity); + int ftdi_set_line_property2(struct ftdi_context *ftdi, enum ftdi_bits_type bits, + enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity, + enum ftdi_break_type break_type); + + int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size); + int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); + int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); + + int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size); + int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); + int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); + + int ftdi_write_data_async(struct ftdi_context *ftdi, unsigned char *buf, int size); + void ftdi_async_complete(struct ftdi_context *ftdi, int wait_for_more); + + int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask); + int ftdi_disable_bitbang(struct ftdi_context *ftdi); + int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode); + int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins); + + int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency); + int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency); + + int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status); + + /* flow control */ + int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl); + int ftdi_setdtr_rts(struct ftdi_context *ftdi, int dtr, int rts); + int ftdi_setdtr(struct ftdi_context *ftdi, int state); + int ftdi_setrts(struct ftdi_context *ftdi, int state); + + int ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable); + int ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable); + + /* set eeprom size */ + void ftdi_eeprom_setsize(struct ftdi_context *ftdi, struct ftdi_eeprom *eeprom, int size); + + /* init and build eeprom from ftdi_eeprom structure */ + void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom); + int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output); + int ftdi_eeprom_decode(struct ftdi_eeprom *eeprom, unsigned char *output, int size); + + /* "eeprom" needs to be valid 128 byte eeprom (generated by the eeprom generator) + the checksum of the eeprom is valided */ + int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid); + int ftdi_read_eeprom_getsize(struct ftdi_context *ftdi, unsigned char *eeprom, int maxsize); + int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_erase_eeprom(struct ftdi_context *ftdi); + + char *ftdi_get_error_string(struct ftdi_context *ftdi); + +#ifdef __cplusplus +} +#endif + +#endif /* __libftdi_h__ */ diff --git a/StartZT b/StartZT new file mode 100755 index 0000000..1180723 --- /dev/null +++ b/StartZT @@ -0,0 +1,50 @@ +#!/bin/bash +# + +DELAY=15 +DIR=/home/zonetest/ZT +NAME=ZT +START=./ZT +LOGFILE=./LOG/CrashReport.txt +ESCAPEFILE=./Escape.ZT +OUTPUTCONSOLE=/dev/tty1 + +cd $DIR + +echo "Starting ZT for the first time" > $OUTPUTCONSOLE +#echo "Checking for escape file" > $OUTPUTCONSOLE + +if [ -e "$ESCAPEFILE" ]; then + #echo "Deleting escape file" > $OUTPUTCONSOLE + rm -f $ESCAPEFILE +fi + +$START > $OUTPUTCONSOLE 2>&1 & + +sleep 30 + +while true ; do + +if [ -e "$ESCAPEFILE" ]; then + echo "Escaping script" > $OUTPUTCONSOLE + exit +fi + +case "$(pidof $NAME | wc -w)" in + +0) echo "ZT crashed $(date)" >> $LOGFILE + echo "ZT crashed $(date). Restarting" > $OUTPUTCONSOLE + $START > /dev/tty1 2>&1 & + ;; +1) # all ok +# echo "Running" + ;; +*) # echo "double" + # kill $(pidof amadeus.x86 | awk '{print $1}') + ;; +esac + + sleep $DELAY +done + +exit diff --git a/ZT b/ZT new file mode 100755 index 0000000..e5e2cfb Binary files /dev/null and b/ZT differ diff --git a/ZT.pro b/ZT.pro new file mode 100644 index 0000000..4ccbfcb --- /dev/null +++ b/ZT.pro @@ -0,0 +1,296 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-12-06T09:47:25 +# +#------------------------------------------------- + +QT += core gui +QT += network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ZT +TEMPLATE = app + + +SOURCES += \ + sources/main.cpp \ + sources/MainPanel.cpp \ + sources/Station.cpp \ + sources/ZTconfigmgr.cpp \ + sources/Zonetest.cpp \ + sources/EngLog.cpp \ + sources/GuiElements/GuiPage.cpp \ + sources/GuiElements/WelcomePage.cpp \ + sources/GuiElements/SimpleTextBoxWidget.cpp \ + sources/Stations/Angrignon.cpp \ + sources/Stations/HonoreBeaugrand.cpp \ + sources/Stations/HenriBourassa.cpp \ + sources/Stations/CoteVertu.cpp \ + sources/Stations/BerriUQAM.cpp \ + sources/Stations/Longueuil.cpp \ + sources/Stations/SaintMichel.cpp \ + sources/Stations/Snowdon.cpp \ + sources/Stations/Montmorency.cpp \ + sources/GuiElements/ZTPage.cpp \ + sources/LazerProbe.cpp \ + sources/LazerProbesMgr.cpp \ + sources/ZTLog.cpp \ + sources/GuiElements/PushButton.cpp \ + sources/ZTStateMachine.cpp \ + sources/ZTData.cpp \ + sources/Simulator/ZTSimulator.cpp \ + sources/GuiElements/CDVItem.cpp \ + sources/IOManager.cpp \ + sources/IOModule.cpp \ + sources/InputModule.cpp \ + sources/OutputModule.cpp \ + sources/MixedModule.cpp \ + sources/Simulator/SimulatorIOManager.cpp \ + sources/Simulator/SimulatorInputModule.cpp \ + sources/Simulator/SImulatorOutputModule.cpp \ + sources/Simulator/SimulatorMixedModule.cpp \ + sources/CDV.cpp \ + sources/AbstractLazerProbeMgr.cpp \ + sources/AbstractLazerProbe.cpp \ + sources/Simulator/SimulatorLazerProbe.cpp \ + sources/Simulator/SimulatorLazerProbesMgr.cpp \ + sources/PCIIOMgr.cpp \ + sources/Simulator/SimulatorPCIIO.cpp \ + sources/GuiElements/ToggleTextButtonWidget.cpp \ + sources/GuiElements/TextButtonWidget.cpp \ + sources/ZT1AnalysisThread.cpp \ + sources/GuiElements/StatusBar.cpp \ + sources/GuiElements/ZT1EquipmentWidget.cpp \ + sources/GuiElements/ZT1StatsZone.cpp \ + sources/Simulator/SimulationScenario.cpp \ + sources/GuiElements/OptionsPage.cpp \ + sources/GuiElements/FunctionSelectionPage.cpp \ + sources/GuiElements/ToggleButtonWidget.cpp \ + sources/GuiElements/EventsBar.cpp \ + sources/GuiElements/EventItem.cpp \ + sources/Event.cpp \ + sources/EventMgr.cpp \ + sources/TrainLogFileMgr.cpp \ + sources/LogMgr.cpp \ + sources/GuiElements/LogsListPage.cpp \ + sources/GuiElements/LogViewPage.cpp \ + sources/GuiElements/GraphItem.cpp \ + sources/GuiElements/GraphCursorWidget.cpp \ + sources/GuiElements/GraphRulerWidget.cpp \ + sources/GuiElements/AnalogGraphItem.cpp \ + sources/ZTSettings.cpp \ + sources/GuiElements/ZT2EquipmentWidget.cpp \ + sources/ZT2AnalysisThread.cpp \ + sources/GuiElements/ZT2StatsZone.cpp \ + sources/TKGenerator.cpp \ + sources/GuiElements/LedWidget.cpp \ + sources/GuiElements/RankRulerWidget.cpp \ + sources/GuiElements/EngineeringPage.cpp \ + sources/GuiElements/PasswordPrompt.cpp \ + sources/GuiElements/EventsRulerWidget.cpp \ + sources/USBDriveInterface.cpp \ + sources/GuiElements/MaintenancePage.cpp \ + sources/Simulator/SimulatorThread.cpp \ + sources/GuiElements/GeneralSettingsPage.cpp \ + sources/GuiElements/ONOFFStatusWidget.cpp \ + sources/GuiElements/ZTLogViewerPage.cpp \ + sources/SwitchCDV.cpp \ + sources/GuiElements/SwitchCDVItem.cpp \ + sources/RamMonitor.cpp \ + sources/ExtIOThread.cpp \ + sources/NetworkManager.cpp \ + sources/TCPProtocol.cpp \ + sources/ExtModules/DI710Driver.cpp \ + sources/AnalogInputModule.cpp \ + sources/PCIIO/PCI1756Interface.cpp \ + sources/ExtModules/USB4704Interface.cpp \ + sources/Stations/Montmorency1012.cpp \ + sources/Stations/Montmorency1022.cpp \ + sources/WatchdogCtrl.cpp \ + sources/TKTransportInterface.cpp \ + sources/DiscreteTKTransport.cpp \ + sources/Modbus/ModbusBackend.cpp \ + sources/Modbus/ModbusMaster.cpp \ + sources/Modbus/ModbusRepository.cpp \ + sources/Modbus/ModbusCCMgr.cpp \ + sources/Modbus/ModbusTKTransport.cpp + +HEADERS += \ + sources/MainPanel.h \ + sources/GlobalDefine.h \ + sources/Station.h \ + sources/ExtModules/Externaliomodule.h \ + sources/ExtModules/Seaio430driver.h \ + sources/ExtModules/Seaio440driver.h \ + sources/ExtModules/Seaio470driver.h \ + sources/ZTconfigmgr.h \ + sources/Zonetest.h \ + sources/ExtModules/Seaiolibinterface.h \ + sources/PCIIO/Comedilibinterface.h \ + sources/PCIIO/PCI1756Definitions.h \ + sources/EngLog.h \ + sources/GuiElements/Guipage.h \ + sources/GuiElements/WelcomePage.h \ + sources/GuiElements/SimpleTextBoxWidget.h \ + sources/Stations/Angrignon.h \ + sources/Stations/HonoreBeaugrand.h \ + sources/Stations/HenriBourassa.h \ + sources/Stations/CoteVertu.h \ + sources/Stations/BerriUQAM.h \ + sources/Stations/Longueuil.h \ + sources/Stations/SaintMichel.h \ + sources/Stations/Snowdon.h \ + sources/Stations/Montmorency.h \ + sources/GuiElements/ZTPage.h \ + sources/LazerProbe.h \ + sources/LazerProbesMgr.h \ + sources/ZTLog.h \ + sources/GuiElements/PushButton.h \ + sources/ZTStateMachine.h \ + sources/ZTData.h \ + sources/Simulator/ZTSimulator.h \ + sources/GuiElements/CDVItem.h \ + sources/ExtModules/ExternalIOMgr.h \ + sources/IOManager.h \ + sources/IOModule.h \ + sources/InputModule.h \ + sources/OutputModule.h \ + sources/MixedModule.h \ + sources/Simulator/SimulatorIOManager.h \ + sources/Simulator/SimulatorInputModule.h \ + sources/Simulator/SImulatorOutputModule.h \ + sources/Simulator/SimulatorMixedModule.h \ + sources/CDV.h \ + sources/AbstractLazerProbeMgr.h \ + sources/AbstractLazerProbe.h \ + sources/Simulator/SimulatorLazerProbe.h \ + sources/Simulator/SimulatorLazerProbesMgr.h \ + sources/PCIIOMgr.h \ + sources/Simulator/SimulatorPCIIO.h \ + sources/GuiElements/ToggleTextButtonWidget.h \ + sources/GuiElements/TextButtonWidget.h \ + sources/ZT1AnalysisThread.h \ + sources/GuiElements/StatusBar.h \ + sources/GuiElements/ZT1EquipmentWidget.h \ + sources/GuiElements/ZT1StatsZone.h \ + sources/Simulator/SimulationScenario.h \ + sources/GuiElements/OptionsPage.h \ + sources/GuiElements/FunctionSelectionPage.h \ + sources/GuiElements/ToggleButtonWidget.h \ + sources/GuiElements/EventsBar.h \ + sources/GuiElements/EventItem.h \ + sources/Event.h \ + sources/EventMgr.h \ + sources/TrainLogFileMgr.h \ + sources/LogMgr.h \ + sources/GuiElements/LogsListPage.h \ + sources/GuiElements/LogViewPage.h \ + sources/GuiElements/GraphItem.h \ + sources/GuiElements/GraphCursorWidget.h \ + sources/GuiElements/GraphRulerWidget.h \ + sources/GuiElements/AnalogGraphItem.h \ + sources/ZTSettings.h \ + sources/GuiElements/ZT2EquipmentWidget.h \ + sources/ZT2AnalysisThread.h \ + sources/GuiElements/ZT2StatsZone.h \ + sources/TKGenerator.h \ + sources/GuiElements/LedWidget.h \ + sources/GuiElements/RankRulerWidget.h \ + sources/GuiElements/EngineeringPage.h \ + sources/GuiElements/PasswordPrompt.h \ + sources/GuiElements/EventsRulerWidget.h \ + sources/USBDriveInterface.h \ + sources/GuiElements/MaintenancePage.h \ + sources/Simulator/SimulatorThread.h \ + sources/GuiElements/GeneralSettingsPage.h \ + sources/ZTVersion.h \ + sources/GuiElements/ONOFFStatusWidget.h \ + sources/GuiElements/ZTLogViewerPage.h \ + sources/SwitchCDV.h \ + sources/GuiElements/SwitchCDVItem.h \ + sources/RamMonitor.h \ + sources/ExtIOThread.h \ + sources/NetworkManager.h \ + sources/TCPProtocol.h \ + sources/ExtModules/DI710Driver.h \ + sources/AnalogInputModule.h \ + sources/PCIIO/PCI1756Interface.h \ + sources/ExtModules/USB4704Definitions.h \ + sources/ExtModules/USB4704Interface.h \ + sources/Stations/Montmorency1012.h \ + sources/Stations/Montmorency1022.h \ + sources/WatchdogCtrl.h \ + sources/TKTransportInterface.h \ + sources/DiscreteTKTransport.h \ + sources/Modbus/ModbusBackend.h \ + sources/Modbus/ModbusMaster.h \ + sources/Modbus/ModbusRepository.h \ + sources/Modbus/ModbusCCMgr.h \ + sources/Modbus/ModbusCCDefs.h \ + sources/Modbus/ModbusTKTransport.h + +#QMAKE_LIBDIR += ./ExtLib +#QT += network + + +unix { + +SOURCES += \ + sources/ExtModules/Externaliomodule.cpp \ + sources/ExtModules/Seaio430driver.cpp \ + sources/ExtModules/Seaio440driver.cpp \ + sources/ExtModules/Seaio470driver.cpp \ + sources/ExtModules/Seaiolibinterface.cpp \ + sources/PCIIO/Comedilibinterface.cpp \ + sources/ExtModules/ExternalIOMgr.cpp \ + + + DEFINES = _TTY_POSIX_ + +# La compilation et l'installation de la librairie de SeaMax crée le fichier /usr/local/lib/libseamax.a +# qui est nécessaire au fonctionnement du programme + LIBS += /usr/local/lib/libseamax.a + +# Utilisation de la librairie libCOMEDI comme interface avec la carte PCI d'entrées/sorties. + LIBS += -lcomedi + LIBS += -lbiodaq + + #La ligne ci-dessous doit être commentée lors de la compilation du projet sur le PC prototype de la ZT et elle doit être présente sur la machine virtuelle sur le PC de développement sinon la compilation ne fonctionne pas. + LIBS += -lftdi + contains(LIBS,-lftdi){ + warning("ATTENTION: La librairie FTDI est incluse. Si vous avez une erreur de compilation reliée à cette librairie (sur le PC du prototype de la ZT), commentez la ligne [ LIBS+=-lftdi ] dans le fichier ZT.pro") + } + + + LIBS += $$PWD/sources/SerialPort/libqextserialport.a + + +} + +win32 { + DEFINES += WINDOWS_OS + LIBS += $$PWD/sources/SerialPort/Win32/libqextserialport.a +} + +#DEFINES += QT_NO_DEBUG_OUTPUT + +OTHER_FILES += \ + Images/GuiBackground.jpg \ + LicTemplate.txt \ + Configuration/ZT.cfg \ + StartZT \ + GetSources.sh \ + FTPGetSources.sh + +INCLUDEPATH += $$PWD/ \ + $$PWD/SeaMaxLinux/ \ + $$PWD/sources/ExtModules/ \ + $$PWD/sources/ \ + $$PWD/sources/Stations \ + $$PWD/sources/PCIIO \ + $$PWD/sources/GuiElements \ + $$PWD/sources/SerialPort \ + $$PWD/sources/Simulator \ + $$PWD/sources/QCustomPlot \ + $$PWD/sources/Modbus diff --git a/setztexecutable b/setztexecutable new file mode 100755 index 0000000..7425e20 --- /dev/null +++ b/setztexecutable @@ -0,0 +1,3 @@ +#!/bin/bash +sudo chown root:root ZT +#sudo chmod +s ZT diff --git a/sources/AbstractLazerProbe.cpp b/sources/AbstractLazerProbe.cpp new file mode 100644 index 0000000..62bdf18 --- /dev/null +++ b/sources/AbstractLazerProbe.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme des sondes lazer (simulée ou réelle). + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "AbstractLazerProbe.h" + +CAbstractLazerProbe::CAbstractLazerProbe() +{ +} + +CAbstractLazerProbe::~CAbstractLazerProbe() +{ +} diff --git a/sources/AbstractLazerProbe.h b/sources/AbstractLazerProbe.h new file mode 100644 index 0000000..41bbb2d --- /dev/null +++ b/sources/AbstractLazerProbe.h @@ -0,0 +1,56 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ABSTRACTLAZERPROBE_H +#define ABSTRACTLAZERPROBE_H +#include + +enum eLazerProbeRxResult +{ + LAZER_PROBE_DATA_INVALID, + LAZER_PROBE_DATA_VALID +}; + +class CAbstractLazerProbe +{ +public: + CAbstractLazerProbe(); + virtual ~CAbstractLazerProbe(); + + virtual unsigned int OpenPort(QString PortName) = 0; + virtual unsigned int GetType() = 0; + virtual QString GetPortName() = 0; + virtual unsigned int GetID() = 0; + virtual unsigned int StartAcquisition() = 0; + virtual unsigned int StopAcquisition() = 0; + virtual unsigned int GetLastData() = 0; + virtual unsigned int FlushProbeData() = 0; + virtual bool IsProbeAlive() = 0; + +}; + +#endif // ABSTRACTLAZERPROBE_H diff --git a/sources/AbstractLazerProbeMgr.cpp b/sources/AbstractLazerProbeMgr.cpp new file mode 100644 index 0000000..2462fc4 --- /dev/null +++ b/sources/AbstractLazerProbeMgr.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme du gestionnaire des sondes lazer + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "AbstractLazerProbeMgr.h" + +CAbstractLazerProbeMgr::CAbstractLazerProbeMgr() +{ +} + +CAbstractLazerProbeMgr::~CAbstractLazerProbeMgr() +{ +} diff --git a/sources/AbstractLazerProbeMgr.h b/sources/AbstractLazerProbeMgr.h new file mode 100644 index 0000000..12fc57a --- /dev/null +++ b/sources/AbstractLazerProbeMgr.h @@ -0,0 +1,57 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ABSTRACTLAZERPROBEMGR_H +#define ABSTRACTLAZERPROBEMGR_H +#include "AbstractLazerProbe.h" + +enum eLazerProbesMgrRetValues +{ + LAZERPROBES_MGR_RET_OK, + LAZERPROBES_MGR_RET_PROBE_OPEN_ERROR, + LAZERPROBES_MGR_RET_INVALID_PROBE_ID +}; + +typedef enum eLazerProbeType +{ + LAZER_PROBE_TYPE_EXTERNAL, //Internal lazer probe installation + LAZER_PROBE_TYPE_INTERNAL, //External lazer probe installation + LAZER_PROBE_TYPE_INVALID +}eLazerProbeType_t; + +class CAbstractLazerProbeMgr +{ +public: + CAbstractLazerProbeMgr(); + virtual ~CAbstractLazerProbeMgr(); + + virtual unsigned int InitLazerProbes(void) = 0; + virtual CAbstractLazerProbe *GetLazerProbeHandle(eLazerProbeType_t LazerProbeType, unsigned int LazerProbeID) = 0; +// virtual unsigned int OpenExternalModules(void) = 0; +}; + +#endif // ABSTRACTLAZERPROBEMGR_H diff --git a/sources/AnalogInputModule.cpp b/sources/AnalogInputModule.cpp new file mode 100644 index 0000000..7f7485a --- /dev/null +++ b/sources/AnalogInputModule.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme des modules d'entrées/sorties externes + mixtes (SEAI/0 470). + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "AnalogInputModule.h" + +CAnalogInputModule::~CAnalogInputModule() +{ + +} diff --git a/sources/AnalogInputModule.h b/sources/AnalogInputModule.h new file mode 100644 index 0000000..b2292f3 --- /dev/null +++ b/sources/AnalogInputModule.h @@ -0,0 +1,44 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ANALOGINPUTMODULE_H +#define ANALOGINPUTMODULE_H + +#include "IOModule.h" + + +class CAnalogInputModule: public CIOModule +{ +public: + + virtual ~CAnalogInputModule(); + virtual unsigned int GetAnalogInput(int Channel, int *Data) = 0; + virtual unsigned int GetAnalogInput(int Channel, double &Data) = 0; + +}; + +#endif // ANALOGINPUTMODULE_H diff --git a/sources/CDV.cpp b/sources/CDV.cpp new file mode 100644 index 0000000..b165811 --- /dev/null +++ b/sources/CDV.cpp @@ -0,0 +1,104 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Objet CDV. Contient différents paramètres d'un CDV ainsi que son état actuel. + Utilisé pour l'interface graphique mais aussi par le state machine pour qui l'état + de certains CDV est utile. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "CDV.h" + +//TEST + +CCDV::CCDV() +{ + mCDVType = CDV_NORMAL_TYPE; + mCDVInputMask = 0; + mCDVITIMask = 0; + mIsOccupied = false; + mIsItiCommanded = false; + mCDVState = CDV_STATE_FREE; + mCDVGraphicalPosition = 0; + mCDVWay = 1; + mCDVIsDeck = false; +} + +CCDV::CCDV(unsigned int CDVITIMask, unsigned int CDVInputMask, unsigned int CDVType, QString CDVLabel, unsigned int CDVWay, unsigned int CDVGraphicalPosition) +{ + mCDVType = CDVType; + mCDVInputMask = CDVInputMask; + mCDVITIMask = CDVITIMask; + mCDVGraphicalPosition = CDVGraphicalPosition; + mCDVWay = CDVWay; + mCDVLabel = CDVLabel; + + mIsOccupied = false; + mIsItiCommanded = false; + mCDVState = CDV_STATE_FREE; + mCDVIsDeck = false; +} + +CCDV::~CCDV() +{ + +} + +unsigned int CCDV::SetInputMask(unsigned int Mask) +{ + mCDVInputMask = Mask; + + return RET_OK; +} + +unsigned int CCDV::SetLabel(QString Label) +{ + mCDVLabel = Label; + return RET_OK; +} + +unsigned int CCDV::ComputeCDVState(unsigned int InputsBuf, unsigned int ZT1ItiMask, unsigned int ZT2ItiMask) +{ + mIsOccupied = false; + mIsItiCommanded = false; + mCDVState = CDV_STATE_FREE; + + if( (((ZT1ItiMask & InputsBuf) != 0) && ((ZT1ItiMask & mCDVITIMask) != 0)) || //If there is a ZT1 itinerary commanded AND this CDV is part of itinerary + (((ZT2ItiMask & InputsBuf) != 0) && ((ZT2ItiMask & mCDVITIMask) != 0)) ) //OR if there is a ZT2 itinerary commanded AND this CDV is part of itinerary + { + mIsItiCommanded = true; + mCDVState = CDV_STATE_ITI_CMD; + } + + if((mCDVInputMask & InputsBuf) == 0) //Check if CDV is occupied + { + mIsOccupied = true; + mCDVState = CDV_STATE_OCCUPIED; + } + return RET_OK; +} + +void CCDV::SetCDVDeck(bool IsDeck) +{ + mCDVIsDeck = IsDeck; +} diff --git a/sources/CDV.h b/sources/CDV.h new file mode 100644 index 0000000..3f7c327 --- /dev/null +++ b/sources/CDV.h @@ -0,0 +1,81 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130603 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef CDV_H +#define CDV_H + +#include "GlobalDefine.h" +#include "CDVItem.h" +#include "ZTData.h" + +class CCDV +{ +public: + CCDV(); + CCDV(unsigned int CDVITIMask, unsigned int CDVInputMask, unsigned int CDVType, QString CDVLabel, unsigned int CDVWay, unsigned int CDVGraphicalPosition); + virtual ~CCDV(); + + unsigned int SetInputMask(unsigned int Mask); + unsigned int SetLabel(QString Label); + void SetITIMask(unsigned int Mask){mCDVITIMask = Mask;} + virtual unsigned int ComputeCDVState(unsigned int InputsBuf,unsigned int ZT1ItiMask, unsigned int ZT2ItiMask); + unsigned int GetCDVType(){return mCDVType;} + + bool IsOccupied(){return mIsOccupied;} + bool IsITICommanded(){return mIsItiCommanded;} + unsigned int GetCDVState(){return mCDVState;} + QString GetLabel(){return mCDVLabel;} + unsigned int GetInputMask(){return mCDVInputMask;} + void SetCDVWay(unsigned int Way){mCDVWay = Way;} + unsigned int GetCDVWay(){return mCDVWay;} + void SetCDVGraphicalPos(unsigned int Pos){mCDVGraphicalPosition = Pos;} + unsigned int GetCDVGraphicalPos(){return mCDVGraphicalPosition;} + void SetCDVDeck(bool IsDeck); + bool IsCDVDeck(){return mCDVIsDeck;} + +// virtual void SetNormalItiMask(unsigned int Mask){qDebug("Error: Trying to set normal itinerary to an non-switch CDV");} +// virtual void SetReverseItiMask(unsigned int Mask){qDebug("Error: Trying to set reverse itinerary to an non-switch CDV");} +// virtual void SetLane(unsigned int Lane){qDebug("Error: Trying to set lane to an non-switch CDV");} + + +protected: + unsigned int mCDVITIMask; //Masque d'entrée de l'itinéraire dont fait partie ce CDV + unsigned int mCDVInputMask; //Masque d'entrée de l'état d'occupation du CDV + unsigned int mCDVType; //Type de CDV, soit normal ou aiguillage (SWITCH) + QString mCDVLabel; //Texte qui identifie le CDV + unsigned int mCDVWay; //La voie dans laquelle est présente le CDV (Voie 1 ou voie 2). + unsigned int mCDVGraphicalPosition; //Position graphique du CDV à l'écran + bool mCDVIsDeck; //Flag indiquant si le CDV est vis-à-vis le quai + + //CDV State + bool mIsOccupied; //État d'occupation du CDV + bool mIsItiCommanded; //Flag indiquant si l'itinéraire dont fait partie le CDV est commandé + unsigned int mCDVState; //État global du CDV (libre - occupé - itinéraire commandé) + +}; + +#endif // CDV_H diff --git a/sources/CStation.cpp b/sources/CStation.cpp new file mode 100644 index 0000000..368f172 --- /dev/null +++ b/sources/CStation.cpp @@ -0,0 +1,31 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe de base des définitions des différentes stations. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "CStation.h" + +CStation::CStation() +{ +} diff --git a/sources/CStation.h b/sources/CStation.h new file mode 100644 index 0000000..1ff19dc --- /dev/null +++ b/sources/CStation.h @@ -0,0 +1,39 @@ +#ifndef CSTATION_H +#define CSTATION_H + +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" + +class CStation +{ +public: + CStation(); +}; + +#endif // CSTATION_H diff --git a/sources/DiscreteTKTransport.cpp b/sources/DiscreteTKTransport.cpp new file mode 100644 index 0000000..acf82fb --- /dev/null +++ b/sources/DiscreteTKTransport.cpp @@ -0,0 +1,786 @@ + +#include "DiscreteTKTransport.h" +#include "EngLog.h" +#include "ZTLog.h" +#include +#include "ZTData.h" +#include + +CDiscreteTKTransport::CDiscreteTKTransport() +{ + // mTKInterface = this; + mOutputMasks = 0; + mOutputModule = 0; + + + mMaintenanceMode = false; + mForceZT1Clear = false; + mForceZT2Clear = false; + + + mClearZT1AlarmMask = mClearZT2AlarmMask = 0; + mAN1State = mZT1CDVState = mAN2State = mZT2CDVState = false; + + mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; + mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; + +// mZT1TKBuffer.clear(); + mZT1TKDataList.clear(); +// mZT2TKBuffer.clear(); + mZT2TKDataList.clear(); + mZT1CurTKIndex = 0; + mZT2CurTKIndex = 0; + + mZT1TKStateMachineTimer = new QTimer(); + mZT1TKStateMachineTimer->setSingleShot(false); + connect(mZT1TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT1SM())); + + mZT2TKStateMachineTimer = new QTimer(); + mZT2TKStateMachineTimer->setSingleShot(false); + connect(mZT2TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT2SM())); + + ResetAlarmCount(); +} + +CDiscreteTKTransport::~CDiscreteTKTransport() +{ + delete mZT1TKStateMachineTimer; + delete mZT2TKStateMachineTimer; +} + +void CDiscreteTKTransport::BindPointers(GenericOutputMasks_t *OutputMasks, COutputModule *OutputModule) +{ + mOutputMasks = OutputMasks; + mOutputModule = OutputModule; + + + + mClearZT1AlarmMask = mOutputMasks->OutputVP1Mask | mOutputMasks->OutputVP2Mask | mOutputMasks->OutputVP3Mask | mOutputMasks->OutputVP4Mask |\ + mOutputMasks->OutputVP5Mask | mOutputMasks->OutputVP6Mask | mOutputMasks->OutputVF1Mask | mOutputMasks->OutputVF2Mask |\ + mOutputMasks->OutputVF3Mask | mOutputMasks->OutputVF4Mask | mOutputMasks->OutputVF5Mask | mOutputMasks->OutputDPEMask |\ + mOutputMasks->OutputDPIMask | mOutputMasks->OutputV00Mask | mOutputMasks->OutputDPGMask | mOutputMasks->OutputDFRMask |\ + mOutputMasks->OutputPEQ1Mask; + + mClearZT2AlarmMask = mOutputMasks->OutputWP1Mask | mOutputMasks->OutputWP2Mask | mOutputMasks->OutputWP3Mask | mOutputMasks->OutputWP4Mask |\ + mOutputMasks->OutputWP5Mask | mOutputMasks->OutputWP6Mask | mOutputMasks->OutputDPI2Mask | mOutputMasks->OutputDPE2Mask |\ + mOutputMasks->OutputV002Mask | mOutputMasks->OutputPEQ2Mask; +} + +int CDiscreteTKTransport::AddNewZT1Detection(CZTDetectionData Detection) +{ + mZT1TKDataList.append(Detection); + return RET_OK; +} +int CDiscreteTKTransport::AddNewZT2Detection(CZTDetectionData Detection) +{ + mZT2TKDataList.append(Detection); + return RET_OK; +} + +unsigned int CDiscreteTKTransport::BeginTKEmission() +{ + + if(IsTKProcessing()) + return RET_ERROR; + + +// if(IsZT1TKProcessing() == false) + { + if(mZT1TKDataList.size() > 0) + { + if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive == false) + { + // mZT1TKBuffer.clear(); + mZT1TKDataList.clear(); + } + else if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE) + { + mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_TK_STATE; + mOutputModule->ClearOutputFlags(mClearZT1AlarmMask); //make shure no TK was displayed to PCC + mZT1TKStateMachineTimer->start(0); + } + } + } + +// if(IsZT2TKProcessing() == false) + { + if(mZT2TKDataList.size() > 0) + { + if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive == false) + { + // mZT2TKBuffer.clear(); + mZT2TKDataList.clear(); + } + else if(mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE) + { + mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_TK_STATE; + mOutputModule->ClearOutputFlags(mClearZT2AlarmMask); //make shure no TK was displayed to PCC + mZT2TKStateMachineTimer->start(0); + } + } + } + + return RET_OK; +} + +unsigned int CDiscreteTKTransport::SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState) +{ + mAN1State = AN1State; + mZT1CDVState = ZT1CDVState; + mAN2State = AN2State; + mZT2CDVState = ZT2CDVState; + + return RET_OK; +} + +void CDiscreteTKTransport::ExecZT1SM() +{ + switch(mZT1TKGeneratorState) + { + case TK_ZT1_GENERATOR_SHOW_TK_STATE: + { + if(mZT1CurTKIndex >= mZT1TKDataList.size()) + { + mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; + } + else + { + SendTKToCC(mZT1TKDataList.at(mZT1CurTKIndex++)); +// mOutputModule->SetOutputFlags(mZT1TKBuffer.at(mZT1CurTKIndex++)); + mZT1TKGeneratorState = TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE; + + CZTLog::instance()->AddLogString("Émission d'une TK ZT1 au PCC",true); + LogTK(mZT1TKDataList.at(mZT1CurTKIndex-1)); + + + if(mMaintenanceMode) + { + emit TKOutputStatesChanged(true,false); + } + } + + break; + } + case TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE: + { + if(mAN1State == true || (mMaintenanceMode == true && mForceZT1Clear == true)) + { + //clear the TK bits + // mOutputModule->ClearOutputFlags(mClearZT1AlarmMask); + ClearTK(ZT1_TYPE_ID); + mZT1RefTimer.start(); + mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_ZERO_STATE; + + if(mMaintenanceMode == true) + { + if(mForceZT1Clear == true) + { + mForceZT1Clear = false; + CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT1",true); + } + else + { + CZTLog::instance()->AddLogString("Acquitement AN1 détectée",true); + } + + emit TKOutputStatesChanged(false,false); + + } + else + { + CZTLog::instance()->AddLogString("Acquitement AN1 détectée",true); + } + } + else if(mZT1CDVState == false && mMaintenanceMode == false) + { + //Enter the auto acquitment TK generation mode... + //A TK is already output, make shure it's there long enough. + CZTLog::instance()->AddLogString("Libération du CDV de quai ZT1. Début de l'acquitement automatique",true); + mZT1RefTimer.start(); + mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; + } + + break; + } + case TK_ZT1_GENERATOR_SHOW_ZERO_STATE: + { + if(mZT1RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) + { + mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_TK_STATE; + } + break; + } + case TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE: + { + if(mZT1CurTKIndex >= mZT1TKDataList.size()) + { + mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; + } + else + { + //mOutputModule->SetOutputFlags(mZT1TKBuffer.at(mZT1CurTKIndex++)); + SendTKToCC(mZT1TKDataList.at(mZT1CurTKIndex++)); + mZT1RefTimer.start(); + mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; + CZTLog::instance()->AddLogString("Émission d'une TK ZT1 au PCC",true); + LogTK(mZT1TKDataList.at(mZT1CurTKIndex-1)); + } + break; + } + case TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE: + { + if(mZT1RefTimer.elapsed() >= TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT) + { + //mOutputModule->ClearOutputFlags(mClearZT1AlarmMask); + ClearTK(ZT1_TYPE_ID); + mZT1RefTimer.start(); + mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE; + CZTLog::instance()->AddLogString("Acquitement automatique TK ZT1",true); + } + break; + } + case TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE: + { + if(mZT1RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) + { + //emit next TK + mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE; + } + break; + } + + case TK_GENERATOR_ZT1_STANDBY_STATE: + { + // mZT1TKBuffer.clear(); + mZT1TKDataList.clear(); + mZT1CurTKIndex = 0; + mZT1TKStateMachineTimer->stop(); + ResetAlarmCount(); + + //In maintenance mode, it is possible to have ZT2 events at the same time + //than ZT1. So if any ZT2 events are waiting in the qeue, send them... + if(mMaintenanceMode) + { + if(mZT2TKDataList.size() > 0) + { + BeginTKEmission(); + } + } + + break; + } + } +} + +void CDiscreteTKTransport::ExecZT2SM() +{ + switch(mZT2TKGeneratorState) + { + case TK_ZT2_GENERATOR_SHOW_TK_STATE: + { + if(mZT2CurTKIndex >= mZT2TKDataList.size()) + { + mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; + } + else + { + // mOutputModule->SetOutputFlags(mZT2TKBuffer.at(mZT2CurTKIndex++)); + SendTKToCC(mZT2TKDataList.at(mZT2CurTKIndex++)); + mZT2TKGeneratorState = TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE; + CZTLog::instance()->AddLogString("Émission d'une TK ZT2 au PCC",true); + LogTK(mZT2TKDataList.at(mZT2CurTKIndex-1)); + if(mMaintenanceMode) + { + emit TKOutputStatesChanged(false,true); + } + } + break; + } + case TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE: + { + if(mAN2State == true || (mMaintenanceMode == true && mForceZT2Clear == true)) + { + //clear the TK bits + // mOutputModule->ClearOutputFlags(mClearZT2AlarmMask); + ClearTK(ZT2_TYPE_ID); + mZT2RefTimer.start(); + mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_ZERO_STATE; + if(mMaintenanceMode == true) + { + if(mForceZT2Clear == true) + { + mForceZT2Clear = false; + CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT2",true); + } + else + { + CZTLog::instance()->AddLogString("Acquitement AN2 détectée",true); + } + + emit TKOutputStatesChanged(false,false); + } + else + { + CZTLog::instance()->AddLogString("Acquitement AN2 détectée",true); + } + } + else if(mZT2CDVState == false && mMaintenanceMode == false) + { + //Enter the auto acquitment TK generation mode... + //A TK is already output, make shure it's there long enough. + CZTLog::instance()->AddLogString("Libération du CDV ZT2. Début de l'acquitement automatique",true); + mZT2RefTimer.start(); + mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; + } + break; + } + case TK_ZT2_GENERATOR_SHOW_ZERO_STATE: + { + if(mZT2RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) + { + mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_TK_STATE; + } + break; + } + case TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE: + { + if(mZT2CurTKIndex >= mZT2TKDataList.size()) + { + mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; + } + else + { + // mOutputModule->SetOutputFlags(mZT2TKBuffer.at(mZT2CurTKIndex++)); + SendTKToCC(mZT2TKDataList.at(mZT2CurTKIndex++)); + mZT2RefTimer.start(); + mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; + CZTLog::instance()->AddLogString("Émission d'une TK ZT2 au PCC",true); + //LogTK(mZT2TKBuffer.at(mZT2CurTKIndex-1)); + LogTK(mZT2TKDataList.at(mZT2CurTKIndex-1)); + } + break; + } + case TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE: + { + if(mZT2RefTimer.elapsed() >= TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT) + { + //mOutputModule->ClearOutputFlags(mClearZT2AlarmMask); + ClearTK(ZT2_TYPE_ID); + mZT2RefTimer.start(); + mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE; + CZTLog::instance()->AddLogString("Acquitement automatique ZT2",true); + } + break; + } + case TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE: + { + if(mZT2RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) + { + //emit next TK + mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE; + } + break; + } + + case TK_GENERATOR_ZT2_STANDBY_STATE: + { + // mZT2TKBuffer.clear(); + mZT2TKDataList.clear(); + mZT2CurTKIndex = 0; + mZT2TKStateMachineTimer->stop(); + ResetAlarmCount(); + + //In maintenance mode, it is possible to have ZT2 events at the same time + //than ZT1. So if any ZT1 events are waiting in the qeue, send them... + if(mMaintenanceMode) + { + if(mZT1TKDataList.size() > 0) + { + BeginTKEmission(); + } + } + + break; + } + } +} + +quint32 CDiscreteTKTransport::IntegerToBCDZT1(quint32 Value) +{ + quint32 BCD = 0; + + if(Value >= 20) + { + BCD |= mOutputMasks->OutputVP6Mask; + Value -= 20; + } + if(Value >= 10) + { + BCD |= mOutputMasks->OutputVP5Mask; + Value -= 10; + } + + if((Value & 1) != 0) + BCD |= mOutputMasks->OutputVP1Mask; + + if((Value & 2) != 0) + BCD |= mOutputMasks->OutputVP2Mask; + + if((Value & 4) != 0) + BCD |= mOutputMasks->OutputVP3Mask; + + if((Value & 8) != 0) + BCD |= mOutputMasks->OutputVP4Mask; + + return BCD; +} + +quint32 CDiscreteTKTransport::IntegerToBCDFN(quint32 Value) +{ + quint32 BCD = 0; + + if(Value >= 10) + { + BCD |= mOutputMasks->OutputVF5Mask; + Value -= 10; + } + + if((Value & 1) != 0) + BCD |= mOutputMasks->OutputVF1Mask; + + if((Value & 2) != 0) + BCD |= mOutputMasks->OutputVF2Mask; + + if((Value & 4) != 0) + BCD |= mOutputMasks->OutputVF3Mask; + + if((Value & 8) != 0) + BCD |= mOutputMasks->OutputVF4Mask; + + return BCD; +} + +quint32 CDiscreteTKTransport::IntegerToBCDZT2(quint32 Value) +{ + quint32 BCD = 0; + + if(Value >= 20) + { + BCD |= mOutputMasks->OutputWP6Mask; + Value -= 20; + } + if(Value >= 10) + { + BCD |= mOutputMasks->OutputWP5Mask; + Value -= 10; + } + + if((Value & 1) != 0) + BCD |= mOutputMasks->OutputWP1Mask; + + if((Value & 2) != 0) + BCD |= mOutputMasks->OutputWP2Mask; + + if((Value & 4) != 0) + BCD |= mOutputMasks->OutputWP3Mask; + + if((Value & 8) != 0) + BCD |= mOutputMasks->OutputWP4Mask; + + return BCD; +} + +unsigned int CDiscreteTKTransport::CancelAllTK() +{ + mOutputModule->ClearOutputFlags(mClearZT1AlarmMask); + mOutputModule->ClearOutputFlags(mClearZT2AlarmMask); + + mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; + mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; + + // mZT1TKBuffer.clear(); + mZT1TKDataList.clear(); + // mZT2TKBuffer.clear(); + mZT2TKDataList.clear(); + + + //exec the SM once + mZT1TKStateMachineTimer->start(); + mZT2TKStateMachineTimer->start(); + ResetAlarmCount(); + + return RET_OK; +} + +unsigned int CDiscreteTKTransport::CancelMaintenanceCurrentTK() +{ + + if(mZT1TKGeneratorState == TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE) + { + mForceZT1Clear = true; + return RET_OK; + } + else if(mZT2TKGeneratorState == TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE) + { + mForceZT2Clear = true; + return RET_OK; + } + return RET_ERROR; +} + + +unsigned int CDiscreteTKTransport::ExitMaintenance() +{ +// if(mMaintenanceMode == false) +// { +// return RET_ERROR; +// } + + + mMaintenanceMode = false; + mForceZT1Clear = false; + mForceZT2Clear = false; + CancelAllTK(); + + return RET_OK; +} + +unsigned int CDiscreteTKTransport::EnterMaintenance() +{ + if(IsTKProcessing()) + { + return RET_ERROR; + } + + CancelAllTK(); + mMaintenanceMode = true; + mForceZT1Clear = false; + mForceZT2Clear = false; + + return RET_OK; +} + +bool CDiscreteTKTransport::IsTKProcessing() +{ + if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE && + mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE) + { + return false; + } + + return true; +} + +bool CDiscreteTKTransport::IsZT1TKProcessing() +{ + if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE) + { + return false; + } + + return true; +} + +bool CDiscreteTKTransport::IsZT2TKProcessing() +{ + if(mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE) + { + return false; + } + + return true; +} + +//void CDiscreteTKTransport::LogTK(CZTDetectionData DetectionData) +//{ +// QString str = "TK envoyée: "; +// QTextStream stream(&str); +// stream.setCodec("UTF-8"); + +// stream << QString::fromUtf8(CZTData::GetErrorString(DetectionData.mDetectionID)); +// stream << " | Rang: " << DetectionData.mRank; +// CZTLog::instance()->AddLogString(str,true); +//} + +//void CDiscreteTKTransport::LogTK(quint32 Value) +//{ +// QString str = "Output: "; +// QTextStream stream(&str); + +// stream << "VP1 " << +// "VP2 " << +// "VP3 " << +// "VP4 " << +// "VP5 " << +// "VP6 " << +// "VF1 " << +// "VF2 " << +// "VF3 " << +// "VF4 " << +// "VF5 " << +// "WP1 " << +// "WP2 " << +// "WP3 " << +// "WP4 " << +// "WP5 " << +// "WP6 " << +// "DPE " << +// "DPI " << +// "V00 " << +// "DPG " << +// "DFR " << +// "RF " << +// "RF2 " << +// "VEL " << +// "VEL2 " << +// "DPI2 " << +// "DPE2 " << +// "V002 " << +// "PEQ1 " << +// "PEQ2 " << +// "WDOG "; + +// CZTLog::instance()->AddLogString(str,true); +// str.clear(); + +// stream << " " << +// " " << ((Value & mOutputMasks->OutputVP1Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVP2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVP3Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVP4Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVP5Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVP6Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVF1Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVF2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVF3Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVF4Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVF5Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputWP1Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputWP2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputWP3Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputWP4Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputWP5Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputWP6Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputDPEMask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputDPIMask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputV00Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputDPGMask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputDFRMask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputRFMask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputRF2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVELMask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputVEL2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputDPI2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputDPE2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputV002Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputPEQ1Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputPEQ2Mask) != 0) << " " << +// " " << ((Value & mOutputMasks->OutputWatchdogMask) != 0) << " "; + + +// CZTLog::instance()->AddLogString(str,true); + +//} + +int CDiscreteTKTransport::SendTKToCC(CZTDetectionData TKData) +{ + quint32 TKFlags = 0; + quint32 Rank = TKData.mRank; + + + switch(TKData.mDetectionID) + { + case DETECTION_MAGNETIC_SENSOR_COUNT: + { + + TKFlags |= mOutputMasks->OutputV00Mask; + TKFlags |= IntegerToBCDZT1(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_FN_DETECTION: + { + TKFlags |= mOutputMasks->OutputDFRMask; + TKFlags |= IntegerToBCDFN(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_PG_DETECTION: + { + TKFlags |= mOutputMasks->OutputDPGMask; + TKFlags |= IntegerToBCDZT1(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_PPI_DETECTION: + { + TKFlags |= mOutputMasks->OutputDPIMask; + TKFlags |= IntegerToBCDZT1(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_PPE_DETECTION: + { + TKFlags |= mOutputMasks->OutputDPEMask; + TKFlags |= IntegerToBCDZT1(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_PEQ1_DETECTION: + { + TKFlags |= mOutputMasks->OutputPEQ1Mask; + TKFlags |= IntegerToBCDZT1(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_PEQ2_DETECTION: + { + TKFlags |= mOutputMasks->OutputPEQ2Mask; + TKFlags |= IntegerToBCDZT2(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT: + { + TKFlags |= mOutputMasks->OutputV002Mask; + TKFlags |= IntegerToBCDZT2(Rank); + mOutputModule->SetOutputFlags(TKFlags); + + break; + } + case DETECTION_ZT2_PPI_DETECTION: + { + TKFlags |= mOutputMasks->OutputDPI2Mask; + TKFlags |= IntegerToBCDZT2(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + case DETECTION_ZT2_PPE_DETECTION: + { + TKFlags |= mOutputMasks->OutputDPE2Mask; + TKFlags |= IntegerToBCDZT2(Rank); + mOutputModule->SetOutputFlags(TKFlags); + break; + } + } + + return RET_OK; +} + +int CDiscreteTKTransport::ClearTK(int ZT) +{ + if(ZT == ZT1_TYPE_ID) + { + mOutputModule->ClearOutputFlags(mClearZT1AlarmMask); + } + else if(ZT == ZT2_TYPE_ID) + { + mOutputModule->ClearOutputFlags(mClearZT2AlarmMask); + } + else + { + return RET_ERROR; + } + + return RET_OK; +} diff --git a/sources/DiscreteTKTransport.h b/sources/DiscreteTKTransport.h new file mode 100644 index 0000000..04c254a --- /dev/null +++ b/sources/DiscreteTKTransport.h @@ -0,0 +1,101 @@ +#ifndef DISCRETETKTRANSPORT_H +#define DISCRETETKTRANSPORT_H + +#include "TKTransportInterface.h" +#include "OutputModule.h" +#include "Station.h" +#include +#include "TKGenerator.h" + +#define TK_GENERATOR_SHOW_ZERO_TIMEOUT 1000 //the Low state time between two TKs +#define TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT 2000 //the amount of time the TK must be emited in auto acquitment mode +#define TK_GENERATOR_MAX_ALARMS 4 +#define TK_GENERATOR_MAX_PEQ 1 +#define TK_GENERATOR_MAX_V00X 1 + + +class CDiscreteTKTransport : public CTKTransportInterface +{ + Q_OBJECT +public: + + enum eTKGeneratorStaes + { + TK_ZT1_GENERATOR_SHOW_TK_STATE, + TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE, + TK_ZT1_GENERATOR_SHOW_ZERO_STATE, + + TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE, + TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE, + TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE, + + TK_ZT1_GENERATOR_FINISH_STATE, + + TK_GENERATOR_ZT1_STANDBY_STATE, + + TK_ZT2_GENERATOR_SHOW_TK_STATE, + TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE, + TK_ZT2_GENERATOR_SHOW_ZERO_STATE, + + TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE, + TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE, + TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE, + + TK_ZT2_GENERATOR_FINISH_STATE, + + TK_GENERATOR_ZT2_STANDBY_STATE + }; + + CDiscreteTKTransport(); + ~CDiscreteTKTransport(); + + + int SendTKToCC(CZTDetectionData TKData); + int ClearTK(int ZT); + + void BindPointers(GenericOutputMasks_t *OutputMasks, COutputModule *OutputModule); + unsigned int CancelAllTK(); + unsigned int CancelMaintenanceCurrentTK(); + unsigned int ExitMaintenance(); + unsigned int EnterMaintenance(); + unsigned int SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState); + unsigned int BeginTKEmission(); + + bool IsTKProcessing(); + bool IsZT1TKProcessing(); + bool IsZT2TKProcessing(); + int AddNewZT1Detection(CZTDetectionData Detection); + int AddNewZT2Detection(CZTDetectionData Detection); + +private: + GenericOutputMasks_t *mOutputMasks; + + COutputModule *mOutputModule; + + QList mZT1TKDataList,mZT2TKDataList; + unsigned int mZT1TKGeneratorState,mZT2TKGeneratorState; + int mZT1CurTKIndex,mZT2CurTKIndex; + QTimer *mZT1TKStateMachineTimer; + QTimer *mZT2TKStateMachineTimer; + QElapsedTimer mZT1RefTimer,mZT2RefTimer; + + bool mAN1State, mZT1CDVState,mAN2State,mZT2CDVState; + bool mMaintenanceMode, mForceZT1Clear, mForceZT2Clear; + + quint32 mClearZT1AlarmMask, mClearZT2AlarmMask; + + quint32 IntegerToBCDZT1(quint32 Value); + quint32 IntegerToBCDZT2(quint32 Value); + quint32 IntegerToBCDFN(quint32 Value); + + //void LogTK(quint32 Value); + // void LogTK(CZTDetectionData DetectionData); + + +public slots: + void ExecZT1SM(); + void ExecZT2SM(); + +}; + +#endif // DISCRETETKTRANSPORT_H diff --git a/sources/EngLog.cpp b/sources/EngLog.cpp new file mode 100644 index 0000000..93292f9 --- /dev/null +++ b/sources/EngLog.cpp @@ -0,0 +1,152 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe permet de créer un fichier log très détaillé. + CEngLog ne devrait être utilisée pour des fins de débogage par l'ingénierie + Le log peut être activé en ajoutant la ligne ENGLOG=V dans le fichier de + configuration de la Zone Tests (ZT.cfg) où V (verbosité) est une valeur entre + 1 et 3 qui représente le niveau de détail désiré. +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "EngLog.h" +#include +#include +#include "RamMonitor.h" +#include + +//#include + +//singleton instanciation +CEngLog CEngLog::mSingleton; + +CEngLog::CEngLog(): + mEngLogFile(NULL), + mVerbosity(3) +{ + //QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); +} + +CEngLog::~CEngLog() +{ + if(mEngLogFile) + delete mEngLogFile; +} + +void CEngLog::Init(unsigned int Verbosity) +{ + mVerbosity = Verbosity; + QString FileName; +#ifndef USE_SINGLE_ENGINEERING_FILE + FileName.sprintf("./ING/IngLog_%s_%s",QDateTime::currentDateTime().date().toString("yyyyMMdd").toAscii().data(),QDateTime::currentDateTime().time().toString("hh-mm-ss").toAscii().data()); + FileName.append(".txt"); +#else + FileName.sprintf("./ING/IngLog.txt"); +#endif + mEngLogFile = new QFile(FileName); + if(mEngLogFile) + { +#ifndef USE_SINGLE_ENGINEERING_FILE + mEngLogFile->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Unbuffered); +#else + QFileInfo EngLogFileInfo(*mEngLogFile); + if(EngLogFileInfo.size() > MAX_ENGINEERING_LOG_FILESIZE) //Make shure the file doesn't get too big + { + mEngLogFile->open(QIODevice::WriteOnly |QIODevice::Truncate | QIODevice::Text | QIODevice::Unbuffered); + } + else + { + mEngLogFile->open(QIODevice::WriteOnly |QIODevice::Append | QIODevice::Text | QIODevice::Unbuffered); + } +#endif + + QString temp; + mEngLogFile->write("\n\n"); + AddLogString(temp.sprintf("********************************************************************"),0); + AddLogString(temp.sprintf("Zone Tests. Fichier Log d'ingénierie"),0); + AddLogString(temp.sprintf("Créé le %s à %s",QDateTime::currentDateTime().date().toString("yyyy-MM-dd").toAscii().data(),QDateTime::currentDateTime().time().toString("hh:mm:ss").toAscii().data()),0); + AddLogString(temp.sprintf("Verbosité niveau %d",mVerbosity),0); + AddLogString(temp.sprintf("********************************************************************"),0); + } +} + +void CEngLog::AddLogString(QString string, unsigned int Verbosity) +{ + if(string.isEmpty()) + return; + + qDebug("%s",string.toUtf8().data()); + + if(mEngLogFile == NULL) + return; + + if(mEngLogFile->isOpen() == false) + return; + + if(Verbosity <= mVerbosity) + { + if(string.at(string.length()-1) != '\n') + string.append('\n'); + + if(string.length() > 1) + string.prepend(QDateTime::currentDateTime().toString("yyyy/MM/dd - hh:mm:ss.zzz : ").toAscii().data()); + + mEngLogFile->write(string.toUtf8()); + +#ifdef LOG_RAM_USAGE + long ram = CRamMonitor::instance()->GetRamUsage(false); + mEngLogFile->write(QString().sprintf("Ram: %ld \n",ram).toUtf8()); +#endif + + } +} + +//When a buffer is already formatted, just write it to the file. +void CEngLog::WriteFormattedString(QString string) +{ + mEngLogFile->write(string.toUtf8()); + qDebug("%s",string.toUtf8().data()); +} + +unsigned int CEngLog::DeleteEngLogFile() +{ + mEngLogFile->remove(); + delete mEngLogFile; + + mEngLogFile = new QFile("./ING/IngLog.txt"); + if(mEngLogFile) + { + mEngLogFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text | QIODevice::Unbuffered); + + QString temp; + mEngLogFile->write("\n\n"); + AddLogString(temp.sprintf("********************************************************************")); + AddLogString(temp.sprintf("Zone Tests. Fichier Log d'ingénierie (créé suite à une destruction)"),0); + AddLogString(temp.sprintf("Créé le %s à %s",QDateTime::currentDateTime().date().toString("yyyy-MM-dd").toAscii().data(),QDateTime::currentDateTime().time().toString("hh:mm:ss").toAscii().data()),0); + AddLogString(temp.sprintf("Verbosité niveau %d",mVerbosity),0); + AddLogString(temp.sprintf("********************************************************************")); + } + mEngLogFile->flush(); + + + return RET_OK; +} diff --git a/sources/EngLog.h b/sources/EngLog.h new file mode 100644 index 0000000..8bb5969 --- /dev/null +++ b/sources/EngLog.h @@ -0,0 +1,61 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "GlobalDefine.h" + +#ifndef ENGLOG_H +#define ENGLOG_H + +#include + +#define USE_SINGLE_ENGINEERING_FILE + +class CEngLog +{ +public: + + //CEngLog is a singleton class + static CEngLog* instance(){return &mSingleton;} + static CEngLog mSingleton; + + CEngLog(); + ~CEngLog(); + + void AddLogString(QString string, unsigned int Verbosity = 3); + void WriteFormattedString(QString string); + void Init(unsigned int Verbosity); + unsigned int DeleteEngLogFile(); + +private: + QFile *mEngLogFile; + unsigned int mVerbosity; + + + + +}; + +#endif // ENGLOG_H diff --git a/sources/Event.cpp b/sources/Event.cpp new file mode 100644 index 0000000..beb2bd2 --- /dev/null +++ b/sources/Event.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe/structure qui décrit une fonction de détection désactivée. Utilisé + par la classe CEventMgr. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Event.h" + +CEvent::CEvent(unsigned int EventType, QString EventLabel, bool IsItemAnimated) +{ + mEventType = EventType; + mEventLabel = EventLabel; + mItemAnimated = IsItemAnimated; +} diff --git a/sources/Event.h b/sources/Event.h new file mode 100644 index 0000000..d6680c5 --- /dev/null +++ b/sources/Event.h @@ -0,0 +1,45 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131022 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef EVENT_H +#define EVENT_H + +#include "GlobalDefine.h" +#include "EventItem.h" + + +class CEvent +{ +public: + CEvent(unsigned int EventType, QString EventLabel,bool IsItemAnimated); + + unsigned int mEventType; + QString mEventLabel; + bool mItemAnimated; +}; + +#endif // EVENT_H diff --git a/sources/EventMgr.cpp b/sources/EventMgr.cpp new file mode 100644 index 0000000..8f18730 --- /dev/null +++ b/sources/EventMgr.cpp @@ -0,0 +1,176 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe gère la liste des fonctions désactivées. Pour chaque fonction + de détection désactivée, un objet "CEvent" est créé et ajouté à la liste. + Cette classe est utilisée par l'interface graphique est la machine à états + d'analyse d'erreurs afin de savoir quels déclenchements ignorer. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "EventMgr.h" +#include "ZTPage.h" + + + +CEventMgr::CEventMgr() +{ + +} + +unsigned int CEventMgr::UpdateEvents(CZTDetectionFunctionConfig *DetectionFuncCfg) +{ + + if(!DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive || + !DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_FN].TKActive) + AddEvent(EVENT_FN_HS); + else + RemoveEvent(EVENT_FN_HS); + + if(!DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive || + !DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_PG].TKActive) + AddEvent(EVENT_PG_HS); + else + RemoveEvent(EVENT_PG_HS); + + if(!DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive || + !DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_PP].TKActive) + AddEvent(EVENT_PP_HS); + else + RemoveEvent(EVENT_PP_HS); + + if(!DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive || + !DetectionFuncCfg->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive) + AddEvent(EVENT_PP2_HS); + else + RemoveEvent(EVENT_PP2_HS); + + mMainPagePtr->UpdateEventsList(); + + return RET_OK; +} + +bool CEventMgr::AddEvent(unsigned int EventID) +{ + //Check if already on the list. If so, do nothing. + for(int i = 0; i < mEventsList.size(); i++) + { + if(mEventsList.at(i)->mEventType == EventID) + return false; + } + + QString Label; + bool IsAnimated = false; + switch(EventID) + { + case EVENT_FN_HS: + { + Label = "Frotteur Négatif HS"; + IsAnimated = true; + break; + } + case EVENT_PG_HS: + { + Label = "Pneu Guidage HS"; + IsAnimated = true; + break; + } + case EVENT_PP_HS: + { + Label = "Pneu Porteur HS"; + IsAnimated = true; + break; + } + case EVENT_PP2_HS: + { + Label = "Pneu Porteur ZT2 HS"; + IsAnimated = true; + break; + } + case EVENT_TK1_HS: + { + Label = "TK1 HS"; + break; + } + case EVENT_CA_PG: + { + Label = "Calibration Pneu Guidage"; + IsAnimated = true; + break; + } + case EVENT_PEQ1: + { + Label = "Panne Équipement ZT1"; + break; + } + case EVENT_MAINTENANCE: + { + Label = "Entretien ZT"; + IsAnimated = true; + break; + } + } + + CEvent *NewEvent = new CEvent(EventID,Label,IsAnimated); + mEventsList.append(NewEvent); + + return true; + +} + +bool CEventMgr::RemoveEvent(unsigned int EventID) +{ + //Find item in the list and remove it if present + for(int i = 0; i < mEventsList.size(); i++) + { + if(mEventsList.at(i)->mEventType == EventID) + { + delete mEventsList.at(i); + mEventsList.removeAt(i); + } + } + + return true; +} + +unsigned int CEventMgr::AddSingleEvent(unsigned int EventID) +{ + if(AddEvent(EventID) == true) + { + mMainPagePtr->UpdateEventsList(); + return RET_OK; + } + + return RET_ERROR; +} + +unsigned int CEventMgr::RemoveSingleEvent(unsigned int EventID) +{ + if(RemoveEvent(EventID) == true) + { + mMainPagePtr->UpdateEventsList(); + return RET_OK; + } + + return RET_ERROR; +} diff --git a/sources/EventMgr.h b/sources/EventMgr.h new file mode 100644 index 0000000..ed1ff4d --- /dev/null +++ b/sources/EventMgr.h @@ -0,0 +1,78 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef EVENTMGR_H +#define EVENTMGR_H + +#include "GlobalDefine.h" +#include "Event.h" +#include "EventItem.h" +#include +#include "ZTData.h" + + +enum eEventTypeID +{ + EVENT_FN_HS, + EVENT_PG_HS, + EVENT_PP_HS, + EVENT_PP2_HS, + EVENT_TK1_HS, + EVENT_CA_PG, + EVENT_PEQ1, + EVENT_MAINTENANCE, + EVENT_MAX_EVENT_ID +}; + +class CZTPage; +class CZoneTest; + +class CEventMgr +{ +public: + CEventMgr(); + + QList mEventsList; + CZTPage *mMainPagePtr; + CZoneTest *mProgramPTr; + + unsigned int UpdateEvents(CZTDetectionFunctionConfig* DetectionFuncCfg); + unsigned int AddSingleEvent(unsigned int EventID); + unsigned int RemoveSingleEvent(unsigned int EventID); + + +private: + bool AddEvent(unsigned int EventID); + bool RemoveEvent(unsigned int EventID); + +signals: + //void EventsListUpdated(QList*); + + +}; + +#endif // EVENTMGR_H diff --git a/sources/ExtIOThread.cpp b/sources/ExtIOThread.cpp new file mode 100644 index 0000000..db7c1a9 --- /dev/null +++ b/sources/ExtIOThread.cpp @@ -0,0 +1,322 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe constitue un thread qui exécute la lecture des modules + d'I/O externes via le port Ethernet. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ExtIOThread.h" + +CExtIOThread::CExtIOThread() : QObject() +{ + mInputModule = 0; + mOutputModule = 0; + mAnalogInputModule = 0; + + mCurInputs = 0xFFFFFFFF; + mCurAnalogInput = 0; + mOutputDirty = false; + mRun = true; + mIsRunning = false; + + mCurAnalogChannel = 0; + mAnalogModulePresent = false; +} + +unsigned int CExtIOThread::BindPointers(CInputModule *InputModule, COutputModule *OutputModule, CAnalogInputModule *AnalogModule, int AnalogChannel) +{ + mInputModule = InputModule; + mOutputModule = OutputModule; + mAnalogInputModule = AnalogModule; + mCurAnalogChannel = AnalogChannel; + + if(mAnalogInputModule != 0) + { + mAnalogModulePresent = true; + } + + return RET_OK; +} + +unsigned int CExtIOThread::GetInputs() +{ + unsigned int inputs; + mMutex.lock(); + inputs = mCurInputs; + mMutex.unlock(); + + return inputs; +} + +unsigned int CExtIOThread::GetInputBuf() +{ + return GetInputs(); +} + +unsigned int CExtIOThread::SetOutput(quint32 buffer) +{ + COutputTransaction NewTransaction; + NewTransaction.mOutputsWord = buffer; + NewTransaction.mOutputTransaction = OUTPUT_MODULE_SET_OUTPUT_WORD; + mMutex.lock(); + mOutputTransactionList.append(NewTransaction); + mMutex.unlock(); + + return RET_OK; +} + +unsigned int CExtIOThread::SetOutput(unsigned char *buffer) +{ + COutputTransaction NewTransaction; + memcpy(&NewTransaction.mOutputsBuf,buffer,4); + NewTransaction.mOutputTransaction = OUTPUT_MODULE_SET_OUTPUT_BUF; + mMutex.lock(); + mOutputTransactionList.append(NewTransaction); + mMutex.unlock(); + + return RET_OK; +} + +unsigned int CExtIOThread::SetOutputFlags(quint32 Flags) +{ + COutputTransaction NewTransaction; + NewTransaction.mOutputsWord = Flags; + NewTransaction.mOutputTransaction = OUTPUT_MODULE_SET_OUTPUT_FLAGS; + mMutex.lock(); + mOutputTransactionList.append(NewTransaction); + mMutex.unlock(); + + return RET_OK; +} + +unsigned int CExtIOThread::ClearOutputFlags(quint32 Flags) +{ + COutputTransaction NewTransaction; + NewTransaction.mOutputsWord = Flags; + NewTransaction.mOutputTransaction = OUTPUT_MODULE_CLEAR_OUTPUT_FLAGS; + mMutex.lock(); + mOutputTransactionList.append(NewTransaction); + mMutex.unlock(); + + return RET_OK; +} + +unsigned int CExtIOThread::ToggleOutputFlags(quint32 Flags) +{ + COutputTransaction NewTransaction; + NewTransaction.mOutputsWord = Flags; + NewTransaction.mOutputTransaction = OUTPUT_MODULE_TOGGLE_OUTPUT_FLAGS; + mMutex.lock(); + mOutputTransactionList.append(NewTransaction); + mMutex.unlock(); + + return RET_OK; +} + +///ATTENTION !!!!!!!!!!!!!!!!! //// +//Le paramètre Channel n'est pas géré en tant que tel +//lors de l'écriture de la fonction, un seul channel (SDF) est utilisé. +//Si d'autres entrées analogiques sont ajoutées, il faudra gérer les +//différents channels. +unsigned int CExtIOThread::GetAnalogInput(int Channel, int *data) +{ + Q_UNUSED(Channel) + + mMutex.lock(); + *data = mCurAnalogInput; + mMutex.unlock(); + + return RET_OK; +} + +unsigned int CExtIOThread::GetAnalogInput(int Channel, double &data) +{ + Q_UNUSED(Channel) + + mMutex.lock(); + data = (double)mCurAnalogInput; + mMutex.unlock(); + + return RET_OK; +} + + +unsigned int CExtIOThread::StopAcquisition() +{ + mMutex.lock(); + mRun = false; + mMutex.unlock(); + + return RET_OK; +} + +void CExtIOThread::DoAcquisition() +{ + bool Run = true; + mDigitalInputsPeriodTimer.start(); + mAnalogInputsTimer.start(); + +#ifdef OUTPUT_EXTIO_SAMPLE_RATE + mSampleRateTimer.start(); +#endif + + mMutex.lock(); + mIsRunning = true; + mMutex.unlock(); + + while(Run == true) + { + //JFM 20140821 + // Read analog inputs + if(mAnalogInputModule != 0) + { + if(mAnalogInputsTimer.nsecsElapsed() >= EXT_ANALOG_INPUT_ACQUISITION_PERIOD) //help relax the communication with the modules + { + int AnalogInput; + mAnalogInputModule->GetAnalogInput(mCurAnalogChannel,&AnalogInput); + + mMutex.lock(); + mCurAnalogInput = AnalogInput; + mMutex.unlock(); + mAnalogInputsTimer.restart(); + } + } + + + //Read discreete inputs + if(mDigitalInputsPeriodTimer.elapsed() >= EXT_DIGITAL_INPUTS_ACQUISITION_PERIOD) + { + unsigned int Input = mInputModule->GetInputBuf(); + mMutex.lock(); + mCurInputs = Input; + mMutex.unlock(); + mDigitalInputsPeriodTimer.restart(); + } + + + //Refresh outputs if necessary + bool OutputDirty = false; + COutputTransaction OutputTransaction; + mMutex.lock(); + if(mOutputTransactionList.size() != 0) + { + OutputDirty = true; + OutputTransaction = mOutputTransactionList.takeFirst(); + } + mMutex.unlock(); + + if(OutputDirty == true) + { + switch(OutputTransaction.mOutputTransaction) + { + case OUTPUT_MODULE_SET_OUTPUT_BUF: + { + mOutputModule->SetOutput(OutputTransaction.mOutputsBuf); + break; + } + case OUTPUT_MODULE_SET_OUTPUT_WORD: + { + mOutputModule->SetOutput(OutputTransaction.mOutputsWord); + break; + } + case OUTPUT_MODULE_SET_OUTPUT_FLAGS: + { + mOutputModule->SetOutputFlags(OutputTransaction.mOutputsWord); + break; + } + case OUTPUT_MODULE_CLEAR_OUTPUT_FLAGS: + { + mOutputModule->ClearOutputFlags(OutputTransaction.mOutputsWord); + break; + } + case OUTPUT_MODULE_TOGGLE_OUTPUT_FLAGS: + { + mOutputModule->ToggleOutputFlags(OutputTransaction.mOutputsWord); + break; + } + } + } + + + mMutex.lock(); + Run = mRun; + mMutex.unlock(); + +#ifdef OUTPUT_EXTIO_SAMPLE_RATE + mMutex.lock(); + mDelay = mSampleRateTimer.elapsed(); + mMutex.unlock(); + mSampleRateTimer.restart(); + +#endif + } + + mMutex.lock(); + mIsRunning = false; + mMutex.unlock(); + //qDebug("Ext IO Thread exit"); + +} + +bool CExtIOThread::IsAnalogModueDetected() +{ + return mAnalogModulePresent; +} + +bool CExtIOThread::IsThreadRunning() +{ + bool Running; + mMutex.lock(); + Running = mIsRunning; + mMutex.unlock(); + + return Running; +} + +#ifdef OUTPUT_EXTIO_SAMPLE_RATE +qint64 CExtIOThread::GetSampleRate() +{ + qint64 temp; + mMutex.lock(); + temp = mDelay; + mMutex.unlock(); + return temp; +// return mSampleRateTimer.nsecsElapsed(); +} + +#endif + +COutputTransaction &COutputTransaction::operator =(const COutputTransaction& a) +{ + mOutputsBuf[0] = a.mOutputsBuf[0]; + mOutputsBuf[1] = a.mOutputsBuf[1]; + mOutputsBuf[2] = a.mOutputsBuf[2]; + mOutputsBuf[3] = a.mOutputsBuf[3]; + + mOutputTransaction = a.mOutputTransaction; + + mOutputsWord = a.mOutputsWord; + + return *this; +} diff --git a/sources/ExtIOThread.h b/sources/ExtIOThread.h new file mode 100644 index 0000000..51ca4da --- /dev/null +++ b/sources/ExtIOThread.h @@ -0,0 +1,133 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "InputModule.h" +#include "OutputModule.h" +#include "AnalogInputModule.h" +#include "QMutex" +#include +#ifndef EXTIOTHREAD_H +#define EXTIOTHREAD_H + +#include + + +enum eOutputsModuleTransactionType +{ + OUTPUT_MODULE_SET_OUTPUT_BUF, + OUTPUT_MODULE_SET_OUTPUT_WORD, + OUTPUT_MODULE_SET_OUTPUT_FLAGS, + OUTPUT_MODULE_CLEAR_OUTPUT_FLAGS, + OUTPUT_MODULE_TOGGLE_OUTPUT_FLAGS, + OUTPUT_MODULE_MAX_TRANSACTION_TYPE + +}; + +class COutputTransaction +{ +public: + quint32 mOutputsWord; + unsigned char mOutputsBuf[4]; + int mOutputTransaction; + + COutputTransaction& operator=(const COutputTransaction& a); +}; + +class CExtIOThread : public QObject, public CAnalogInputModule, public CInputModule, public COutputModule +{ + Q_OBJECT +public: + explicit CExtIOThread(); + + unsigned int BindPointers(CInputModule *InputModule, COutputModule *OutputModule, CAnalogInputModule *AnalogInputModule, int AnalogChannel); + bool IsThreadRunning(); + + + unsigned int StopAcquisition(); + bool IsAnalogModueDetected(); + + //Input module interface + virtual unsigned int GetInputs(); + virtual unsigned int GetInputBuf(); + + //Output module interface + virtual unsigned int SetOutput(unsigned char* buffer); + virtual unsigned int SetOutput(quint32 buffer); + virtual unsigned int SetOutputFlags(quint32 Flags); + virtual unsigned int ClearOutputFlags(quint32 Flags); + virtual unsigned int ToggleOutputFlags(quint32 Flags); + + + //Mixed module interface + virtual unsigned int GetAnalogInput(int Channel, int *data); + virtual unsigned int GetAnalogInput(int Channel,double &data); + +#ifdef OUTPUT_EXTIO_SAMPLE_RATE + QElapsedTimer mSampleRateTimer; + qint64 GetSampleRate(); + qint64 mDelay; +#endif + +private: + CInputModule *mInputModule; + COutputModule *mOutputModule; + CAnalogInputModule *mAnalogInputModule; + + QElapsedTimer mDigitalInputsPeriodTimer,mAnalogInputsTimer; + + QMutex mMutex; + + unsigned int mCurInputs; + int mCurAnalogInput; + int mCurAnalogChannel; + + quint32 mCurOutputsWord; +// quint32 mRequestedOutputWord; + unsigned char mCurOutputsBuf[4]; + int mCurOutputTransaction; + bool mOutputDirty; + bool mAnalogModulePresent; + + bool mRun; + bool mIsRunning; + + QList mOutputTransactionList; + + + +signals: + + + +public slots: + void DoAcquisition(); + +}; + + + +#endif // EXTIOTHREAD_H diff --git a/sources/ExtModules/DI710Driver.cpp b/sources/ExtModules/DI710Driver.cpp new file mode 100644 index 0000000..89736f6 --- /dev/null +++ b/sources/ExtModules/DI710Driver.cpp @@ -0,0 +1,402 @@ +#include "DI710Driver.h" +#include +#include + + +#include +#include // Needed for memset +#include // Needed for the socket functions +#include // Needed for the socket functions +#include + + + +CDI710Driver::CDI710Driver() +{ + mRunThread = true; + mRunning = false; + mPendingOperation = DI710_NO_OPERATION; +} + +unsigned int CDI710Driver::OpenDevice(QString IPAdress, int Port) +{ + +// int status; +// struct addrinfo host_info; // The struct that getaddrinfo() fills up with data. +// struct addrinfo *host_info_list; // Pointer to the to the linked list of host_info's. + +// // The MAN page of getaddrinfo() states "All the other fields in the structure pointed +// // to by hints must contain either 0 or a null pointer, as appropriate." When a struct +// // is created in c++, it will be given a block of memory. This memory is not nessesary +// // empty. Therefor we use the memset function to make sure all fields are NULL. +// memset(&host_info, 0, sizeof host_info); + +// std::cout << "Setting up the structs..." << std::endl; + +// host_info.ai_family = AF_UNSPEC; // IP version not specified. Can be both. +// host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP. + +// // Now fill up the linked list of host_info structs with google's address information. +// status = getaddrinfo("www.google.com", "80", &host_info, &host_info_list); +// // getaddrinfo returns 0 on succes, or some other value when an error occured. +// // (translated into human readable text by the gai_gai_strerror function). +// if (status != 0) std::cout << "getaddrinfo error" << gai_strerror(status) ; + + +// std::cout << "Creating a socket..." << std::endl; +// int socketfd ; // The socket descripter +// socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype, +// host_info_list->ai_protocol); +// if (socketfd == -1) std::cout << "socket error " ; + + +// std::cout << "Connect()ing..." << std::endl; +// status = connect(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen); +// if (status == -1) std::cout << "connect error" ; + + +// std::cout << "send()ing message..." << std::endl; +// char *msg = "GET / HTTP/1.1\nhost: www.google.com\n\n"; +// int len; +// ssize_t bytes_sent; +// len = strlen(msg); +// bytes_sent = send(socketfd, msg, len, 0); + +// std::cout << "Waiting to recieve data..." << std::endl; +// ssize_t bytes_recieved; +// char incomming_data_buffer[1000]; +// bytes_recieved = recv(socketfd, incomming_data_buffer,1000, 0); +// // If no data arrives, the program will just wait here until some data arrives. +// if (bytes_recieved == 0) std::cout << "host shut down." << std::endl ; +// if (bytes_recieved == -1)std::cout << "recieve error!" << std::endl ; +// std::cout << bytes_recieved << " bytes recieved :" << std::endl ; +// incomming_data_buffer[bytes_recieved] = '\0' ; +// std::cout << incomming_data_buffer << std::endl; +// std::cout << "Receiving complete. Closing socket..." << std::endl; +// freeaddrinfo(host_info_list); +// close(socketfd); + + + + + + + + + + mDataQIPAddress.setAddress(IPAdress); + mDataQPort = Port; + mTCPSocket.setSocketOption(QAbstractSocket::LowDelayOption,1); + + mTCPSocket.connectToHost(IPAdress,Port); + + if(mTCPSocket.waitForConnected(5000) == true) + { + qDebug("DI710 device Connected"); + return SetupDevice(); + return DI710_RET_OK; + } + + return DI710_RET_ERR_MODULE_OFFLINE; +} + +void CDI710Driver::Run() +{ + bool Run = true; + int Operation; + mRunning = true; + QElapsedTimer timer; + timer.start(); + + qDebug("DataQ thread started"); + + while(Run) + { + + mTCPSocket.waitForReadyRead(200); + if(mTCPSocket.bytesAvailable() >= 2) + { +// QByteArray data = mTCPSocket.read(2); +// qint16 temp; +// QDataStream stream(&data,QIODevice::ReadOnly); +// stream.device()->seek(0); +// stream >> temp; + + + + + char data[2]; + quint16 temp = 0; + mTCPSocket.read(data,2); + // data[3] = 0; + + temp = data[1]; + temp <<= 8; + temp += data[0]; + + mMutex.lockForWrite(); + mCurData = (int)temp; + mMutex.unlock(); + qDebug() << QByteArray(data,2).toHex() << " : " << temp; + //qDebug() << timer.elapsed(); + // qDebug() << mTCPSocket.bytesAvailable(); + timer.start(); + + } + + mMutex.lockForRead(); + //Run = mRunThread; + Operation = mPendingOperation; + mPendingOperation = DI710_NO_OPERATION; + mMutex.unlock(); + + + switch(Operation) + { + case DI710_NO_OPERATION: + { + break; + } + case DI710_STOP_ACQUISITION_OPERATION: + { + SendStopAcquisitionFrame(); +// qDebug("DataQ stop acquisition operation executed"); + break; + } + case DI710_START_ACQUISITION_OPERATION: + { + SendStartAcquisitionFrame(); +// qDebug("Dataq start acquisition operation executed"); + break; + } + case DI710_STOP_THREAD_OPERATION: + { + SendStopAcquisitionFrame(); + Run = false; +// qDebug("Dataq stop thread operation executed"); + break; + } + case DI710_INVALID_OPERATION: + { + qDebug("Dataq invalid operation..."); + break; + } + } + } + + mMutex.lockForWrite(); + mRunning = false; + mMutex.unlock(); +// qDebug("DataQ thread stopped"); +} + +int CDI710Driver::GetAnalogData(int channel) +{ + Q_UNUSED(channel) + + int data = 0XDEADBEEF; + mMutex.lockForRead(); + data = mCurData; + mMutex.unlock(); + + return data; + +} + +unsigned int CDI710Driver::SetupDevice() +{ + + mTCPSocket.readAll(); + + QByteArray data; + + + if(SendStopAcquisitionFrame() != DI710_RET_OK) + return DI710_RET_CANNOT_CONFIGURE; + + + + data.clear(); + data.append((char)0); + data.append("X00"); + mTCPSocket.write(data); + if(mTCPSocket.waitForReadyRead(1000) == true) + { + qDebug() << mTCPSocket.readAll(); + } + else + { + return DI710_RET_CANNOT_CONFIGURE; + } + + data.clear(); + data.append((char)0); + data.append("M000E"); + mTCPSocket.write(data); + if(mTCPSocket.waitForReadyRead(1000) == true) + { + qDebug() << mTCPSocket.readAll(); + } + else + { + return DI710_RET_CANNOT_CONFIGURE; + } + + data.clear(); + data.append((char)0); + data.append("L00F001"); + mTCPSocket.write(data); + if(mTCPSocket.waitForReadyRead(1000) == true) + { + qDebug() << mTCPSocket.readAll(); + } + else + { + return DI710_RET_CANNOT_CONFIGURE; + } + + data.clear(); + data.append((char)0); + data.append("C01"); + mTCPSocket.write(data); + if(mTCPSocket.waitForReadyRead(1000) == true) + { + qDebug() << mTCPSocket.readAll(); + } + else + { + return DI710_RET_CANNOT_CONFIGURE; + } + + + //Check if we can start... + if(SendStartAcquisitionFrame() != DI710_RET_OK) + return DI710_RET_CANNOT_CONFIGURE; + + //stop for the moment... + if(SendStopAcquisitionFrame() != DI710_RET_OK) + return DI710_RET_CANNOT_CONFIGURE; + +// mTCPSocket.setReadBufferSize(2); + + + return DI710_RET_OK; +} + +int CDI710Driver::SendStopAcquisitionFrame() +{ + bool done = false; + QByteArray data; + data.clear(); + data.append((char)0); + data.append("T0"); + mTCPSocket.setReadBufferSize(0); + mTCPSocket.readAll(); + mTCPSocket.write(data); + + QByteArray rxdata; + rxdata.clear(); + while(done == false) + { + + if(mTCPSocket.waitForReadyRead(1000) == true) + { + rxdata.append(mTCPSocket.readAll()); + + if(rxdata.contains("T0")) + { + done = true; + } + +// qDebug() << rxdata; + } + else + { + return DI710_RET_CANNOT_CONFIGURE; + } + } + + + + return DI710_RET_OK; +} + +int CDI710Driver::SendStartAcquisitionFrame() +{ + bool done = false; + QByteArray data; + data.clear(); + data.append((char)0); + data.append("S3"); + mTCPSocket.setReadBufferSize(0); + mTCPSocket.write(data); + + QByteArray rxdata; + rxdata.clear(); + while(done == false) + { + if(mTCPSocket.waitForReadyRead(1000) == true) + { + + rxdata.append(mTCPSocket.read(1)); + if(rxdata.contains("S3")) + { + done = true; +// qDebug() << rxdata; + } + + } + else + { + qDebug() << rxdata; + return DI710_RET_CANNOT_CONFIGURE; + } + } + +// mTCPSocket.setReadBufferSize(2); + + return DI710_RET_OK; +} + +void CDI710Driver::StopThread() +{ +// mMutex.lockForWrite(); +// mRunThread = false; +// mMutex.unlock(); + mMutex.lockForWrite(); + mPendingOperation = DI710_STOP_THREAD_OPERATION; + mMutex.unlock(); +} + +bool CDI710Driver::IsThreadRunning() +{ + bool ret; + mMutex.lockForRead(); + ret = mRunning; + mMutex.unlock(); + + return ret; +} + +unsigned int CDI710Driver::StartAcquisition() +{ + mMutex.lockForWrite(); + mPendingOperation = DI710_START_ACQUISITION_OPERATION; + mMutex.unlock(); + return DI710_RET_OK; +} + +unsigned int CDI710Driver::StopAcquisition() +{ + mMutex.lockForWrite(); + mPendingOperation = DI710_STOP_ACQUISITION_OPERATION; + mMutex.unlock(); + return DI710_RET_OK; +} + +unsigned int CDI710Driver::GetAnalogInput(int Channel, int *Data) +{ + Q_UNUSED(Channel) + *Data = GetAnalogData(0); + return DI710_RET_OK; +} diff --git a/sources/ExtModules/DI710Driver.h b/sources/ExtModules/DI710Driver.h new file mode 100644 index 0000000..dc1430e --- /dev/null +++ b/sources/ExtModules/DI710Driver.h @@ -0,0 +1,82 @@ +#ifndef DI710DRIVER_H +#define DI710DRIVER_H +#include "GlobalDefine.h" +//#include +#include +#include +#include +#include + + +#include +#include + +#define DI710_TCP_PORT 10001 + +enum eDI710RetValue +{ + DI710_RET_OK, + DI710_RET_ERR_INVALID_POINTER, + DI710_RET_ERR_MODULE_OFFLINE, + DI710_RET_ERR_MODULE_TYPE_MISMATCH, + DI710_RET_MODULE_ALREADY_OPENED, + DI710_RET_CANNOT_CONFIGURE +}; + +enum eDI710Operations +{ + DI710_NO_OPERATION, + DI710_STOP_ACQUISITION_OPERATION, + DI710_START_ACQUISITION_OPERATION, + DI710_STOP_THREAD_OPERATION, + DI710_INVALID_OPERATION +}; + +class CDI710Driver : /*public QObject, */public CAnalogInputModule +{ + //Q_OBJECT +public: + CDI710Driver(); + + + unsigned int OpenDevice(QString IPAdress,int Port); + int GetAnalogData(int channel); + void StopThread(); + bool IsThreadRunning(); + unsigned int StartAcquisition(); + unsigned int StopAcquisition(); + virtual unsigned int GetAnalogInput(int Channel, int *Data); + + + + + +private: + + unsigned int SetupDevice(); + bool mRunThread; + QReadWriteLock mMutex; + QTcpSocket mTCPSocket; + int mCurData; + int mPendingOperation; + bool mRunning; + QHostAddress mDataQIPAddress; + int mDataQPort; + + int SendStopAcquisitionFrame(); + int SendStartAcquisitionFrame(); + + + + + +public slots: + void Run(); +// void DeviceSocketConnected(); +// void DeviceSocketDisconnected(); +// void DeviceSocketError(QAbstractSocket::SocketError); +// void DataAvailable(); + +}; + +#endif // DI710DRIVER_H diff --git a/sources/ExtModules/ExternalIOMgr.cpp b/sources/ExtModules/ExternalIOMgr.cpp new file mode 100644 index 0000000..0a5b4f9 --- /dev/null +++ b/sources/ExtModules/ExternalIOMgr.cpp @@ -0,0 +1,263 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe haut niveau de gestion des modules d'entrées/sorties externes (Sealevel). + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "ExternalIOMgr.h" +#include "ZTconfigmgr.h" +#ifndef WINDOWS_OS +#include "Seaio430driver.h" +#include "Seaio440driver.h" +#include "Seaio470driver.h" +#endif +#include "EngLog.h" + +CExternalIOMgr::CExternalIOMgr(): + mNbOpenedModules(0) +{ +} +CExternalIOMgr::~CExternalIOMgr() +{ + for(int i = 0; i < mExternalModulesList.size(); i++) + { + if(mExternalModulesList.at(i)) + delete mExternalModulesList.at(i); + } + + mExternalModulesList.clear(); + mExternalIODriver.CloseSeaMaxInterface(); +} + + + +void CExternalIOMgr::DestroyModule() +{ +} + +unsigned int CExternalIOMgr::InitExternalIO() +{ + if(mExternalIODriver.OpenSeaMaxInterface(CZTConfigMgr::instance()->GetExtIOIPAddress()) == RET_ERROR) + { + CEngLog::instance()->AddLogString("Impossible de se connecter aux modules d'entrées/sorties externes",1); + return EXTIO_MGR_RET_ERR_CANNOT_CONNECT; + } + + //Cycle the interface initialization. This prevents the communication + //failure in case the app is recovering from a crash. + mExternalIODriver.CloseSeaMaxInterface(); + usleep(500000); + if(mExternalIODriver.OpenSeaMaxInterface(CZTConfigMgr::instance()->GetExtIOIPAddress()) == RET_ERROR) + { + CEngLog::instance()->AddLogString("Impossible de se connecter aux modules d'entrées/sorties externes",1); + return EXTIO_MGR_RET_ERR_CANNOT_CONNECT; + } + + //Open each module and make shure the configuration matches the slave address + QList * ModulesList = 0; + int i; + + //Parse list extracted from config file and create modules instances. + ModulesList = CZTConfigMgr::instance()->GetExtIOModulesConfigList(); + for(i = 0; i < ModulesList->size(); i++) + { + + switch(ModulesList->at(i).ModuleType) + { + case EXT_IO_TYPE_430: + { + CSeaIO430Module *NewModule = new CSeaIO430Module(); + + unsigned int Ret = NewModule->OpenModule(ModulesList->at(i).ModuleSlaveAddress,mExternalIODriver.GetSeaMaxInterfacePtr(),ModulesList->at(i).ModuleID); + + switch(Ret) + { + case EXT_MOD_RET_MODULE_ALREADY_OPENED: + case EXT_MOD_RET_ERR_INVALID_POINTER: + { + return EXTIO_MGR_RET_ERR_CANNOT_OPEN_MODULE; + break; + } + case EXT_MOD_RET_ERR_MODULE_OFFLINE: + { + return EXTIO_MGR_RET_ERR_MOD_OFFLINE; + break; + } + case EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH: + { + return EXTIO_MGR_RET_ERR_MOD_TYPE_MISMATCH; + break; + } + case EXTIO_MGR_RET_OK: + { + mExternalModulesList.append(NewModule); + mNbOpenedModules++; + break; + } + default: + { + CEngLog::instance()->AddLogString("CExternalIOMgr::InitExternalIO. Erreur non gérée...",1); + return EXTIO_MGR_RET_ERR_CANNOT_OPEN_MODULE; + } + } + break; + } + case EXT_IO_TYPE_440: + { + CSeaIO440Module *NewModule = new CSeaIO440Module(); + unsigned int Ret = NewModule->OpenModule(ModulesList->at(i).ModuleSlaveAddress,mExternalIODriver.GetSeaMaxInterfacePtr(),ModulesList->at(i).ModuleID); + + switch(Ret) + { + case EXT_MOD_RET_MODULE_ALREADY_OPENED: + case EXT_MOD_RET_ERR_INVALID_POINTER: + { + return EXTIO_MGR_RET_ERR_CANNOT_OPEN_MODULE; + break; + } + case EXT_MOD_RET_ERR_MODULE_OFFLINE: + { + return EXTIO_MGR_RET_ERR_MOD_OFFLINE; + break; + } + case EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH: + { + return EXTIO_MGR_RET_ERR_MOD_TYPE_MISMATCH; + break; + } + case EXTIO_MGR_RET_OK: + { + mExternalModulesList.append(NewModule); + mNbOpenedModules++; + break; + } + default: + { + CEngLog::instance()->AddLogString("CExternalIOMgr::InitExternalIO. Erreur non gérée...",1); + return EXTIO_MGR_RET_ERR_CANNOT_OPEN_MODULE; + } + } + break; + } + case EXT_IO_TYPE_470: + { + CSeaIO470Module *NewModule = new CSeaIO470Module(); + unsigned int Ret = NewModule->OpenModule(ModulesList->at(i).ModuleSlaveAddress,mExternalIODriver.GetSeaMaxInterfacePtr(),ModulesList->at(i).ModuleID); + + switch(Ret) + { + case EXT_MOD_RET_MODULE_ALREADY_OPENED: + case EXT_MOD_RET_ERR_INVALID_POINTER: + { + return EXTIO_MGR_RET_ERR_CANNOT_OPEN_MODULE; + break; + } + case EXT_MOD_RET_ERR_MODULE_OFFLINE: + { + return EXTIO_MGR_RET_ERR_MOD_OFFLINE; + break; + } + case EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH: + { + return EXTIO_MGR_RET_ERR_MOD_TYPE_MISMATCH; + break; + } + case EXTIO_MGR_RET_OK: + { + mExternalModulesList.append(NewModule); + mNbOpenedModules++; + break; + } + default: + { + CEngLog::instance()->AddLogString("CExternalIOMgr::InitExternalIO. Erreur non gérée...",1); + return EXTIO_MGR_RET_ERR_CANNOT_OPEN_MODULE; + } + } + break; + } + case EXT_IO_TYPE_INVALID: + default: + { + //TODO: Manage this erroneous occurence ??? + //this would be a programming error :( + break; + } + } + + } + + return EXTIO_MGR_RET_OK; +} + +CExternalIOModule * CExternalIOMgr::GetModuleHandle(eExternalModuleType_t ModuleType, unsigned int ModuleID) +{ + CExternalIOModule* ModulePtr; + for(int i = 0; i < mExternalModulesList.size(); i++) + { + ModulePtr = mExternalModulesList.at(i); +// qDebug("TYPE %d",ModulePtr->GetType()); +// qDebug("ID %d",ModulePtr->GetID()); + if(ModulePtr->GetType() == ModuleType && ModulePtr->GetID() == ModuleID) + { + return ModulePtr; + } + } + return 0; +} + +unsigned int CExternalIOMgr::InitIO() +{ + return InitExternalIO(); +} + +CIOModule * CExternalIOMgr::GetModule(eIOModuleType_t type, unsigned int ModuleID) +{ + switch(type) + { + case IO_MODULE_INPUT_TYPE: + { + return (CSeaIO430Module*)GetModuleHandle(EXT_IO_TYPE_430,ModuleID); + break; + } + case IO_MODULE_OUTPUT_TYPE: + { + return (CSeaIO440Module *)GetModuleHandle(EXT_IO_TYPE_440,ModuleID); + + break; + } + case IO_MODULE_MIXED_TYPE: + { + return (CSeaIO470Module *)GetModuleHandle(EXT_IO_TYPE_470,ModuleID); + break; + } + default: + case IO_MODULE_INVALID_TYPE: + { + return 0; + break; + } + } + + +} diff --git a/sources/ExtModules/ExternalIOMgr.h b/sources/ExtModules/ExternalIOMgr.h new file mode 100644 index 0000000..2b3c072 --- /dev/null +++ b/sources/ExtModules/ExternalIOMgr.h @@ -0,0 +1,67 @@ +#ifndef EXTERNALIOMGR_H +#define EXTERNALIOMGR_H + +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#ifndef WINDOWS_OS +#include "seamaxlin.h" + +#include "Seaiolibinterface.h" +#endif +#include "Externaliomodule.h" +#include "QList" +#include "IOManager.h" + +class CExternalIOMgr : public CIOManager +{ +public: + + + CExternalIOMgr(); + ~CExternalIOMgr(); + + unsigned int InitExternalIO(void); + CExternalIOModule *GetModuleHandle(eExternalModuleType_t ModuleType, unsigned int ModuleID); + + virtual CIOModule *GetModule(eIOModuleType_t type, unsigned int ModuleID); + virtual unsigned int InitIO(); + void DestroyModule(); + + +private: +#ifndef WINDOWS_OS + CSeaMaxLin *mSeaMaxInterface; //The SeaMax driver interface used to communicate with the modules + CSeaIOLibInterface mExternalIODriver; + unsigned int mNbOpenedModules; + QList mExternalModulesList; +#endif + +}; + +#endif // EXTERNALIOMGR_H diff --git a/sources/ExtModules/Externaliomodule.cpp b/sources/ExtModules/Externaliomodule.cpp new file mode 100644 index 0000000..41578a8 --- /dev/null +++ b/sources/ExtModules/Externaliomodule.cpp @@ -0,0 +1,127 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe d'interface avec le driver de communication des modules ethernet + externes (Sealevel). + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Externaliomodule.h" +#include + +CExternalIOModule::CExternalIOModule(): + mIsOpened(false) +{ + +} +CExternalIOModule::~CExternalIOModule() +{ +} + +#ifndef WINDOWS_OS +unsigned int CExternalIOModule::SetModuleDriverPtr(CSeaMaxLin *DriverPtr) +{ + if(DriverPtr == 0) + return RET_ERROR; + + mModuleDriverPtr = DriverPtr; + return RET_OK; +} + +//unsigned int CExternalIOModule::OpenModule(unsigned int SlaveAddress,SeaMaxLin *DriverPtr, unsigned int ModuleID) +//{ +//// if(mIsOpened == true) +//// return EXT_MOD_RET_MODULE_ALREADY_OPENED; + +////// if(SetModuleDriverPtr(DriverPtr) == RET_ERROR) +////// { +////// CEngLog::instance()->AddLogString("Erreur Fatale: CExternalIOModule::OpenModule, le pointeur DriverPtr est invalide",1); +////// return EXT_MOD_RET_ERR_INVALID_POINTER; +////// } + +//// unsigned short ModuleType; +//// int Ret; +//// mModuleAddress = SlaveAddress; +//// mModuleID = ModuleID; +//// // Ret = mModuleDriverPtr->Ioctl(mModuleAddress,IOCTL_GET_EXT_CONFIG,&ModuleType); +//// Ret = SeaMaxLinIoctl(DriverPtr,(unsigned char)SlaveAddress,IOCTL_GET_EXT_CONFIG,&ModuleType); +//// if(Ret != 0) +//// { +//// CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: CExternalIOModule::OpenModule, aucune réponse du module Type: %d, addresse: %d, ID: %d",mModuleType,SlaveAddress,ModuleID),1); +//// return EXT_MOD_RET_ERR_MODULE_OFFLINE; +//// } + +//// if((eExternalModuleType_t)ModuleType != mModuleType) +//// { +//// CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: le module à l'addresse %d est configuré de type %d mais est plutôt de type %d",SlaveAddress,(unsigned short)mModuleType,ModuleType),1); +//// mIsOpened = false; +//// return EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH; +//// } + +//// CEngLog::instance()->AddLogString(QString("").sprintf("Module ouvert avec succès. Addresse: %d, Type: %d, ID: %d",SlaveAddress,(unsigned short)mModuleType,ModuleID),3); +//// mIsOpened = true; + +//// return EXT_MOD_RET_OK; +// return EXT_MOD_RET_ERR_MODULE_OFFLINE; + + +//} + +unsigned int CExternalIOModule::OpenModule(unsigned int SlaveAddress,CSeaMaxLin *DriverPtr, unsigned int ModuleID) +{ + if(mIsOpened == true) + return EXT_MOD_RET_MODULE_ALREADY_OPENED; + + if(SetModuleDriverPtr(DriverPtr) == RET_ERROR) + { + CEngLog::instance()->AddLogString("Erreur Fatale: CExternalIOModule::OpenModule, le pointeur DriverPtr est invalide",1); + return EXT_MOD_RET_ERR_INVALID_POINTER; + } + + unsigned short buf[50]; + unsigned short ModuleType; + int Ret; + mModuleAddress = SlaveAddress; + mModuleID = ModuleID; + Ret = mModuleDriverPtr->Ioctl(mModuleAddress,IOCTL_READ_COMM_PARAM/*IOCTL_GET_EXT_CONFIG*/,buf); + if(Ret != 0) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: CExternalIOModule::OpenModule, aucune réponse du module Type: %d, addresse: %d, ID: %d",mModuleType,SlaveAddress,ModuleID),1); + return EXT_MOD_RET_ERR_MODULE_OFFLINE; + } + ModuleType = buf[0]; + if((eExternalModuleType_t)ModuleType != mModuleType) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: le module à l'addresse %d est configuré de type %d mais est plutôt de type %d",SlaveAddress,(unsigned short)mModuleType,ModuleType),1); + mIsOpened = false; + return EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH; + } + + CEngLog::instance()->AddLogString(QString("").sprintf("Module ouvert avec succès. Addresse: %d, Type: %d, ID: %d",SlaveAddress,(unsigned short)mModuleType,ModuleID),3); + mIsOpened = true; + + return EXT_MOD_RET_OK; + + +} +#endif diff --git a/sources/ExtModules/Externaliomodule.h b/sources/ExtModules/Externaliomodule.h new file mode 100644 index 0000000..31b841c --- /dev/null +++ b/sources/ExtModules/Externaliomodule.h @@ -0,0 +1,63 @@ +#ifndef EXTERNALIOMODULE_H +#define EXTERNALIOMODULE_H +#include "GlobalDefine.h" +#ifndef WINDOWS_OS +#include "seamaxlin.h" +#endif +#include "IOModule.h" + +typedef enum eExternalModuleType +{ + EXT_IO_TYPE_430 = 430, + EXT_IO_TYPE_440 = 440, + EXT_IO_TYPE_470 = 470, + EXT_IO_TYPE_INVALID = 0 +}eExternalModuleType_t; + +enum eExternalModuleRetValue +{ + EXT_MOD_RET_OK, + EXT_MOD_RET_ERR_INVALID_POINTER, + EXT_MOD_RET_ERR_MODULE_OFFLINE, + EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH, + EXT_MOD_RET_MODULE_ALREADY_OPENED, + EXT_MOD_RET_WRONG_ANALOG_CONFIGURATION +}; + +class CExternalIOModule +{ +public: + + CExternalIOModule(); + virtual ~CExternalIOModule(); +#ifndef WINDOWS_OS + unsigned int SetModuleDriverPtr(CSeaMaxLin *DriverPtr); + virtual unsigned int OpenModule(unsigned int SlaveAddress,CSeaMaxLin *DriverPtr, unsigned int ModuleID); +// unsigned int OpenModule(unsigned int SlaveAddress,SeaMaxLin *DriverPtr, unsigned int ModuleID); + + eExternalModuleType_t GetType(void){return mModuleType;} + unsigned int GetID(void){return mModuleID;} +#endif + + +protected: + bool mIsOpened; + #ifndef WINDOWS_OS + CSeaMaxLin *mModuleDriverPtr; + unsigned int mModuleAddress; + unsigned int mModuleID; + eExternalModuleType_t mModuleType; + + seaio_type_t mSeaIOModuleType; + address_loc_t mRegisterStart; + address_range_t mRegisterRange; +#endif + + + // pseaMaxModule->Read(2,type,start,range,&data[0]); + + + +}; + +#endif // EXTERNALIOMODULE_H diff --git a/sources/ExtModules/Seaio430driver.cpp b/sources/ExtModules/Seaio430driver.cpp new file mode 100644 index 0000000..3a4e26b --- /dev/null +++ b/sources/ExtModules/Seaio430driver.cpp @@ -0,0 +1,105 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Pilote d'interface avec un module d'entrées discrètes SEAIO430 + Hérite de CInputModule et réimplémente les fonctions virtuelles d'accès aux + données du module d'entrées externes. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Seaio430driver.h" +#include +#include +#include "EngLog.h" + +CSeaIO430Module::CSeaIO430Module(CSeaMaxLin *ModuleDriverPtr) +{ + mModuleDriverPtr = ModuleDriverPtr; + mModuleType = EXT_IO_TYPE_430; +} + +unsigned int CSeaIO430Module::GetInputs(unsigned char *DataBuf) +{ + if(DataBuf == 0) + return RET_ERROR; + + if(ReadInputs() == RET_ERROR) + return RET_ERROR; + + memcpy(DataBuf,mInputBuffer,4/*sizeof(mInputBuffer)*/); + return RET_OK; +} + +unsigned int CSeaIO430Module::GetInputs() +{ + unsigned int Buf; + + mMutex.lock(); + ReadInputs(); + memcpy(&Buf,mInputBuffer,sizeof(mInputBuffer)); + mMutex.unlock(); + return Buf; +} + +unsigned int CSeaIO430Module::GetInputBuf() +{ + unsigned int Buf; + + mMutex.lock(); + ReadInputs(); + memcpy(&Buf,mInputBuffer,sizeof(mInputBuffer)); + mMutex.unlock(); + return Buf; +} + +//unsigned char * CSeaIO430Module::GetInputs() +//{ +// return &mInputBuffer[0]; +//} + +unsigned int CSeaIO430Module::ReadInputs() +{ + if(mModuleDriverPtr == 0) + return RET_ERROR; + + mSeaIOModuleType = D_INPUTS; //Input type + mRegisterStart = 1; //Start with input 1 + mRegisterRange = 32; //Read all the 32 inputs + + int RET = mModuleDriverPtr->Read(mModuleAddress,mSeaIOModuleType,mRegisterStart,mRegisterRange,&mInputBuffer[0]); + if(RET < 0) + { + CEngLog::instance()->AddLogString(QString("SeaIO430 module read FAILED: %d").arg(RET)); + } + + return RET_OK; + +} +unsigned int CSeaIO430Module::ReadAndGetInputs(unsigned char *DataBuf) +{ + if(ReadInputs() == 0) + return RET_ERROR; + + memcpy(DataBuf,mInputBuffer,sizeof(mInputBuffer)); + return RET_OK; +} diff --git a/sources/ExtModules/Seaio430driver.h b/sources/ExtModules/Seaio430driver.h new file mode 100644 index 0000000..7bf04ca --- /dev/null +++ b/sources/ExtModules/Seaio430driver.h @@ -0,0 +1,55 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SEAIO430DRIVER_H +#define SEAIO430DRIVER_H + +#include "GlobalDefine.h" +#include "Externaliomodule.h" +#include "seamaxlin.h" +#include "InputModule.h" +#include + + +class CSeaIO430Module : public CExternalIOModule, public CInputModule +{ +public: + CSeaIO430Module(CSeaMaxLin *ModuleInterfacePtr = 0); + + virtual unsigned int GetInputs(); + virtual unsigned int GetInputBuf(); + unsigned int ReadInputs(void); + unsigned int ReadAndGetInputs(unsigned char *DataBuf); + +private: + unsigned char mInputBuffer[4]; //Buffer de données pour les entrées discrètes. + //On utilise un array simple pour éviter l'allocation dynamique. + unsigned int GetInputs(unsigned char *DataBuf); + QMutex mMutex; +}; + +#endif // SEAIO430DRIVER_H diff --git a/sources/ExtModules/Seaio440driver.cpp b/sources/ExtModules/Seaio440driver.cpp new file mode 100644 index 0000000..352f0dd --- /dev/null +++ b/sources/ExtModules/Seaio440driver.cpp @@ -0,0 +1,101 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Pilote d'interface avec un module d'entrées discrètes SEAIO440 + Hérite de COutputModule et réimplémente les fonctions virtuelles d'accès aux + données du module de sorties externes. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Seaio440driver.h" +#include "EngLog.h" + +CSeaIO440Module::CSeaIO440Module(CSeaMaxLin *ModuleDriverPtr) +{ + mModuleDriverPtr = ModuleDriverPtr; + mModuleType = EXT_IO_TYPE_440; + mOutputBuffer = 0; +} + +CSeaIO440Module::~CSeaIO440Module() +{ +// qDebug("clear outputs"); +// quint32 out = 0; +// SetOutput(out); +} + +unsigned int CSeaIO440Module::SetOutput(unsigned char *OutputBuffer) +{ + if(mModuleDriverPtr == 0) + return RET_ERROR; + + if(OutputBuffer == 0) + return RET_ERROR; + + mSeaIOModuleType = COILS; //Output type + mRegisterStart = 1; //Start with input 1 + mRegisterRange = 32; //Set all the 32 outputs + + int RET = mModuleDriverPtr->Write(mModuleAddress,mSeaIOModuleType,mRegisterStart,mRegisterRange,&OutputBuffer[0]); + if(RET < 0) + { + CEngLog::instance()->AddLogString(QString("SeaIO440 Modbus write FAILED: %d").arg(RET)); + } + + return RET_OK; +} + +unsigned int CSeaIO440Module::SetOutput(quint32 buffer) +{ + unsigned char buf[4]; + memcpy(&buf[0],&buffer,4); + mOutputBuffer = buffer; + + SetOutput(buf); + return RET_OK; +} + +unsigned int CSeaIO440Module::SetOutputFlags(quint32 FlagMask) +{ + + mOutputBuffer |= FlagMask; + SetOutput(mOutputBuffer); + + return RET_OK; +} + +unsigned int CSeaIO440Module::ClearOutputFlags(quint32 FlagMask) +{ + mOutputBuffer &= ~FlagMask; + SetOutput(mOutputBuffer); + + return RET_OK; +} + +unsigned int CSeaIO440Module::ToggleOutputFlags(quint32 FlagMask) +{ + mOutputBuffer ^= FlagMask; + SetOutput(mOutputBuffer); + + return RET_OK; +} diff --git a/sources/ExtModules/Seaio440driver.h b/sources/ExtModules/Seaio440driver.h new file mode 100644 index 0000000..ff8cae2 --- /dev/null +++ b/sources/ExtModules/Seaio440driver.h @@ -0,0 +1,53 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SEAIO440DRIVER_H +#define SEAIO440DRIVER_H + +#include "GlobalDefine.h" +#include "Externaliomodule.h" +#include "seamaxlin.h" +#include "OutputModule.h" + + +class CSeaIO440Module : public CExternalIOModule, + public COutputModule +{ +public: + CSeaIO440Module(CSeaMaxLin *ModuleInterfacePtr = 0); + virtual ~CSeaIO440Module(); + virtual unsigned int SetOutput(unsigned char* buffer); + virtual unsigned int SetOutput(quint32 buffer); + virtual unsigned int SetOutputFlags(quint32 Flags); + virtual unsigned int ClearOutputFlags(quint32 Flags); + virtual unsigned int ToggleOutputFlags(quint32 Flags); + + unsigned int mOutputBuffer; + +}; + +#endif // SEAIO440DRIVER_H diff --git a/sources/ExtModules/Seaio470driver.cpp b/sources/ExtModules/Seaio470driver.cpp new file mode 100644 index 0000000..e3c860c --- /dev/null +++ b/sources/ExtModules/Seaio470driver.cpp @@ -0,0 +1,152 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Pilote d'interface avec un module d'entrées discrètes SEAIO470 + Hérite de CAnalogInputModule et réimplémente les fonctions virtuelles d'accès aux + données du module mixte externes. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Seaio470driver.h" + +CSeaIO470Module::CSeaIO470Module(CSeaMaxLin *ModuleDriverPtr) +{ + mModuleDriverPtr = ModuleDriverPtr; + mModuleType = EXT_IO_TYPE_470; + mCurInput = 0; +} + +//Reimplement the base class OpenModule() since the 470 module needs some more operations than the 430 and 440 modules. +// +unsigned int CSeaIO470Module::OpenModule(unsigned int SlaveAddress, CSeaMaxLin *DriverPtr, unsigned int ModuleID) +{ + if(mIsOpened == true) + return EXT_MOD_RET_MODULE_ALREADY_OPENED; + + if(SetModuleDriverPtr(DriverPtr) == RET_ERROR) + { + CEngLog::instance()->AddLogString("Erreur Fatale: CExternalIOModule::OpenModule, le pointeur DriverPtr est invalide",1); + return EXT_MOD_RET_ERR_INVALID_POINTER; + } + + unsigned short buf[50]; + unsigned short ModuleType; + int Ret; + mModuleAddress = SlaveAddress; + mModuleID = ModuleID; + Ret = mModuleDriverPtr->Ioctl(mModuleAddress,IOCTL_READ_COMM_PARAM,buf); + if(Ret != 0) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: CExternalIOModule::OpenModule, aucune réponse du module Type: %d, addresse: %d, ID: %d",mModuleType,SlaveAddress,ModuleID),1); + return EXT_MOD_RET_ERR_MODULE_OFFLINE; + } + ModuleType = buf[0]; + if((eExternalModuleType_t)ModuleType != mModuleType) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur: le module à l'addresse %d est configuré de type %d mais est plutôt de type %d",SlaveAddress,(unsigned short)mModuleType,ModuleType),1); + mIsOpened = false; + return EXT_MOD_RET_ERR_MODULE_TYPE_MISMATCH; + } + + //Force analog inputs config. + // + adda_config ModuleConfig; + ModuleConfig.device.channel_mode = CURRENT_LOOP; + ModuleConfig.device.channel_mode = ANALOG_OFFSET; + ModuleConfig.channels.ch_1 = ZERO_TO_TEN; + ModuleConfig.channels.ch_2 = ZERO_TO_TEN; + ModuleConfig.channels.ch_3 = ZERO_TO_TEN; + ModuleConfig.channels.ch_4 = ZERO_TO_TEN; + ModuleConfig.channels.ch_5 = ZERO_TO_TEN; + ModuleConfig.channels.ch_6 = ZERO_TO_TEN; + ModuleConfig.channels.ch_7 = ZERO_TO_TEN; + ModuleConfig.channels.ch_8 = ZERO_TO_TEN; + + +// ModuleConfig.device.channel_mode = SINGLE_ENDED; +// ModuleConfig.device.channel_mode = ANALOG_OFFSET; +// ModuleConfig.channels.ch_1 = ZERO_TO_FIVE; +// ModuleConfig.channels.ch_2 = ZERO_TO_FIVE; +// ModuleConfig.channels.ch_3 = ZERO_TO_FIVE; +// ModuleConfig.channels.ch_4 = ZERO_TO_FIVE; +// ModuleConfig.channels.ch_5 = ZERO_TO_FIVE; +// ModuleConfig.channels.ch_6 = ZERO_TO_FIVE; +// ModuleConfig.channels.ch_7 = ZERO_TO_FIVE; +// ModuleConfig.channels.ch_8 = ZERO_TO_FIVE; + int result = mModuleDriverPtr->Ioctl(mModuleAddress,IOCTL_SET_ADDA_CONFIG,&ModuleConfig); + if(result < 0) + { +// qDebug("Impossible de configurer le module 470"); + } + + + CEngLog::instance()->AddLogString(QString("").sprintf("Module ouvert avec succès. Addresse: %d, Type: %d, ID: %d",SlaveAddress,(unsigned short)mModuleType,ModuleID),3); + mIsOpened = true; + + return EXT_MOD_RET_OK; +} + +unsigned int CSeaIO470Module::ReadInput(int Channel) +{ + if(mModuleDriverPtr == 0) + return RET_ERROR; + + if(Channel < 1 || Channel > SEAIO_470_MAX_CHANNEL) + return RET_ERROR; + + mSeaIOModuleType = INPUTREG; //Input type + mRegisterStart = Channel; //Assign channel to read + mRegisterRange = 1; //only 1 input + + + int result = mModuleDriverPtr->Read(mModuleAddress,INPUTREG,Channel,1,&mInputBuffer[0]); + if(result < 0) + { +// qDebug("impossible de lire l'entrée ananogique"); + } + + //We know the module is configured in 0 - 10V range (see the Open() function). + mCurInput = (mInputBuffer[0] << 8) + (mInputBuffer[1]); + + return RET_OK; +} + +unsigned int CSeaIO470Module::GetAnalogInput(int Channel, int *Data) +{ + if(ReadInput(Channel) == RET_ERROR) + return RET_ERROR; + + *Data = mCurInput; + + return RET_OK; +} + +unsigned int CSeaIO470Module::GetAnalogInput(int Channel, double &Data) +{ + if(ReadInput(Channel) == RET_ERROR) + return RET_ERROR; + + Data = (double)mCurInput; + + return RET_OK; +} diff --git a/sources/ExtModules/Seaio470driver.h b/sources/ExtModules/Seaio470driver.h new file mode 100644 index 0000000..aac2570 --- /dev/null +++ b/sources/ExtModules/Seaio470driver.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SEAIO470DRIVER_H +#define SEAIO470DRIVER_H + +#include "GlobalDefine.h" +#include "Externaliomodule.h" +#include "seamaxlin.h" +#include "AnalogInputModule.h" + +#define SEAIO_470_MAX_CHANNEL 8 + + +class CSeaIO470Module : public CExternalIOModule, + public CAnalogInputModule +{ +public: + CSeaIO470Module(CSeaMaxLin *ModuleInterfacePtr = 0); + unsigned int OpenModule(unsigned int SlaveAddress, CSeaMaxLin *DriverPtr, unsigned int ModuleID); + + unsigned int GetAnalogInput(int Channel, int *Data); + virtual unsigned int GetAnalogInput(int Channel, double &Data); + +private: + unsigned int ReadInput(int Channel); + + char mInputBuffer[2]; + int mCurInput; + + + +}; + +#endif // SEAIO470DRIVER_H diff --git a/sources/ExtModules/Seaiolibinterface.cpp b/sources/ExtModules/Seaiolibinterface.cpp new file mode 100644 index 0000000..e9680fd --- /dev/null +++ b/sources/ExtModules/Seaiolibinterface.cpp @@ -0,0 +1,77 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe qui offre une interface avec la librairie de SeaLevel pour les modules + externes. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Seaiolibinterface.h" + + + +CSeaIOLibInterface::CSeaIOLibInterface(): + mIsOpened(false) +{ +} + +CSeaIOLibInterface::~CSeaIOLibInterface() +{ + mSeaMaxInterface.Close(); +} +void CSeaIOLibInterface::CloseSeaMaxInterface() +{ + mSeaMaxInterface.Close(); +} + +unsigned int CSeaIOLibInterface::OpenSeaMaxInterface(QString MasterModuleIP) +{ + QString Address = "sealevel_tcp://"; + Address += MasterModuleIP; + CEngLog::instance()->AddLogString(QString("Connexion aux modules externes : " + Address),1); + if(mSeaMaxInterface.Open(Address.toAscii().data()) < 0) + { + + //Try to connect 2 times... sometimes the first connection is not successful + if(mSeaMaxInterface.Open(Address.toAscii().data()) < 0) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Connexion aux modules externes impossible à l'adresse: %s",Address.toAscii().data()),1); + mIsOpened = false; + return RET_ERROR; + } + + } + + CEngLog::instance()->AddLogString("Connexion aux modules externes établie",3); + mIsOpened = true; + + return RET_OK; +} + +CSeaMaxLin *CSeaIOLibInterface::GetSeaMaxInterfacePtr() +{ + if(mIsOpened == true) + return &mSeaMaxInterface; + else + return NULL; +} diff --git a/sources/ExtModules/Seaiolibinterface.h b/sources/ExtModules/Seaiolibinterface.h new file mode 100644 index 0000000..7ef58c6 --- /dev/null +++ b/sources/ExtModules/Seaiolibinterface.h @@ -0,0 +1,53 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121213 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SEAIOLIBINTERFACE_H +#define SEAIOLIBINTERFACE_H +#include "GlobalDefine.h" +#include "seamaxlin.h" +#include + +class CSeaIOLibInterface +{ +public: + + CSeaIOLibInterface(); + ~CSeaIOLibInterface(); + + unsigned int OpenSeaMaxInterface(QString MasterModuleIP); + CSeaMaxLin * GetSeaMaxInterfacePtr(void); + void CloseSeaMaxInterface(); + +private: + + CSeaMaxLin mSeaMaxInterface; + bool mIsOpened; + + +}; + +#endif // SEAIOLIBINTERFACE_H diff --git a/sources/ExtModules/USB4704Definitions.h b/sources/ExtModules/USB4704Definitions.h new file mode 100644 index 0000000..9496ba2 --- /dev/null +++ b/sources/ExtModules/USB4704Definitions.h @@ -0,0 +1,33 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef USB4704DEFINITIONS_H +#define USB4704DEFINITIONS_H + +#define USB4704_DAQNAVI_NAME "USB-4704" + +#endif // PCI1756DEFINITIONS_H diff --git a/sources/ExtModules/USB4704Interface.cpp b/sources/ExtModules/USB4704Interface.cpp new file mode 100644 index 0000000..d8451ed --- /dev/null +++ b/sources/ExtModules/USB4704Interface.cpp @@ -0,0 +1,148 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe d'interface avec la carte d'I/O PCI1756. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "USB4704Interface.h" +#include "USB4704Definitions.h" +#include +#include + +CUSB4704Interface::CUSB4704Interface(): + mOpened(false) +{ + mInputBuf = 0; +} + +CUSB4704Interface::~CUSB4704Interface() +{ + mInputCtrl->Dispose(); +} + + +unsigned int CUSB4704Interface::OpenInterface() +{ + + if(mOpened) + return RET_ERROR; + + + + CEngLog::instance()->AddLogString(QString("Ouverture du module USB externe :"),3); + + mInputCtrl = AdxInstantAiCtrlCreate(); + ICollection *supportedDevices = mInputCtrl->getSupportedDevices(); + if(supportedDevices->getCount() == 0) + { + CEngLog::instance()->AddLogString("L'ouverture du module USB a échouée (Aucun module n'est installé)",1); + return RET_ERROR; + } + + bool found = false; + for (int i = 0; i < supportedDevices->getCount(); i++) + { + DeviceTreeNode const &node = supportedDevices->getItem(i); + QString DeviceDescription(QString::fromWCharArray(node.Description)); + qDebug() << "Device Nbr: " << node.DeviceNumber << " : "<< DeviceDescription; + if(QString::fromWCharArray(node.Description).contains(USB4704_DAQNAVI_NAME)) + { + if(mInputCtrl->setSelectedDevice(DeviceInformation(node.Description)) != Success) + { + CEngLog::instance()->AddLogString("L'ouverture du module USB externe a échouée (Module occupé)",1); + supportedDevices->Dispose(); + mInputCtrl->Dispose(); + return RET_ERROR; + } + CEngLog::instance()->AddLogString(QString("Module USB externe initialisé :") + QString::fromWCharArray(node.Description),3); + + found = true; + break; + } + } + if(found == false) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur. Incohérence du type de module USB externe"),1); + return RET_ERROR; + } + + supportedDevices->Dispose(); + CEngLog::instance()->AddLogString("Module USB externe ouvert avec succès",3); + mOpened = true; + return RET_OK; + +} + +unsigned int CUSB4704Interface::GetAnalogInput(int Channel,int *Data) +{ + if(mOpened == false) + { + *Data = 0; + return RET_ERROR; + } + + int Buf = 0; + + ErrorCode errorCode = Success; + mMutex.lock(); + errorCode = mInputCtrl->Read(Channel,Buf); + mMutex.unlock(); + if(errorCode != Success) + { + qDebug("USB read Error"); + *Data = 0; + return RET_ERROR; + } + + *Data = Buf; + + return RET_OK; +} + +unsigned int CUSB4704Interface::GetAnalogInput(int Channel, double &Data) +{ + if(mOpened == false) + { + Data = 0.0; + return RET_ERROR; + } + + double Buf = 0; + + ErrorCode errorCode = Success; + mMutex.lock(); + errorCode = mInputCtrl->Read(Channel,Buf); + mMutex.unlock(); + if(errorCode != Success) + { + qDebug("USB read Error"); + Data = 0.; + return RET_ERROR; + } + + Data = Buf; + + return RET_OK; +} + diff --git a/sources/ExtModules/USB4704Interface.h b/sources/ExtModules/USB4704Interface.h new file mode 100644 index 0000000..19274b5 --- /dev/null +++ b/sources/ExtModules/USB4704Interface.h @@ -0,0 +1,63 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20140828 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef USB4704INTERFACE_H +#define USB4704INTERFACE_H + +#include +#include "GlobalDefine.h" +#include "AnalogInputModule.h" +#include + +using namespace Automation::BDaq; + +class CUSB4704Interface : public CAnalogInputModule +{ +public: + + + + CUSB4704Interface(); + ~CUSB4704Interface(); + + unsigned int OpenInterface(void); + virtual unsigned int GetAnalogInput(int Channel, int *Data); + virtual unsigned int GetAnalogInput(int Channel, double &Data); + + + + +private: + + InstantAiCtrl *mInputCtrl; + bool mOpened; + QMutex mMutex; + unsigned int mInputBuf; + +}; + +#endif // USB4704INTERFACE_H diff --git a/sources/GlobalDefine.h b/sources/GlobalDefine.h new file mode 100644 index 0000000..1bf62df --- /dev/null +++ b/sources/GlobalDefine.h @@ -0,0 +1,84 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#ifndef GLOBAL_DEFINE +#define GLOBAL_DEFINE + +//#include +#include "EngLog.h" + +//Screen resolution. +#define SCREEN_RES_WIDTH 1024 +#define SCREEN_RES_HEIGHT 768 + +//Train parameters +#define MR_BOGIE_LENGTH 1.52 //meters +#define MPM_BOGIE_LENGTH 2.0 //meters + +//The amount of millisecs to wait for the sensors to stabilize before +//beginning the execution of ZT application +#define ZT_EXTERNAL_WATCHDOG_TIMEOUT 10000 //10 seconds +#define ZT_EXTERNAL_WATCHDOG_PULSE_TIME 1000 //1 second +#define ZT_SM_MAX_NB_PG_CALIB_PASSAGES 50 //Nb maximal de passages pour calibration du pneu guidage +#define ZT_DEFAULT_DETECTION_RANK 1 //The rank of a detection when there is a count error + + +//To be able to run the application with no PCI card installed. +//This will skip PCI card initialization. +//#define NO_PCI_CARD_INSTALLED + +#define DEFAULT_PASSWORD "zonetest" +#define BASE_FILE_MAGICNBR 0xDEADBEEF +#define TRAINLOG_FILE_MAGICNBR BASE_FILE_MAGICNBR + 1 + + +//Misc definitions +#define MAX_LOG_FILE_COUNT 100 +#define MAX_LOG_DIR_SIZE (qint64)1073741824 //in bytes = 1 GB +#define EXT_DIGITAL_INPUTS_ACQUISITION_PERIOD 100 //milliseconds +#define EXT_ANALOG_INPUT_ACQUISITION_PERIOD 200000 //nanoseconds +#define FILESYSTEM_FORCED_SYNC_TIMEOUT (qint64)2400000 //2.4 million milliseconds = 40 minutes +#define MAX_ENGINEERING_LOG_FILESIZE (qint32)1000000 //~1Mb +//#define OUTPUT_EXTIO_SAMPLE_RATE + +#define USE_DAQNAVI_LIB + +#define USE_NETWORKING +#define TCP_SERVER_PORT 1234 +#define CUSTOM_KERNEL_INSTALLED //Custom kernel with modified serial.c to disable hardware FIFO. + + +//Debug defs +//#define LOG_RAM_USAGE + +//General purpose return values. +enum eGeneralRetValue +{ + RET_OK, + RET_ERROR +}; + +#endif diff --git a/sources/GuiElements/AnalogGraphItem.cpp b/sources/GuiElements/AnalogGraphItem.cpp new file mode 100644 index 0000000..172a59e --- /dev/null +++ b/sources/GuiElements/AnalogGraphItem.cpp @@ -0,0 +1,412 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe d'affichage d'un graphique analogique (vitesse du train, sondes lazer, + etc.) La fonction SetData permet d'associer la liste de points à tracer. La + fonction DisplayData() permet de fixer le timespan à afficher. La fonction détermine + quels points sont dans le span et crée une liste de lignes qui sont ensuite affichés + dans la fonction de rappel paint(). + + Utilisée dans la page de visualisation des passages de train. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131024 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "AnalogGraphItem.h" +#include +#include +#include +#include + +CAnalogGraphItem::CAnalogGraphItem(QGraphicsItem *Parent) +{ + setParentItem(Parent); + mDataSet = 0; + mStartTime = mStopTime = 0; + mDataValid = false; + mLabel = new QGraphicsTextItem(this); + + mGraphPixmap = new QPixmap(boundingRect().width(),boundingRect().height()); + mHorizLine = 0; + mYOffset = 0; + + + +} +CAnalogGraphItem::~CAnalogGraphItem() +{ + delete mGraphPixmap; + + if(mHorizLine != 0) + delete mHorizLine; +} + +void CAnalogGraphItem::SetData(QList *DataList) +{ + mDataSet = DataList; + //Build the lines list +} + +unsigned int CAnalogGraphItem::DisplayData(quint64 StartTime, quint64 StopTime) +{ + + mPainterPath = QPainterPath(); + + if(mDataSet == 0) + return RET_OK; + + if(mDataSet->isEmpty()) + return RET_ERROR; + + quint64 MinTime = mDataSet->first()->mTime; + quint64 MaxTime = mDataSet->last()->mTime; + + if(StartTime >= StopTime) + return RET_ERROR; + if(StartTime < MinTime) + return RET_ERROR; + if(StopTime > MaxTime) + return RET_ERROR; + + + + quint64 TimeSpan = StopTime - StartTime; + + + + mStartTime = StartTime; + mStopTime = StopTime; + + + //Find the index of the first and last point included in the timespan. + int StartIndex = 0, StopIndex = 0; + int i = 0; + bool StartFound = false, StopFound = false; + + quint64 StartDrawTime = StartTime ,EndDrawTime = StopTime; + + if(StartTime < mAbsoluteStartTime) + StartDrawTime = mAbsoluteStartTime; + + + if(StopTime > mAbsoluteEndTime) + EndDrawTime = mAbsoluteEndTime; + + + while(StartFound == false || StopFound == false) + { + if(i >= mDataSet->size()) + { + qDebug("GraphItem::Array overflow while searching for time index"); + return RET_ERROR; + } + + quint64 CurTime = mDataSet->at(i)->mTime; + if(CurTime <= StartDrawTime) + { + StartIndex = i; + StartFound = true; + } + if(CurTime >= EndDrawTime && !StopFound) + { + StopIndex = i; + StopFound = true; + } + + i++; + } + + //Find the Y scaling (vertical) + qreal MaxValue = std::numeric_limits::min(); + qreal MinValue = std::numeric_limits::max(); + + for(int i = 0; i < mDataSet->size(); i++) + { + qreal CurValue = mDataSet->at(i)->mValue; + + if(CurValue != -1 && CurValue != 0) //-1 is the value for "NO DATA" and 0 is not a valid value + { + if(MaxValue < CurValue) + MaxValue = CurValue; + if(MinValue > CurValue) + MinValue = CurValue; + } + } + + if(MinValue < 0) + { + MinValue *= -1; + MinValue += 1; + mYOffset = MinValue; + + for(int i = 0; i < mDataSet->size(); i++) + { + mDataSet->at(i)->mValue += MinValue; + } + MaxValue += MinValue; + MinValue = 1; + } + + //Build the lines list + mLinesList.clear(); + qreal Width = boundingRect().width(); + qreal Height = boundingRect().height(); + qreal tick = (Width)/TimeSpan; //pixels per microsec + qreal YFactor = (Height-2)/(MaxValue - MinValue); + mYScaling = YFactor; + mXScaling = tick; + + + qreal X1,X2,Y1,Y2; + + //There is no quadratic interpolation, simply draw a straight + //line between the points. When needed, execute a linear + //interpolation when one of the two points creating a line is + //outside the timespan (at both extremities of the view). + + // P2 P3 + // P1 | *-------* | + // * | | P4 + // | | * + // |<----timespan---->| + // Start End + // + //Interpolation needed between Start->P2 and P3->End so there is no + //"gap" in the graph between the first/last points and the view. + + + for(int i = StartIndex; i < StopIndex; i++) + { + if(mDataSet->at(i)->mValue != -1) //-1 is the value for "NO DATA". + { + QLine NewLine; + + //Check if interpolation is needed at the left + //of the span + if(mDataSet->at(i)->mTime < StartTime) + { + //Interpolate Y value at StartTime + qreal x1 = mDataSet->at(i)->mTime; + qreal y1 = mDataSet->at(i)->mValue - MinValue; + qreal x2 = mDataSet->at(i+1)->mTime; + qreal y2 = mDataSet->at(i+1)->mValue - MinValue; + + // Y = mX + B + qreal DeltaX = x2 - x1; + qreal DeltaY = y2 - y1; + + qreal m = DeltaY/DeltaX; + + Y1 = (qreal)StartTime*m; + + Y1 += (y2 - m*x2); + + X1 = 0; + + } + else + { + X1 = mDataSet->at(i)->mTime - StartTime; + Y1 = mDataSet->at(i)->mValue - MinValue; + } + + //Check if interpolation is needed at the right + //of the span + if(mDataSet->at(i+1)->mTime > StopTime) + { + //Interpolate Y value at StopTime + qreal x1 = mDataSet->at(i)->mTime; + qreal y1 = mDataSet->at(i)->mValue - MinValue; + qreal x2 = mDataSet->at(i+1)->mTime; + qreal y2 = mDataSet->at(i+1)->mValue - MinValue; + + qreal DeltaX = x2 - x1; + qreal DeltaY = y2 - y1; + + qreal m = DeltaY/DeltaX; + + Y2 = (qreal)(StopTime)*m; + + Y2 += (y2 - m*x2); + + X2 = StopTime - StartTime; + } + else + { + X2 = mDataSet->at(i+1)->mTime - StartTime; + Y2 = mDataSet->at(i+1)->mValue - MinValue; + } + + Y1 = Height - Y1*YFactor; + Y2 = Height - Y2*YFactor; + + NewLine.setLine(X1*tick,Y1-1,X2*tick,Y2-1); + mLinesList.append(NewLine); + +// if(mPainterPath.isEmpty()) +// mPainterPath.moveTo(X1*tick,Y1-1); + +// mPainterPath.lineTo(X2*tick,Y2-1); + } + } + + if(mHorizLine != 0) + { + Y1 = (mHorizLineYPos+mYOffset-MinValue); + Y1 = Height - Y1*YFactor; + mHorizLine->setP1(QPoint(0,Y1-1)); + mHorizLine->setP2(QPoint((mDataSet->at(StopIndex)->mTime - StartTime)*tick,Y1-1)); + } + + mDataValid = true; + +//#ifndef WINDOWS_OS + mGraphPixmap->fill(QColor(245, 245, 255)); + QPainter *painter = new QPainter(mGraphPixmap); + painter->drawLines(mLinesList); + delete painter; +//#endif + + update(); + + return RET_OK; +} + +qreal CAnalogGraphItem::GetValueForTime(quint64 time) +{ + qreal value = 0.0; + for(int i = 0; i < mDataSet->size()-1; i++) + { + if(time >= mDataSet->at(i)->mTime && time < mDataSet->at(i+1)->mTime) + { + value = mDataSet->at(i)->mValue - mYOffset; + break; + } + } + + QString label = mLabelTitle; + label += "\n"; + label += QString().sprintf("%.2f",value); + + mLabel->setPlainText(label); + mLabel->setPos(mLabel->pos().x(),boundingRect().height()/2 - mLabel->boundingRect().height()/2); + update(); + return value; +} + +void CAnalogGraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + if(mDataValid == false) + return ; + if(mDataSet == 0) + return; + if(mDataSet->size() == 0) + return; + +// painter->setClipRect(option->exposedRect); + + +// QPen pen; +// pen.setWidth(1); + +//// pen.setColor(Qt::red); +//// painter->setPen(pen); +//// painter->drawRect(boundingRect()); + +// pen.setColor(Qt::black); +// painter->setPen(pen); + +//#ifdef WINDOWS_OS +// painter->drawLines(mLinesList); +//#else + + + painter->drawPixmap(0,0,*mGraphPixmap); + if(mHorizLine != 0) + { + painter->setPen(QPen(Qt::red)); + painter->drawLine(*mHorizLine); + } + + //painter->drawPath(mPainterPath); + + +//#endif +// for(int i = 0; i < mLinesList.size(); i++) +// { +// painter->drawEllipse(mLinesList.at(i).p1(),2,2); +// } + +} + + +//void CGraphItem::UpdateDisplay() +//{ +// DisplayData(mStartIndex,mStopIndex); +// update(); +//} + +void CAnalogGraphItem::AddHorizontalLine(qreal YPosition) +{ + if(mHorizLine == 0) + mHorizLine = new QLine(); + + mHorizLineYPos = YPosition; +} + +void CAnalogGraphItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); +} + + +void CAnalogGraphItem::mouseReleaseEvent( QGraphicsSceneMouseEvent * event) +{ + event->ignore(); +} + +void CAnalogGraphItem::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + //mBackgroundRect->setRect(boundingRect()); + delete mGraphPixmap; + mGraphPixmap = new QPixmap(boundingRect().width(),boundingRect().height()); + DisplayData(mStartTime,mStopTime); +} +void CAnalogGraphItem::SetLabel(QString label,int Offset) +{ + QFont font; + font.setBold(true); + mLabelTitle = label; + mLabel->setFont(font); + mLabel->setPlainText(label); + mLabel->setPos(-Offset,boundingRect().height()/2 - mLabel->boundingRect().height()/2); +} + +CGraphAnalogDataPair::CGraphAnalogDataPair(qreal Value, quint64 Time): + mValue(Value), + mTime(Time) +{ +} diff --git a/sources/GuiElements/AnalogGraphItem.h b/sources/GuiElements/AnalogGraphItem.h new file mode 100644 index 0000000..b666f1f --- /dev/null +++ b/sources/GuiElements/AnalogGraphItem.h @@ -0,0 +1,60 @@ +#ifndef ANALOGGRAPHITEM_H +#define ANALOGGRAPHITEM_H + +#include +#include +#include +#include +#include +#include + +class CGraphAnalogDataPair +{ +public: + CGraphAnalogDataPair(qreal Value, quint64 Time); + qreal mValue; //changed from qint32 + quint64 mTime; +}; + +class CAnalogGraphItem : public QGraphicsWidget +{ + Q_OBJECT +public: + CAnalogGraphItem(QGraphicsItem *Parent = 0); + ~CAnalogGraphItem(); + + QList *mDataSet; + QGraphicsRectItem *mBackgroundRect; + + unsigned int DisplayData(quint64 StartTime, quint64 StopTime); + void SetData(QList *DataList); + void SetLabel(QString label,int Offset); + void SetAbsoluteLimits(quint64 StartTime,quint64 EndTime){mAbsoluteStartTime = StartTime; mAbsoluteEndTime = EndTime;} + void AddHorizontalLine(qreal YPosition); + qreal GetValueForTime(quint64 time); + + virtual void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + +private: + + bool mDataValid; + quint64 mStartTime, mStopTime, mAbsoluteEndTime,mAbsoluteStartTime; + QVector mLinesList; + QString mLabelTitle; + QGraphicsTextItem *mLabel; + QPixmap *mGraphPixmap; + qreal mYScaling,mXScaling; + qreal mYOffset; + qreal mHorizLineYPos; + QLine *mHorizLine; + + QPainterPath mPainterPath; + + + +}; + +#endif // ANALOGGRAPHITEM_H diff --git a/sources/GuiElements/CDVItem.cpp b/sources/GuiElements/CDVItem.cpp new file mode 100644 index 0000000..431c29d --- /dev/null +++ b/sources/GuiElements/CDVItem.cpp @@ -0,0 +1,144 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Élément graphique qui affiche un CDV. L'affichage change en fonction de l'état + du CDV (libre, occupé, itinéraire commandé). + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130524 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "CDVItem.h" +#include +#include "ZTData.h" +#include +#include "CDV.h" + + + +CCDVItem::CCDVItem(CCDV *CDVPtr,QGraphicsItem *Parent) +{ + if(Parent != 0) + setParentItem(Parent); + + mCDVPtr = CDVPtr; + mCDVFreeBrush = new QBrush(Qt::gray); + mCDVITICommandedBrush = new QBrush(Qt::darkGreen); + mCDVOccupiedBrush = new QBrush(QColor(255,128,0)); + + mCDVState = CDV_STATE_FREE; + mCurBrush = mCDVFreeBrush; + + setGeometry(0,0,90,20); +} + +CCDVItem::~CCDVItem() +{ + delete mCDVFreeBrush; + delete mCDVITICommandedBrush; + delete mCDVOccupiedBrush; +} + +void CCDVItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + QRectF CDVRect = rect(); + + painter->setBrush(*mCurBrush); + painter->setPen(Qt::black); + painter->drawRect(CDVRect); + +// QRectF textRect(CDVRect.adjusted(-3,-3,-3,-3)); +// painter->drawRect(textRect); + + int flags = Qt::AlignHCenter | Qt::AlignVCenter/* | Qt::TextWordWrap*/; + + QFont font; +// font.setPointSizeF(9.5); + font.setPixelSize(13); + painter->setPen(Qt::black); + painter->setFont(font); + painter->drawText(CDVRect, flags, mCDVLabel); + +} + +unsigned int CCDVItem::SetParameters(QString Label/*, unsigned int posx, unsigned int posy*/) +{ + mCDVLabel = Label; +// setPos(posx,posy); + return RET_OK; +} + +unsigned int CCDVItem::UpdateState() +{ + return SetState(mCDVPtr->GetCDVState()); +} + +unsigned int CCDVItem::SetState(unsigned int State) +{ + if(State >= CDV_STATE_UNKNOWN) + return RET_ERROR; + if(mCDVState == State) + return RET_OK; + + mCDVState = State; + switch(State) + { + case CDV_STATE_OCCUPIED: + { + mCurBrush = mCDVOccupiedBrush; + break; + } + case CDV_STATE_FREE: + { + mCurBrush = mCDVFreeBrush; + break; + } + case CDV_STATE_ITI_CMD: + { + mCurBrush = mCDVITICommandedBrush; + break; + } + } + update(rect()); + + return RET_OK; +} + +void CCDVItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + emit CDVRightClicked(this); + } +} + +void CCDVItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} + +CCDV *CCDVItem::GetCDV() +{ + return mCDVPtr; +} diff --git a/sources/GuiElements/CDVItem.h b/sources/GuiElements/CDVItem.h new file mode 100644 index 0000000..646e388 --- /dev/null +++ b/sources/GuiElements/CDVItem.h @@ -0,0 +1,67 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "GlobalDefine.h" +#include +#include + + + +#ifndef CDVITEM_H +#define CDVITEM_H + +class CCDV; + +class CCDVItem : public QGraphicsWidget +{ + Q_OBJECT + +public: + CCDVItem(CCDV *CDVPtr,QGraphicsItem *Parent = 0); + ~CCDVItem(); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + unsigned int SetParameters(QString Label/*, unsigned int posx, unsigned int posy*/); + virtual unsigned int SetState(unsigned int State); + unsigned int UpdateState(); + + CCDV *GetCDV(); + +protected: + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + + QString mCDVLabel; + unsigned int mCDVState; + QBrush *mCDVFreeBrush, *mCDVITICommandedBrush, *mCDVOccupiedBrush,*mCurBrush; + + CCDV *mCDVPtr; //Pointer to the CDV object + +signals: + void CDVRightClicked(CCDVItem*); +}; + +#endif // CDVITEM_H diff --git a/sources/GuiElements/EngineeringPage.cpp b/sources/GuiElements/EngineeringPage.cpp new file mode 100644 index 0000000..9cd2a69 --- /dev/null +++ b/sources/GuiElements/EngineeringPage.cpp @@ -0,0 +1,1129 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page d'ingénierie. Contient des information spécifique à l'ingénierie et + permet d'éxécuter des tâches réservées à l'ingénierie. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "EngineeringPage.h" +#include +#include "GlobalDefine.h" +#include +#include +#include "Zonetest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "ZTLog.h" +#include "TrainLogFileMgr.h" +#include +#include +#include "RamMonitor.h" +//#include + +CEngineeringPage::~CEngineeringPage() +{ + for(int Btn = 0; Btn < GENERIC_OUTPUT_NB_ID; Btn++) + delete OutputToggleBtn[Btn]; + + for(int led = 0; led < GENERIC_INPUT_NB_ID; led++) + delete mInputLeds[led]; + + for(int led = 0; led < mInputLedsCDV.size(); led++) + delete mInputLedsCDV.at(led); + +} + +CEngineeringPage::CEngineeringPage(QGraphicsWidget *Parent) +{ + setParentItem(Parent); + + mProgramHandle = 0; + mPCIIO = 0; + mStation = 0; + mDisablePassword = false; + mInputMasks = 0; + mCDVList = 0; + + mInputModulePtr = 0; + + mPasswordPrompt = new CPasswordPrompt(Parent); + mPasswordPrompt->setZValue(1); + mPasswordPrompt->hide(); + connect(mPasswordPrompt,SIGNAL(PasswordValid()),this,SLOT(PasswordValid())); + connect(mPasswordPrompt,SIGNAL(Canceled()),this,SLOT(PasswordInvalid())); + + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QBrush BackgroundBrush(QColor(245, 245, 255,200)); + mBackgroundRect->setBrush(BackgroundBrush); + + mCancelButton = new CTextButtonWidget("Fermer"); + mCancelButton->setParentItem(this); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mConvertCSVButton = new CTextButtonWidget("Convertir .CSV"); + mConvertCSVButton->setParentItem(this); + mConvertCSVButton->setPos(350,280); + connect(mConvertCSVButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + + mTestButton = new CTextButtonWidget("Test"); + mTestButton->setParentItem(this); + mTestButton->setPos(350,310); + connect(mTestButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + + mInfoUpdateTimer = new QTimer(); + mInfoUpdateTimer->setSingleShot(false); + mInfoUpdateTimer->stop(); + connect(mInfoUpdateTimer,SIGNAL(timeout()),this,SLOT(UpdateInfo())); + + mRAMUsageText = new QGraphicsTextItem(this); + mRAMUsageText->setPos(50,20); + + mPCIIODataText = new QGraphicsTextItem(this); + mPCIIODataText->setPos(50,50); + + mExternalInputDataText = new QGraphicsTextItem(this); + mExternalInputDataText->setPos(50,80); + + + mIntLazerProbeValue = new QGraphicsTextItem(this); + mIntLazerProbeValue->setPos(400,20); + mIntLazerProbeValue->setPlainText("Sonde Lazer Int: ?"); + + mExtLazerProbeValue = new QGraphicsTextItem(this); + mExtLazerProbeValue->setPos(400,50); + mExtLazerProbeValue->setPlainText("Sonde Lazer Ext: ?"); + + mAnalogSDFValue = new QGraphicsTextItem(this); + mAnalogSDFValue->setPos(400,80); + mAnalogSDFValue->setPlainText("4-20mA SDF: ?"); + + + mExportZT1CSVChkBx = new QCheckBox("Exporter automatiquement CSV ZT1"); + QGraphicsProxyWidget *Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mExportZT1CSVChkBx); + Proxy->setPos(50,110); + connect(mExportZT1CSVChkBx,SIGNAL(stateChanged(int)),this,SLOT(ZT1AutoCSVCheckBoxChanged(int))); + + mExportZT2CSVChkBx = new QCheckBox("Exporter automatiquement CSV ZT2"); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mExportZT2CSVChkBx); + Proxy->setPos(50,140); + connect(mExportZT2CSVChkBx,SIGNAL(stateChanged(int)),this,SLOT(ZT2AutoCSVCheckBoxChanged(int))); + + mHighResLogging = new QCheckBox("Log haute resolution"); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mHighResLogging); + Proxy->setPos(50,170); + connect(mHighResLogging,SIGNAL(stateChanged(int)),this,SLOT(HighResLogCheckBoxChanged(int))); + + mKeepAllMPM10Logs = new QCheckBox("Conserver tous les Logs MPM10"); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mKeepAllMPM10Logs); + Proxy->setPos(350,110); + connect(mKeepAllMPM10Logs,SIGNAL(stateChanged(int)),this,SLOT(KeepAllMPM10LogsCheckBoxChanged(int))); + + mKeepZT1Logs = new QCheckBox("Conserver les Logs ZT1"); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mKeepZT1Logs); + Proxy->setPos(350,140); + connect(mKeepZT1Logs,SIGNAL(stateChanged(int)),this,SLOT(KeepZT1LogsCheckBoxChanged(int))); + + mKeepZT2Logs = new QCheckBox("Conserver les Logs ZT2"); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mKeepZT2Logs); + Proxy->setPos(350,170); + connect(mKeepZT2Logs,SIGNAL(stateChanged(int)),this,SLOT(KeepZT2LogsCheckBoxChanged(int))); + + + QGraphicsTextItem *NbLogFilesLabel = new QGraphicsTextItem(this); + NbLogFilesLabel->setPlainText("Nb. Max passages\nà conserver"); + NbLogFilesLabel->setPos(350,195); + + mNbLogFilesSpinBox = new QSpinBox(); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mNbLogFilesSpinBox); + Proxy->setPos(475,200); + mNbLogFilesSpinBox->resize(70,30); + mNbLogFilesSpinBox->setMinimum(1); + mNbLogFilesSpinBox->setMaximum(1000); + mNbLogFilesSpinBox->setValue(100); + connect(mNbLogFilesSpinBox,SIGNAL(valueChanged(int)),this,SLOT(MaxNbLogFilesChanged(int))); + + + mNbLogsText = new QGraphicsTextItem(this); + mNbLogsText->setPlainText(""); + mNbLogsText->setPos(50,250); + + mDeleteLogsButton = new CTextButtonWidget("Effacer fichiers"); + mDeleteLogsButton->setParentItem(this); + mDeleteLogsButton->setPos(50,280); + connect(mDeleteLogsButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mArchiveLogsButton = new CTextButtonWidget("Archiver fichiers"); + mArchiveLogsButton->setParentItem(this); + mArchiveLogsButton->setPos(200,280); + connect(mArchiveLogsButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mDeleteEngLogBtn = new CTextButtonWidget("Détruire EngLog"); + mDeleteEngLogBtn->setParentItem(this); + mDeleteEngLogBtn->setPos(50,310); + connect(mDeleteEngLogBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mDeleteZTLogButton = new CTextButtonWidget("Détruire ZTLog"); + mDeleteZTLogButton->setParentItem(this); + mDeleteZTLogButton->setPos(200,310); + connect(mDeleteZTLogButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + + mUSBFlashDetectionTxt = new QGraphicsTextItem(this); + mUSBFlashDetectionTxt->setPos(50,340); + mUSBFlashDetectionTxt->setPlainText(""); + + mPGCalibrationSwitch = new CToggleButtonWidget("./Images/Slider_Green.png","./Images/Slider_Red.png",this,"Calibration PG"); + mPGCalibrationSwitch->setPos(730, 150); + mPGCalibrationSwitch->resize(50,30); + connect(mPGCalibrationSwitch,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(PGCalibBtnToggled(CToggleButtonWidget*))); + + mPGTresholdValueSpinBox = new QSpinBox(); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mPGTresholdValueSpinBox); + Proxy->setPos(740,190); + mPGTresholdValueSpinBox->resize(70,30); + mPGTresholdValueSpinBox->setMinimum(1); + mPGTresholdValueSpinBox->setMaximum(2000); + mPGTresholdValueSpinBox->setValue(255); + + mPGNbPassagesForCalibSpinBox = new QSpinBox(); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mPGNbPassagesForCalibSpinBox); + Proxy->setPos(790,150); + mPGNbPassagesForCalibSpinBox->resize(50,30); + mPGNbPassagesForCalibSpinBox->setMinimum(1); + mPGNbPassagesForCalibSpinBox->setMaximum(ZT_SM_MAX_NB_PG_CALIB_PASSAGES); + mPGNbPassagesForCalibSpinBox->setValue(10); + + QGraphicsTextItem *Text = new QGraphicsTextItem(this); + Text->setPos(845,140); + Text->setPlainText("Passages\npour calibration "); + + mPGValueSetBtn = new CTextButtonWidget("Changer Seuil",0,30); + mPGValueSetBtn->setParentItem(this); + mPGValueSetBtn->setPos(820,190); + connect(mPGValueSetBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mCopyCalibValueBtn = new CTextButtonWidget("Copier",0,30); + mCopyCalibValueBtn->setParentItem(this); + mCopyCalibValueBtn->setPos(780,230); + connect(mCopyCalibValueBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + mCopyCalibValueBtn->hide(); + + Text = new QGraphicsTextItem(this); + Text->setPos(710 - 80,190); + Text->setPlainText("Valeur seuil PG: "); + + mCalibResultText = new QGraphicsTextItem(this); + mCalibResultText->setPos(710 - 80,230); + mCalibResultText->setPlainText("Valeur seuil PG calibration: Calib. non effectuée"); + + mActualPGTresholdValueText = new QGraphicsTextItem(this); + mActualPGTresholdValueText->setPos(710 - 80,260); + + +} + +void CEngineeringPage::Init() +{ + QGraphicsTextItem *Label = new QGraphicsTextItem(this); + QFont font; + font.setPointSize(12); + font.setBold(true); + Label->setFont(font); + + Label->setPlainText("Contrôle manuel des TK (ATTENTION !!!)"); + QString ONPixmapFilePath = "./Images/Slider_Green.png"; + QString OFFPixmapFilePath = "./Images/Slider_Red.png"; + QSizeF SlideButtonSize(50,30); + int OriginY = 400, OriginX = 90; + int row = OriginY, col = OriginX; + QString label; + unsigned int ButtonData; + mInputMasks = mStation->GetInputMasks(); + mCDVList = mStation->GetCDVList(); + GenericOutputMasks_t * OutputMasks = mStation->GetOutputMasks(); + Label->setPos(OriginX-30,OriginY-30); + + for(int Btn = 0; Btn < GENERIC_OUTPUT_NB_ID; Btn++) + { + switch(Btn) + { + case GENERIC_OUTPUT_VP1_ID: + { + label = "VP1"; + ButtonData = OutputMasks->OutputVP1Mask; + break; + } + case GENERIC_OUTPUT_VP2_ID: + { + label = "VP2"; + ButtonData = OutputMasks->OutputVP2Mask; + break; + } + case GENERIC_OUTPUT_VP3_ID: + { + label = "VP3"; + ButtonData = OutputMasks->OutputVP3Mask; + break; + } + case GENERIC_OUTPUT_VP4_ID: + { + label = "VP4"; + ButtonData = OutputMasks->OutputVP4Mask; + break; + } + case GENERIC_OUTPUT_VP5_ID: + { + label = "VP5"; + ButtonData = OutputMasks->OutputVP5Mask; + break; + } + case GENERIC_OUTPUT_VP6_ID: + { + row += 40, col = OriginX; + label = "VP6"; + ButtonData = OutputMasks->OutputVP6Mask; + break; + } + case GENERIC_OUTPUT_DPE_ID: + { + label = "PPE"; + ButtonData = OutputMasks->OutputDPEMask; + break; + } + case GENERIC_OUTPUT_DPI_ID: + { + label = "PPI"; + ButtonData = OutputMasks->OutputDPIMask; + break; + } + case GENERIC_OUTPUT_V00_ID: + { + label = "V00"; + ButtonData = OutputMasks->OutputV00Mask; + break; + } + case GENERIC_OUTPUT_VF1_ID: + { + label = "VF1"; + ButtonData = OutputMasks->OutputVF1Mask; + break; + } + case GENERIC_OUTPUT_VF2_ID: + { + label = "VF2"; + ButtonData = OutputMasks->OutputVF2Mask; + row += 40, col = OriginX; + break; + } + case GENERIC_OUTPUT_VF3_ID: + { + label = "VF3"; + ButtonData = OutputMasks->OutputVF3Mask; + break; + } + case GENERIC_OUTPUT_VF4_ID: + { + ButtonData = OutputMasks->OutputVF4Mask; + label = "VF4"; + break; + } + case GENERIC_OUTPUT_VF5_ID: + { + label = "VF5"; + ButtonData = OutputMasks->OutputVF5Mask; + break; + } + case GENERIC_OUTPUT_DPG_ID: + { + label = "DPG"; + ButtonData = OutputMasks->OutputDPGMask; + break; + } + case GENERIC_OUTPUT_DFR_ID: + { + row += 40, col = OriginX; + label = "DFR"; + ButtonData = OutputMasks->OutputDFRMask; + break; + } + case GENERIC_OUTPUT_RF_ID: + { + label = "RF"; + ButtonData = OutputMasks->OutputRFMask; + break; + } + case GENERIC_OUTPUT_VEL_ID: + { + label = "VEL"; + ButtonData = OutputMasks->OutputVELMask; + break; + } + case GENERIC_OUTPUT_VEL2_ID: + { + label = "VEL2"; + ButtonData = OutputMasks->OutputVEL2Mask; + break; + } + case GENERIC_OUTPUT_WP1_ID: + { + label = "WP1"; + ButtonData = OutputMasks->OutputWP1Mask; + break; + } + case GENERIC_OUTPUT_WP2_ID: + { + row += 40, col = OriginX; + label = "WP2"; + ButtonData = OutputMasks->OutputWP2Mask; + break; + } + case GENERIC_OUTPUT_WP3_ID: + { + label = "WP3"; + ButtonData = OutputMasks->OutputWP3Mask; + break; + } + case GENERIC_OUTPUT_WP4_ID: + { + label = "WP4"; + ButtonData = OutputMasks->OutputWP4Mask; + break; + } + case GENERIC_OUTPUT_WP5_ID: + { + label = "WP5"; + ButtonData = OutputMasks->OutputWP5Mask; + break; + } + case GENERIC_OUTPUT_WP6_ID: + { + label = "WP6"; + ButtonData = OutputMasks->OutputWP6Mask; + break; + } + case GENERIC_OUTPUT_DPI2_ID: + { + row += 40, col = OriginX; + label = "PPI2"; + ButtonData = OutputMasks->OutputDPI2Mask; + break; + } + case GENERIC_OUTPUT_DPE2_ID: + { + label = "PPE2"; + ButtonData = OutputMasks->OutputDPE2Mask; + break; + } + case GENERIC_OUTPUT_V002_ID: + { + label = "V002"; + ButtonData = OutputMasks->OutputV002Mask; + break; + } + case GENERIC_OUTPUT_RF2_ID: + { + label = "RF2"; + ButtonData = OutputMasks->OutputRF2Mask; + break; + } + case GENERIC_OUTPUT_PEQ1_ID: + { + label = "PEQ1"; + ButtonData = OutputMasks->OutputPEQ1Mask; + break; + } + case GENERIC_OUTPUT_PEQ2_ID: + { + row += 40, col = OriginX; + label = "PEQ2"; + ButtonData = OutputMasks->OutputPEQ2Mask; + break; + } + case GENERIC_OUTPUT_WATCHDOG_ID: + { + label = "VIGIE"; + ButtonData = OutputMasks->OutputWatchdogMask; + break; + } + } + + OutputToggleBtn[Btn] = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this,label); + OutputToggleBtn[Btn]->setPos(col,row); + OutputToggleBtn[Btn]->resize(SlideButtonSize); + OutputToggleBtn[Btn]->SetData(ButtonData); + connect(OutputToggleBtn[Btn],SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(OutputToggled(CToggleButtonWidget*))); + col += 100; + } + + OriginY = 400, OriginX = 580; + row = OriginY, col = OriginX; + + Label = new QGraphicsTextItem(this); + Label->setFont(font); + Label->setPlainText("État des entrées"); + Label->setPos(OriginX + 10, OriginY - 30); + + + + for(int led = 0; led < GENERIC_INPUT_NB_ID; led++) + { + switch(led) + { + case GENERIC_INPUT_ZT1_S1_ID: + { + label = "ZT1 S1"; + break; + } + case GENERIC_INPUT_ZT1_S2_ID: + { + label = "ZT1 S2"; + break; + } + case GENERIC_INPUT_ZT1_PI_ID: + { + label = "ZT1 PI"; + break; + } + case GENERIC_INPUT_ZT1_PE_ID: + { + label = "ZT1 PE"; + break; + } + case GENERIC_INPUT_ZT1_FN_ID: + { + label = "ZT1 FN"; + break; + } + case GENERIC_INPUT_ZT2_S1_ID: + { + label = "ZT2 S1"; + break; + } + case GENERIC_INPUT_ZT2_PI_ID: + { + label = "ZT2 PI"; + break; + } + case GENERIC_INPUT_ZT2_PE_ID: + { + row += 60, col = OriginX; + label = "ZT2 PE"; + break; + } + case GENERIC_INPUT_ZT1_ITI_ID: + { + label = "ZT1 ITI"; + break; + } + case GENERIC_INPUT_ZT2_ITI_ID: + { + label = "ZT2 ITI"; + break; + } + case GENERIC_INPUT_ZT1_AN_ID: + { + label = "ZT1 AN"; + break; + } + case GENERIC_INPUT_ZT2_AN_ID: + { + label = "ZT2 AN"; + break; + } + case GENERIC_INPUT_ZT1_ARF_ID: + { + label = "ZT1 ARF"; + break; + } + case GENERIC_INPUT_ZT2_ARF_ID: + { + label = "ZT2 ARF"; + break; + } + case GENERIC_INPUT_STATION_ID_0_ID: + { + row += 60, col = OriginX; + label = "ID1"; + break; + } + case GENERIC_INPUT_STATION_ID_1_ID: + { + + label = "ID2"; + break; + } + case GENERIC_INPUT_STATION_ID_2_ID: + { + label = "ID3"; + break; + } + case GENERIC_INPUT_STATION_ID_3_ID: + { + label = "ID4"; + break; + } + } + + mInputLeds[led] = new CLedWidget(label,this); + mInputLeds[led]->setPos(col,row); + + col += 60; + } + + row += 60, col = OriginX; + + for(int led = 0; led < mCDVList->size(); led++) + { + label = mCDVList->at(led)->GetLabel(); + + CLedWidget *NewLedWidget = new CLedWidget(label,this); + NewLedWidget->setPos(col,row); + + if((led+1)%7 == 0) + { + col = OriginX; + row += 60; + } + else + { + col +=60; + } + + mInputLedsCDV.append(NewLedWidget); + } +} + +void CEngineeringPage::BindPointers(CZoneTest *ProgramHandle,CInputModule *InputModulePtr, COutputModule *OutputModulePtr, CPCIIOMgr *PCIIO,CZTSettingsData *ZTSettings,CUSBDriveInterface *USBInterface,CStation *StationPtr,CAnalogInputModule *AnalogInterface) +{ + mProgramHandle = ProgramHandle; + mInputModulePtr = InputModulePtr; + mOutputModulePtr = OutputModulePtr; + + mAnalogInterface = AnalogInterface; + + + mPCIIO = PCIIO; + mZTSettings = ZTSettings; + mUSBInterfacePtr = USBInterface; + mStation = StationPtr; + + mAutoExportZT1CSV = mZTSettings->mAutoExportZT1CSV; + mAutoExportZT2CSV = mZTSettings->mAutoExportZT2CSV; + mExportZT1CSVChkBx->setChecked(mAutoExportZT1CSV); + mExportZT2CSVChkBx->setChecked(mAutoExportZT2CSV); + + mPGTresholdValueSpinBox->setValue(mProgramHandle->GetPGTreshold()); + mPGCalibTresholdValue = mProgramHandle->GetPGTreshold(); + mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold())); +} + +void CEngineeringPage::UpdateInfo() +{ + unsigned int PCIInputs = mPCIIO->GetInputs(); + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + QString String; + QTextStream Stream(&String); + +// Stream.setPadChar('1'); +// Stream.setFieldAlignment(QTextStream::AlignRight); + Stream.setCodec("UTF-8"); + Stream.setIntegerBase(16); +// Stream.setFieldWidth(0); + Stream << QString("Entrées PCI: [0x") << PCIInputs << "] : [0b"; + Stream.setIntegerBase(2); +// Stream.setFieldWidth(16); + Stream << PCIInputs << "]"; + + mPCIIODataText->setPlainText(String); + + unsigned int ExtModuleInputs = mInputModulePtr->GetInputs(); + + String.clear(); + Stream.setIntegerBase(16); +// Stream.setFieldWidth(0); + Stream << QString("Entrées Externes: [0x") << ExtModuleInputs << "] : [0b"; + Stream.setIntegerBase(2); +// Stream.setFieldWidth(32); + Stream << ExtModuleInputs << "]"; + mExternalInputDataText->setPlainText(String); + + if(mUSBInterfacePtr->IsDriveDetected()) + mUSBFlashDetectionTxt->setPlainText(QString().sprintf("Clef USB détectée : %s",mUSBInterfacePtr->GetDrivePath().toLatin1().data())); + else + mUSBFlashDetectionTxt->setPlainText("Clef USB non détectée"); + + long rss = CRamMonitor::instance()->GetRamUsage(); + mRAMUsageText->setPlainText(QString().sprintf("Utilisation RAM: %ld [%ldk]",rss,rss/1024)); + + double reading; + + if(mAnalogInterface != 0) + { + mAnalogInterface->GetAnalogInput(mStation->GetAnalogAcqChannels()->SDFAcquisitionChannel,reading); +// float value = (float)reading; +// value -= 32767/2; +// value *= 10; +// value /= 32767/2; + mAnalogSDFValue->setPlainText(QString().sprintf("4-20mA SDF: %f",reading)); + } + + mInputLeds[GENERIC_INPUT_ZT1_S1_ID]->SetLed((PCIInputs & mInputMasks->InputZT1S1Mask) != 0); + mInputLeds[GENERIC_INPUT_ZT1_S2_ID]->SetLed((PCIInputs & mInputMasks->InputZT1S2Mask) != 0); + mInputLeds[GENERIC_INPUT_ZT1_PI_ID]->SetLed((PCIInputs & mInputMasks->InputZT1PIMask) != 0); + mInputLeds[GENERIC_INPUT_ZT1_PE_ID]->SetLed((PCIInputs & mInputMasks->InputZT1PEMask) != 0); + mInputLeds[GENERIC_INPUT_ZT1_FN_ID]->SetLed((PCIInputs & mInputMasks->InputZT1FNMask) != 0); + mInputLeds[GENERIC_INPUT_ZT2_S1_ID]->SetLed((PCIInputs & mInputMasks->InputZT2S1Mask) != 0); + mInputLeds[GENERIC_INPUT_ZT2_PI_ID]->SetLed((PCIInputs & mInputMasks->InputZT2PIMask) != 0); + mInputLeds[GENERIC_INPUT_ZT2_PE_ID]->SetLed((PCIInputs & mInputMasks->InputZT2PEMask) != 0); + mInputLeds[GENERIC_INPUT_ZT1_ITI_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT1ITIMask) != 0); + mInputLeds[GENERIC_INPUT_ZT2_ITI_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT2ITIMask) != 0); + mInputLeds[GENERIC_INPUT_ZT1_AN_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT1ANMask) != 0); + mInputLeds[GENERIC_INPUT_ZT2_AN_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT2ANMask) != 0); + mInputLeds[GENERIC_INPUT_ZT1_ARF_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT1ARFMask) != 0); + mInputLeds[GENERIC_INPUT_ZT2_ARF_ID]->SetLed((ExtModuleInputs & mInputMasks->InputZT2ARFMask) != 0); + mInputLeds[GENERIC_INPUT_STATION_ID_0_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_0_MASK) != 0); + mInputLeds[GENERIC_INPUT_STATION_ID_1_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_1_MASK) != 0); + mInputLeds[GENERIC_INPUT_STATION_ID_2_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_2_MASK) != 0); + mInputLeds[GENERIC_INPUT_STATION_ID_3_ID]->SetLed((ExtModuleInputs & STATION_KEY_ID_3_MASK) != 0); + + for(int led = 0; led < mCDVList->size(); led++) + { + mInputLedsCDV.at(led)->SetLed(!mCDVList->at(led)->IsOccupied()); + } + + + #ifdef OUTPUT_EXTIO_SAMPLE_RATE + + long int sampletime = mExtIOInterface->GetSampleRate(); + float samplerate = 1/((float)sampletime / 1000); + qDebug("ExtIO Sample rate: %ld, %f",sampletime,samplerate); + #endif +} + +void CEngineeringPage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + mBackgroundRect->setRect(boundingRect()); + mCancelButton->setPos(50,boundingRect().height()-50); +} + +void CEngineeringPage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mCancelButton) + { + mProgramHandle->CloseEngineeringPageRequest(); + } + else if(BtnPtr == mDeleteLogsButton) + { + DeleteAllLogs(); + } + else if(BtnPtr == mArchiveLogsButton) + { + if(mUSBInterfacePtr->IsDriveDetected() == false) + { + QMessageBox MsgBox; + MsgBox.setText("Veuillez insérer une clef USB"); + MsgBox.exec(); + } + else + { + ArchiveLogFiles(); + } + } + else if(BtnPtr == mPGValueSetBtn) + { + CZTLog::instance()->AddLogString(QString().sprintf("Seuil PG changé. Ancien: %d, Nouveau: %d",mProgramHandle->GetPGTreshold(),mPGTresholdValueSpinBox->value()),true); + mProgramHandle->SetPGTreshold(mPGTresholdValueSpinBox->value()); + mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold())); + } + else if(BtnPtr == mCopyCalibValueBtn) + { + mPGTresholdValueSpinBox->setValue(mPGCalibTresholdValue); + } + else if(BtnPtr == mConvertCSVButton) + { + QString FilePath = QFileDialog::getOpenFileName(0, tr("Fichier de passage"), "./Trains", tr("Passages (*.csv)")); + + if(FilePath.isEmpty() == false) + { + CTrainLogFileMgr::instance()->SaveBINFromCSV(FilePath); + } + + } + else if(BtnPtr == mDeleteEngLogBtn) + { + CEngLog::instance()->DeleteEngLogFile(); + } + else if(BtnPtr == mDeleteZTLogButton) + { + CZTLog::instance()->DeleteLogFile(); + } + else if(BtnPtr == mTestButton) + { + } +} + +void CEngineeringPage::showEvent(QShowEvent *event) +{ + Q_UNUSED(event) + UpdateInfo(); + mInfoUpdateTimer->start(1000); + RefreshLogsList(); + mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold())); + mPGTresholdValueSpinBox->setValue(mProgramHandle->GetPGTreshold()); +} +void CEngineeringPage::hideEvent(QHideEvent *event) +{ + Q_UNUSED(event) + mInfoUpdateTimer->stop(); +} + +void CEngineeringPage::ShowPage() +{ + if(mDisablePassword == true) + { + show(); + CZTLog::instance()->AddLogString("Page d'ingénierie, mot de passe désactivé. Ouverture de la page",true); + } + else + { + mPasswordPrompt->RequestPassword(); + CZTLog::instance()->AddLogString("Page d'ingénierie, demande du mot de passe"); + } +} + +void CEngineeringPage::PasswordValid() +{ + mPasswordPrompt->hide(); + CZTLog::instance()->AddLogString("Page d'ingénierie, mot de passe valide. Ouverture de la page",true); + show(); +} + +void CEngineeringPage::PasswordInvalid() +{ + mPasswordPrompt->hide(); + mProgramHandle->CloseEngineeringPageRequest(); + CZTLog::instance()->AddLogString("Mot de passe invalide",true); +} + +void CEngineeringPage::ZT1AutoCSVCheckBoxChanged(int state) +{ + if(state == Qt::Checked) + mAutoExportZT1CSV = true; + else if(state == Qt::Unchecked) + mAutoExportZT1CSV = false; + + mProgramHandle->SaveAutoExportCSVSettings(mAutoExportZT1CSV,mAutoExportZT2CSV); +} + +void CEngineeringPage::ZT2AutoCSVCheckBoxChanged(int state) +{ + if(state == Qt::Checked) + mAutoExportZT2CSV = true; + else if(state == Qt::Unchecked) + mAutoExportZT2CSV = false; + + mProgramHandle->SaveAutoExportCSVSettings(mAutoExportZT1CSV,mAutoExportZT2CSV); +} + +void CEngineeringPage::HighResLogCheckBoxChanged(int state) +{ + if(mProgramHandle == 0) + return; + if(isVisible() == false) + return; + + if(state == Qt::Checked) + { + mProgramHandle->HighResLogging(true); + } + else + { + mProgramHandle->HighResLogging(false); + } +} + +void CEngineeringPage::KeepAllMPM10LogsCheckBoxChanged(int state) +{ + if(mProgramHandle == 0) + return; + if(isVisible() == false) + return; + + if(state == Qt::Checked) + { + mProgramHandle->KeepAllMPM10Logs(true); + } + else + { + mProgramHandle->KeepAllMPM10Logs(false); + } +} + +void CEngineeringPage::KeepZT1LogsCheckBoxChanged(int state) +{ + if(mProgramHandle == 0) + return; + if(isVisible() == false) + return; + + if(state == Qt::Checked) + { + mProgramHandle->KeepAllZT1Logs(true); + } + else + { + mProgramHandle->KeepAllZT1Logs(false); + } +} + +void CEngineeringPage::KeepZT2LogsCheckBoxChanged(int state) +{ + if(mProgramHandle == 0) + return; + if(isVisible() == false) + return; + + if(state == Qt::Checked) + { + mProgramHandle->KeepAllZT2Logs(true); + } + else + { + mProgramHandle->KeepAllZT2Logs(false); + } +} + +void CEngineeringPage::MaxNbLogFilesChanged(int value) +{ + if(mProgramHandle == 0) + return; + if(isVisible() == false) + return; + + mProgramHandle->SetLogFilesNumber(value); +} + +void CEngineeringPage::RefreshLogsList() +{ + QStringList LogFilters; + LogFilters << "*.bin"; + QDir LogDir("./Trains/"); + + LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + LogDir.setNameFilters(LogFilters); + LogDir.setSorting(QDir::Name); + + mLogFilesList = LogDir.entryInfoList(); + + mNbLogsText->setPlainText(QString().sprintf("Nombre de fichiers de passages: %d",mLogFilesList.size())); +} + +void CEngineeringPage::DeleteAllLogs() +{ + QStringList LogFilters; + LogFilters << "*.bin" << "*.csv"; + QDir LogDir("./Trains/"); + + LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + LogDir.setNameFilters(LogFilters); + LogDir.setSorting(QDir::Name); + + for(int i = 0; i < LogDir.entryInfoList().size(); i++) + { + QFile::remove(LogDir.entryInfoList().at(i).absoluteFilePath()); + } + + RefreshLogsList(); + mProgramHandle->TrainFilesChanged(); +} + +void CEngineeringPage::ZTLogFilesSettings(int NbLogFiles, bool KeepMPM10Logs, bool KeepZT1Logs, bool KeepZT2Logs) +{ + if(KeepMPM10Logs == true) + mKeepAllMPM10Logs->setCheckState(Qt::Checked); + + if(KeepZT1Logs == true) + mKeepZT1Logs->setCheckState(Qt::Checked); + + if(KeepZT2Logs == true) + mKeepZT2Logs->setCheckState(Qt::Checked); + + mNbLogFilesSpinBox->setValue(NbLogFiles); +} + +void CEngineeringPage::ArchiveLogFiles() +{ + RefreshLogsList(); + + QString PathName = mUSBInterfacePtr->GetDrivePath(); + PathName += "/ArchiveLogZT_"; + PathName += mStation->GetStationShortName(); + PathName += QDateTime::currentDateTime().toString("_yyyyMMdd"); + QDir TargetDir(PathName); + + TargetDir.mkdir(PathName); //If the directory does not exist, it will be created. + + //copy files + QStringList LogFilters; + LogFilters << "*.bin" << "*.csv"; + QDir LogDir("./Trains/"); + + LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + LogDir.setNameFilters(LogFilters); + LogDir.setSorting(QDir::Name); + for(int i = 0; i < LogDir.entryInfoList().size(); i++) + { + QString DestFileName = PathName; + DestFileName += "/"; + DestFileName += LogDir.entryInfoList().at(i).fileName(); + QFile::copy(LogDir.entryInfoList().at(i).absoluteFilePath(),DestFileName); + } + + system("sync"); +// DeleteAllLogs(); + mProgramHandle->TrainFilesChanged(); + +} + +void CEngineeringPage::OutputToggled(CToggleButtonWidget *Button) +{ + if(Button->GetButtonState() == TOGGLE_BUTTON_ON) + { + mOutputModulePtr->SetOutputFlags(Button->GetData()); + } + else + { + mOutputModulePtr->ClearOutputFlags(Button->GetData()); + } +} + +void CEngineeringPage::PGCalibBtnToggled(CToggleButtonWidget *Btn) +{ + if(Btn == mPGCalibrationSwitch) + { + if(mPGCalibrationSwitch->GetButtonState() ==TOGGLE_BUTTON_ON) + { + if(mProgramHandle->StartPGCalibrationRequest(mPGNbPassagesForCalibSpinBox->value()) == false) + { + mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_OFF); + QMessageBox MsgBox; + MsgBox.setText("La Zone Tests est active\nVeuillez attendre qu'elle se libère"); + MsgBox.exec(); + } + else + { + mCalibResultText->setPlainText("Valeur seuil PG calibration: Calib. en cours"); + mCopyCalibValueBtn->hide(); + CZTLog::instance()->AddLogString("Calibration PG démarrée.",true); + } + } + else + { + + if(mProgramHandle->StopPGCalibrationRequest() == false) + { + mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_ON); + QMessageBox MsgBox; + MsgBox.setText("La Zone Tests est active\nVeuillez attendre qu'elle se libère"); + MsgBox.exec(); + return; + } + else + { + mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_OFF); + mCopyCalibValueBtn->hide(); + mCalibResultText->setPlainText("Valeur seuil PG calibration: Calib. non effectuée"); + CZTLog::instance()->AddLogString("Calibration PG annulée par l'utilisateur",true); + + } + + } + } +} + +void CEngineeringPage::LazerProbeDataAvailable(unsigned int Data, unsigned int ProbeID) +{ + if(!isVisible()) + return; + + QString ProbeData; + ProbeData.clear(); + if(ProbeID == LAZER_PROBE_TYPE_EXTERNAL) + { + ProbeData.sprintf("Sonde Lazer Ext: %d",Data); + mExtLazerProbeValue->setPlainText(ProbeData); + } + else + { + ProbeData.sprintf("Sonde Lazer Ixt: %d",Data); + mIntLazerProbeValue->setPlainText(ProbeData); + } + +} + +void CEngineeringPage::PGCalibFinished(int Treshold) +{ + mPGCalibrationSwitch->SetButtonState(TOGGLE_BUTTON_OFF); + mCalibResultText->setPlainText(QString().sprintf("Valeur seuil PG calibration: %d",Treshold)); + mPGCalibTresholdValue = Treshold; + mCopyCalibValueBtn->show(); + mProgramHandle->StopPGCalibrationRequest(); + CZTLog::instance()->AddLogString(QString().sprintf("Calibration PG terminée. Seuil calculé: %d",Treshold),true); +} + +void CEngineeringPage::PGCalibUpdate(int CurTrain, int TotalTrain) +{ + mCalibResultText->setPlainText(QString().sprintf("Valeur seuil PG calibration: Calib. en cours: Train %d / %d",CurTrain,TotalTrain)); + CZTLog::instance()->AddLogString(QString().sprintf("Calibration PG: Passage du train %d/%d",CurTrain,TotalTrain),true); +} + +//Grab the mouse if the user clicks outside buttons +void CEngineeringPage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void CEngineeringPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} diff --git a/sources/GuiElements/EngineeringPage.h b/sources/GuiElements/EngineeringPage.h new file mode 100644 index 0000000..d623765 --- /dev/null +++ b/sources/GuiElements/EngineeringPage.h @@ -0,0 +1,164 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef ENGINEERINGPAGE_H +#define ENGINEERINGPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "ZTSimulator.h" +#include "TextButtonWidget.h" +#include "InputModule.h" + +#include "PCIIOMgr.h" +#include "PasswordPrompt.h" +#include "ZTData.h" +#include +#include +#include "USBDriveInterface.h" +#include "ToggleButtonWidget.h" +#include +#include "MixedModule.h" +#include "OutputModule.h" + + +class CZoneTest; + +class CEngineeringPage : public CGuiPage +{ +Q_OBJECT +public: + ~CEngineeringPage(); + CEngineeringPage(QGraphicsWidget *Parent = 0); + CPushButton *mToolsPushButton; + CPasswordPrompt *mPasswordPrompt; + bool mDisablePassword; + + + void BindPointers(CZoneTest *ProgramHandle,CInputModule *InputModulePtr, COutputModule *OutputModulePtr, CPCIIOMgr *PCIIO,CZTSettingsData *ZTSettings,CUSBDriveInterface *USBInterface,CStation *StationPtr,CAnalogInputModule *AnalogInterface); + void ZTLogFilesSettings(int NbLogFiles, bool KeepMPM10Logs, bool KeepZT1Logs, bool KeepZT2Logs); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void showEvent(QShowEvent *event); + virtual void hideEvent(QHideEvent *event); + virtual void ShowPage(); + void Init(); + +private: + CZoneTest *mProgramHandle; + CAnalogInputModule *mAnalogInterface; + CInputModule *mInputModulePtr; + COutputModule *mOutputModulePtr; + + CPCIIOMgr *mPCIIO; + CZTSettingsData *mZTSettings; + QGraphicsRectItem *mBackgroundRect; + CStation *mStation; + GenericInputMasks_t *mInputMasks; + QList *mCDVList; + + CTextButtonWidget *mCancelButton; + CTextButtonWidget *mConvertCSVButton; + CTextButtonWidget *mTestButton; + CTextButtonWidget *mDeleteEngLogBtn; + + QGraphicsTextItem *mPCIIODataText; + QGraphicsTextItem *mExternalInputDataText; + QGraphicsTextItem *mRAMUsageText; + QGraphicsTextItem *mIntLazerProbeValue; + QGraphicsTextItem *mExtLazerProbeValue; + QGraphicsTextItem *mAnalogSDFValue; + QCheckBox *mExportZT1CSVChkBx,*mExportZT2CSVChkBx, *mHighResLogging; + QCheckBox *mKeepAllMPM10Logs, *mKeepZT1Logs,*mKeepZT2Logs; + QSpinBox *mNbLogFilesSpinBox; + + QGraphicsTextItem *mNbLogsText; + CTextButtonWidget *mDeleteLogsButton; + CTextButtonWidget *mArchiveLogsButton; + CTextButtonWidget *mDeleteZTLogButton; + + CToggleButtonWidget *mPGCalibrationSwitch; + QSpinBox *mPGTresholdValueSpinBox, *mPGNbPassagesForCalibSpinBox; + CTextButtonWidget *mPGValueSetBtn, *mCopyCalibValueBtn; + QGraphicsTextItem *mCalibResultText, *mActualPGTresholdValueText; + + + CUSBDriveInterface *mUSBInterfacePtr; + QGraphicsTextItem *mUSBFlashDetectionTxt; + + QTimer *mInfoUpdateTimer; + + QFileInfoList mLogFilesList; + + //Outputs control + CToggleButtonWidget *OutputToggleBtn[GENERIC_OUTPUT_NB_ID]; + + //Inputs monitor + CLedWidget *mInputLeds[GENERIC_INPUT_NB_ID]; + QList mInputLedsCDV; + + + bool mAutoExportZT1CSV,mAutoExportZT2CSV; + int mPGCalibTresholdValue; + + + + void RefreshLogsList(); + void DeleteAllLogs(); + void ArchiveLogFiles(); + + CZT1LogData *mDummy[5000]; + + + + +public slots: + void ButtonClicked(CTextButtonWidget *); + void UpdateInfo(); + void PasswordValid(); + void PasswordInvalid(); + void ZT1AutoCSVCheckBoxChanged(int); + void ZT2AutoCSVCheckBoxChanged(int); + void HighResLogCheckBoxChanged(int); + void KeepZT1LogsCheckBoxChanged(int); + void KeepZT2LogsCheckBoxChanged(int); + void KeepAllMPM10LogsCheckBoxChanged(int); + void OutputToggled(CToggleButtonWidget*); + void LazerProbeDataAvailable(unsigned int,unsigned int); + void PGCalibBtnToggled(CToggleButtonWidget*); + void PGCalibFinished(int); + void PGCalibUpdate(int,int); + void MaxNbLogFilesChanged(int); + +}; + +#endif // ENGINEERINGPAGE_H diff --git a/sources/GuiElements/EventItem.cpp b/sources/GuiElements/EventItem.cpp new file mode 100644 index 0000000..c083b50 --- /dev/null +++ b/sources/GuiElements/EventItem.cpp @@ -0,0 +1,131 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Affiche un rectangle qui "flash" en rouge lorsqu'une fonction de détection + est désactivée. Le clignotement est une petite animation qui change la + transparence de la couleur de fond. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130524 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "EventItem.h" +#include +#include "ZTData.h" +#include +#include "CDV.h" +#include + +CEventItem::CEventItem(QString Label,bool Animated,QGraphicsItem *Parent) +{ + setParentItem(Parent); + +// mCDVFreeBrush = new QBrush(Qt::gray); +// mCDVITICommandedBrush = new QBrush(Qt::darkGreen); +// mCDVOccupiedBrush = new QBrush(Qt::yellow); + + setGeometry(0,0,40,25); + mCurBrush = new QBrush(Qt::lightGray); + mLabelFont.setPixelSize(12); + mLabelFont.setBold(true); + + SetLabel(Label); + + mAnimated = Animated; + if(mAnimated) + { + mAnimationTimeline = new QTimeLine(1000); + connect(mAnimationTimeline,SIGNAL(valueChanged(qreal)),this,SLOT(UpdateAnimation(qreal))); + connect(mAnimationTimeline,SIGNAL(finished()),this,SLOT(AnimationFinished())); + mAnimationTimeline->start(); + } + + mAlpha = 0; +} + +CEventItem::~CEventItem() +{ + if(mAnimated) + delete mAnimationTimeline; +} + +void CEventItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + QRectF EventRect = rect(); + + if(mAnimated) + mCurBrush->setColor(QColor(255,mAlpha,mAlpha,255)); + + painter->setBrush(*mCurBrush); + painter->setPen(Qt::black); + painter->drawRect(EventRect); + +// QRectF textRect(CDVRect.adjusted(-3,-3,-3,-3)); +// painter->drawRect(textRect); + + int flags = Qt::AlignHCenter | Qt::AlignVCenter/* | Qt::TextWordWrap*/; + + painter->setPen(Qt::black); + painter->setFont(mLabelFont); + painter->drawText(EventRect, flags, mLabel); + +} + +void CEventItem::SetLabel(QString Label) +{ + mLabel = Label; + QSizeF Size; + Size = size(); + QFontMetrics FontMetrics(mLabelFont); + Size.setWidth(FontMetrics.boundingRect(mLabel).width() + 10); + resize(Size); +} + +void CEventItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + emit EventItemRightClicked(this); + } +} + +void CEventItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} + +void CEventItem::UpdateAnimation(qreal value) +{ + mAlpha = 255*value; + + + //update(QGraphicsItem::pos().x(),QGraphicsItem::pos().x(),40,25); + update(); +} + +void CEventItem::AnimationFinished() +{ + mAnimationTimeline->toggleDirection(); + mAnimationTimeline->start(); +} diff --git a/sources/GuiElements/EventItem.h b/sources/GuiElements/EventItem.h new file mode 100644 index 0000000..0508d42 --- /dev/null +++ b/sources/GuiElements/EventItem.h @@ -0,0 +1,71 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131022 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "GlobalDefine.h" +#include +#include +#include + + + +#ifndef EVENTITEM_H +#define EVENTITEM_H + +class CEventItem : public QGraphicsWidget +{ + Q_OBJECT + +public: + CEventItem(QString Label,bool Animated,QGraphicsItem *Parent = 0); + ~CEventItem(); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + unsigned int SetParameters(QString Label/*, unsigned int posx, unsigned int posy*/); + unsigned int SetState(unsigned int State); + unsigned int UpdateState(); + void SetLabel(QString Label); + +protected: + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + +private: + QBrush *mCurBrush; + QString mLabel; + QFont mLabelFont; + bool mAnimated; + QTimeLine *mAnimationTimeline; + unsigned int mAlpha; + +signals: + void EventItemRightClicked(CEventItem*); + +public slots: + void UpdateAnimation(qreal); + void AnimationFinished(); +}; + +#endif // EVENTITEM_H diff --git a/sources/GuiElements/EventsBar.cpp b/sources/GuiElements/EventsBar.cpp new file mode 100644 index 0000000..10a22be --- /dev/null +++ b/sources/GuiElements/EventsBar.cpp @@ -0,0 +1,79 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Crée une liste d'objets CEventItem et les dispose en ligne dans le bas de + l'écran. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "EventsBar.h" +#include +#include + +CEventsBar::CEventsBar(QGraphicsItem *Parent) +{ + setParentItem(Parent); + resize(SCREEN_RES_WIDTH,25); + +// QPen temp; +// temp.setColor(Qt::red); +// QGraphicsRectItem *temprect = new QGraphicsRectItem(this); +// temprect->setPen(temp); +// temprect->setRect(boundingRect()); +// temprect->show(); +} + +//void CEventsBar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +//{ + +//} + +void CEventsBar::UpdateDisplay() +{ + if(mEventsItemList.size() == 0) + return; + + for(int i = 1; i < mEventsItemList.size(); i++) + { + CEventItem *CurEvent = mEventsItemList.at(i), *PrevEvent = mEventsItemList.at(i-1); + + CurEvent->setPos(PrevEvent->pos().x() + PrevEvent->rect().width()+3,0); + } +} + +void CEventsBar::UpdateEventsList() +{ + //clear existing list if necessary + for(int i = 0; i < mEventsItemList.size(); i++) + { + delete mEventsItemList.at(i); + } + mEventsItemList.clear(); + + for(int i = 0; i < mEventsList->size(); i++) + { + CEventItem *NewItem = new CEventItem(mEventsList->at(i)->mEventLabel,mEventsList->at(i)->mItemAnimated,this); + mEventsItemList.append(NewItem); + } + UpdateDisplay(); +} diff --git a/sources/GuiElements/EventsBar.h b/sources/GuiElements/EventsBar.h new file mode 100644 index 0000000..69dc27c --- /dev/null +++ b/sources/GuiElements/EventsBar.h @@ -0,0 +1,58 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131022 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef EVENTSBAR_H +#define EVENTSBAR_H + +#include "GlobalDefine.h" +#include +#include +#include "EventItem.h" +#include "Event.h" + +class CEventsBar : public QGraphicsWidget +{ + Q_OBJECT +public: + CEventsBar(QGraphicsItem *Parent = 0); + +// void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + QList *mEventsList; + void UpdateEventsList(); + + +private: + + QList mEventsItemList; + void UpdateDisplay(); + + + + +}; + +#endif // EVENTSBAR_H diff --git a/sources/GuiElements/EventsRulerWidget.cpp b/sources/GuiElements/EventsRulerWidget.cpp new file mode 100644 index 0000000..fae03bf --- /dev/null +++ b/sources/GuiElements/EventsRulerWidget.cpp @@ -0,0 +1,127 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Dessine une règle temporelle sur laquelle sont affichés les déclenchements. + Une ligne rouge est dessinée au temps correspondant au déclenchement et du + texte identifiant le type de déclenchement est aussi affiché. + + Utilisée dans la page de visualisation des passages de train. + + CETTE CLASSE DEVRAIT ÊTRE OPTIMISÉE. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "EventsRulerWidget.h" +#include +#include + +CEventRulerWidget::CEventRulerWidget(qreal RulerPixelWidth, QGraphicsItem *Parent) +{ + setParentItem(Parent); + mPixelWidth = RulerPixelWidth; + mLabel = new QGraphicsTextItem(this); +} + +void CEventRulerWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + if(mEventItems.isEmpty()) + return; + + QFont font; + font.setPixelSize(12); + painter->setFont(font); + qreal pitch = mPixelWidth/(mEndTime - mStartTime); //pixel/ns + + QPen LinePen,TextPen; + LinePen.setColor(Qt::red); + LinePen.setWidth(2); + TextPen.setColor(Qt::black); + TextPen.setWidth(1); + + qreal Height = boundingRect().height(); + + for(int i = 0; i < mEventItems.size(); i++) + { + if(mEventItems.at(i).mEventTime >= mStartTime) + { + if(mEventItems.at(i).mEventTime <= mEndTime) + { + qreal PixelPos = (mEventItems.at(i).mEventTime - mStartTime)*pitch; + painter->setPen(LinePen); + painter->drawLine(PixelPos,0,PixelPos,Height); + painter->setPen(TextPen); + painter->drawText(QRectF(PixelPos+3,0,50,Height),mEventItems.at(i).mLabel,Qt::AlignLeft | Qt::AlignVCenter); + } + else + { + return; + } + } + } +} + +unsigned int CEventRulerWidget::SetRange(quint64 StartTime, quint64 EndTime) +{ + if(StartTime > EndTime) + return false; + + if(mEventItems.isEmpty()) + return false; + + + mStartTime = StartTime; + mEndTime = EndTime; + + update(); + + return RET_OK; +} + +unsigned int CEventRulerWidget::AddEventItem(QString Rank, quint64 EventTime) +{ + CEventRulerWidgetItem NewItem; + NewItem.mLabel = Rank; + NewItem.mEventTime = EventTime; + + mEventItems.append(NewItem); + return RET_OK; +} + +void CEventRulerWidget::SetLabel(QString Label, int Offset) +{ + QFont font; + font.setBold(true); + mLabel->setFont(font); + mLabel->setPlainText(Label); + mLabel->setPos(-Offset,boundingRect().height()/2 - mLabel->boundingRect().height()/2); +} + +void CEventRulerWidget::ClearRuler() +{ + mEventItems.clear(); + update(); +} diff --git a/sources/GuiElements/EventsRulerWidget.h b/sources/GuiElements/EventsRulerWidget.h new file mode 100644 index 0000000..ca35cd7 --- /dev/null +++ b/sources/GuiElements/EventsRulerWidget.h @@ -0,0 +1,65 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131030 JFM + Verision d'origine. + +### 20131107 Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef EVENTSRULERWIDGET_H +#define EVENTSRULERWIDGET_H + +#include "GlobalDefine.h" +#include + +class CEventRulerWidgetItem +{ +public: + QString mLabel; + quint64 mEventTime; +}; + +class CEventRulerWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CEventRulerWidget(qreal RulerPixelWidth,QGraphicsItem *Parent = 0); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + unsigned int SetRange(quint64 StartTime, quint64 EndTime); + unsigned int AddEventItem(QString EventLabel,quint64 EventTime); + void SetLabel(QString Label,int Offset); + void ClearRuler(); + + +private: + qreal mPixelWidth; + quint64 mStartTime, mEndTime; + qreal mPixelPitch; + QGraphicsTextItem *mLabel; + + QList mEventItems; + +}; + +#endif // RANKRULERWIDGET_H diff --git a/sources/GuiElements/FunctionSelectionPage.cpp b/sources/GuiElements/FunctionSelectionPage.cpp new file mode 100644 index 0000000..d1a0391 --- /dev/null +++ b/sources/GuiElements/FunctionSelectionPage.cpp @@ -0,0 +1,401 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page d'activation ou de désactivation des fonctions de détection. + Des boutons curseurs permettent de mettre à ON ou à OFF une fonction, soit + pour son analyse ou pour sa TK ou les deux. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "FunctionSelectionPage.h" +#include "GlobalDefine.h" +#include "Zonetest.h" +#include + + + +CFunctionSelectionPage::CFunctionSelectionPage(QGraphicsWidget *Parent) +{ + Q_UNUSED(Parent) + mProgramHandle = 0; + mZTSimulatorPtr = 0; + + + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QBrush BackgroundBrush(QColor(245, 245, 255)); + mBackgroundRect->setBrush(BackgroundBrush); + + QGraphicsTextItem *Title = new QGraphicsTextItem("Configuration des fonctions de détection",this); + QFont font; + font.setPointSize(15); + Title->setFont(font); + Title->setPos(40,10); + + mCancelButton = new CTextButtonWidget("Annuler"); + mCancelButton->setParentItem(this); + mCancelButton->setPos(50,360); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mAcceptButton = new CTextButtonWidget("Appliquer"); + mAcceptButton->setParentItem(this); + mAcceptButton->setPos(145,360); + connect(mAcceptButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + + QPointF ArrayTopLeft; + ArrayTopLeft.setX(250); + ArrayTopLeft.setY(100); + qreal XButtonSpacing = 90; + qreal YLineSpacing = 40; + QString ONPixmapFilePath = "./Images/Slider_Green.png"; + QString OFFPixmapFilePath = "./Images/Slider_Red.png"; + QSizeF SlideButtonSize(50,30); + font.setPointSize(12); + + + QGraphicsTextItem *Label = new QGraphicsTextItem("Analyse",this); + Label->setFont(font); + Label->setPos(ArrayTopLeft.x() - 10,ArrayTopLeft.y() - YLineSpacing); + + Label = new QGraphicsTextItem("TK",this); + Label->setFont(font); + Label->setPos(ArrayTopLeft.x() + XButtonSpacing +5 ,ArrayTopLeft.y() - YLineSpacing); + + int i = 0; + Label = new QGraphicsTextItem("Frotteur Négatif:",this); + Label->setFont(font); + Label->setPos(35,ArrayTopLeft.y() + (i*YLineSpacing)); + mFNFuncToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mFNFuncToggleBtn->resize(SlideButtonSize); + mFNFuncToggleBtn->setPos(ArrayTopLeft.x(),ArrayTopLeft.y() + (i*YLineSpacing)); + mFNTKToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mFNTKToggleBtn->resize(SlideButtonSize); + mFNTKToggleBtn->setPos(ArrayTopLeft.x() + XButtonSpacing,ArrayTopLeft.y() + (i*YLineSpacing)); + + i++; + Label = new QGraphicsTextItem("Pneu de guidage:",this); + Label->setFont(font); + Label->setPos(35,ArrayTopLeft.y() + (i*YLineSpacing)); + mPGFuncToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mPGFuncToggleBtn->resize(SlideButtonSize); + mPGFuncToggleBtn->setPos(ArrayTopLeft.x(),ArrayTopLeft.y() + (i*YLineSpacing)); + mPGTKToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mPGTKToggleBtn->resize(SlideButtonSize); + mPGTKToggleBtn->setPos(ArrayTopLeft.x() + XButtonSpacing,ArrayTopLeft.y() + (i*YLineSpacing)); + + i++; + Label = new QGraphicsTextItem("Pneu porteur:",this); + Label->setFont(font); + Label->setPos(35,ArrayTopLeft.y() + (i*YLineSpacing)); + mPPFuncToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mPPFuncToggleBtn->resize(SlideButtonSize); + mPPFuncToggleBtn->setPos(ArrayTopLeft.x(),ArrayTopLeft.y() + (i*YLineSpacing)); + mPPTKToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mPPTKToggleBtn->resize(SlideButtonSize); + mPPTKToggleBtn->setPos(ArrayTopLeft.x() + XButtonSpacing,ArrayTopLeft.y() + (i*YLineSpacing)); + + i++; + Label = new QGraphicsTextItem("Pneu porteur ZT2:",this); + Label->setFont(font); + Label->setPos(35,ArrayTopLeft.y() + (i*YLineSpacing)); + mPP2FuncToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mPP2FuncToggleBtn->resize(SlideButtonSize); + mPP2FuncToggleBtn->setPos(ArrayTopLeft.x(),ArrayTopLeft.y() + (i*YLineSpacing)); + mPP2TKToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mPP2TKToggleBtn->resize(SlideButtonSize); + mPP2TKToggleBtn->setPos(ArrayTopLeft.x() + XButtonSpacing,ArrayTopLeft.y() + (i*YLineSpacing)); + + i++; + Label = new QGraphicsTextItem("ZT1:",this); + Label->setFont(font); + Label->setPos(35,ArrayTopLeft.y() + (i*YLineSpacing)); + mZT1FuncToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mZT1FuncToggleBtn->resize(SlideButtonSize); + mZT1FuncToggleBtn->setPos(ArrayTopLeft.x(),ArrayTopLeft.y() + (i*YLineSpacing)); + connect(mZT1FuncToggleBtn,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(ToggleButtonToggled(CToggleButtonWidget*))); + mZT1TKToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mZT1TKToggleBtn->resize(SlideButtonSize); + mZT1TKToggleBtn->setPos(ArrayTopLeft.x() + XButtonSpacing,ArrayTopLeft.y() + (i*YLineSpacing)); + connect(mZT1TKToggleBtn,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(ToggleButtonToggled(CToggleButtonWidget*))); + + i++; + Label = new QGraphicsTextItem("ZT2:",this); + Label->setFont(font); + Label->setPos(35,ArrayTopLeft.y() + (i*YLineSpacing)); + mZT2FuncToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mZT2FuncToggleBtn->resize(SlideButtonSize); + mZT2FuncToggleBtn->setPos(ArrayTopLeft.x(),ArrayTopLeft.y() + (i*YLineSpacing)); + connect(mZT2FuncToggleBtn,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(ToggleButtonToggled(CToggleButtonWidget*))); + mZT2TKToggleBtn = new CToggleButtonWidget(ONPixmapFilePath,OFFPixmapFilePath,this); + mZT2TKToggleBtn->resize(SlideButtonSize); + mZT2TKToggleBtn->setPos(ArrayTopLeft.x() + XButtonSpacing,ArrayTopLeft.y() + (i*YLineSpacing)); + connect(mZT2TKToggleBtn,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(ToggleButtonToggled(CToggleButtonWidget*))); +} + +void CFunctionSelectionPage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + mBackgroundRect->setRect(boundingRect()); +} + +void CFunctionSelectionPage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mAcceptButton) + { + UpdateConfig(); + mProgramHandle->DetectionFunctionsConfigChanged(&mZTConfig); + hide(); + } + else if(BtnPtr == mCancelButton) + { + UpdateDisplay(); //revert any changes made to the buttons + hide(); + } +} + +unsigned int CFunctionSelectionPage::SetConfig(CZTDetectionFunctionConfig *Config) +{ + mZTConfig = *Config; + UpdateDisplay(); + return RET_OK; +} + +void CFunctionSelectionPage::UpdateDisplay() +{ + //update FN buttons + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive == true) + mFNFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mFNFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_FN].TKActive == true) + mFNTKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mFNTKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + + //update PG buttons + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive == true) + mPGFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mPGFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_PG].TKActive == true) + mPGTKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mPGTKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + + //update PP buttons + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive == true) + mPPFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mPPFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP].TKActive == true) + mPPTKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mPPTKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + + //update PP2 buttons + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive == true) + mPP2FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mPP2FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP2].TKActive == true) + mPP2TKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mPP2TKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + + //update ZT1 buttons + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive == true) + mZT1FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mZT1FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive == true) + mZT1TKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mZT1TKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + + //update ZT2 buttons + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == true) + mZT2FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mZT2FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + if(mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive == true) + mZT2TKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + else + mZT2TKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + +} + +void CFunctionSelectionPage::UpdateConfig() +{ + //update FN flags + if(mFNFuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive = false; + + if(mFNTKToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_FN].TKActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_FN].TKActive = false; + + //update PG flags + if(mPGFuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive = false; + + if(mPGTKToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PG].TKActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PG].TKActive = false; + + //update PP flags + if(mPPFuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive = false; + + if(mPPTKToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP].TKActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP].TKActive = false; + + //update PP2 flags + if(mPP2FuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive = false; + + if(mPP2TKToggleBtn->GetButtonState()) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP2].TKActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_PP2].TKActive = false; + + //update ZT1 flags + if(mZT1FuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive = false; + + if(mZT1TKToggleBtn->GetButtonState()) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive = false; + + + //update ZT2 flags + if(mZT2FuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_ON) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive = false; + + if(mZT2TKToggleBtn->GetButtonState()) + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive = true; + else + mZTConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive = false; +} + +void CFunctionSelectionPage::ToggleButtonToggled(CToggleButtonWidget *ToggleButton) +{ + + if(ToggleButton == mZT1FuncToggleBtn) + { + if(mZT1FuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_OFF) + { + mFNFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + mFNFuncToggleBtn->SetButtonEnabled(false); + mPGFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + mPGFuncToggleBtn->SetButtonEnabled(false); + mPPFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + mPPFuncToggleBtn->SetButtonEnabled(false); + } + else + { + mFNFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + mFNFuncToggleBtn->SetButtonEnabled(true); + mPGFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + mPGFuncToggleBtn->SetButtonEnabled(true); + mPPFuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + mPPFuncToggleBtn->SetButtonEnabled(true); + } + } + if(ToggleButton == mZT1TKToggleBtn) + { + if(mZT1TKToggleBtn->GetButtonState() == TOGGLE_BUTTON_OFF) + { + mFNTKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + mFNTKToggleBtn->SetButtonEnabled(false); + mPGTKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + mPGTKToggleBtn->SetButtonEnabled(false); + mPPTKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + mPPTKToggleBtn->SetButtonEnabled(false); + } + else + { + mFNTKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + mFNTKToggleBtn->SetButtonEnabled(true); + mPGTKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + mPGTKToggleBtn->SetButtonEnabled(true); + mPPTKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + mPPTKToggleBtn->SetButtonEnabled(true); + } + } + + if(ToggleButton == mZT2FuncToggleBtn) + { + if(mZT2FuncToggleBtn->GetButtonState() == TOGGLE_BUTTON_OFF) + { + mPP2FuncToggleBtn->SetButtonEnabled(false); + mPP2FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + } + else + { + mPP2FuncToggleBtn->SetButtonEnabled(true); + mPP2FuncToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + } + } + if(ToggleButton == mZT2TKToggleBtn) + { + if(mZT2TKToggleBtn->GetButtonState() == TOGGLE_BUTTON_OFF) + { + mPP2TKToggleBtn->SetButtonEnabled(false); + mPP2TKToggleBtn->SetButtonState(TOGGLE_BUTTON_OFF); + } + else + { + mPP2TKToggleBtn->SetButtonEnabled(true); + mPP2TKToggleBtn->SetButtonState(TOGGLE_BUTTON_ON); + } + } +} + +//Grab the mouse if the user clicks outside buttons +void CFunctionSelectionPage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void CFunctionSelectionPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} diff --git a/sources/GuiElements/FunctionSelectionPage.h b/sources/GuiElements/FunctionSelectionPage.h new file mode 100644 index 0000000..7018595 --- /dev/null +++ b/sources/GuiElements/FunctionSelectionPage.h @@ -0,0 +1,84 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef FUNCTIONSELECTIONPAGE_H +#define FUNCTIONSELECTIONPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "ZTSimulator.h" +#include "ToggleButtonWidget.h" +#include "ZTData.h" + + +class CZoneTest; + +class CFunctionSelectionPage : public CGuiPage +{ +Q_OBJECT +public: + CFunctionSelectionPage(QGraphicsWidget *Parent = 0); + CZoneTest *mProgramHandle; + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + + unsigned int SetConfig(CZTDetectionFunctionConfig* Config); + void UpdateDisplay(); + +private: + CZTSimulator *mZTSimulatorPtr; + QGraphicsRectItem *mBackgroundRect; + CTextButtonWidget *mCancelButton; + CTextButtonWidget *mAcceptButton; + + CToggleButtonWidget *mFNFuncToggleBtn, *mFNTKToggleBtn; + CToggleButtonWidget *mPGFuncToggleBtn, *mPGTKToggleBtn; + CToggleButtonWidget *mPPFuncToggleBtn, *mPPTKToggleBtn; + CToggleButtonWidget *mPP2FuncToggleBtn, *mPP2TKToggleBtn; + CToggleButtonWidget *mZT1FuncToggleBtn, *mZT1TKToggleBtn; + CToggleButtonWidget *mZT2FuncToggleBtn, *mZT2TKToggleBtn; + + CZTDetectionFunctionConfig mZTConfig; + + + void UpdateConfig(); + + +public slots: + void ButtonClicked(CTextButtonWidget *); + void ToggleButtonToggled(CToggleButtonWidget*); + +}; + +#endif // FUNCTIONSELECTIONPAGE_H + diff --git a/sources/GuiElements/GeneralSettingsPage.cpp b/sources/GuiElements/GeneralSettingsPage.cpp new file mode 100644 index 0000000..b351aa7 --- /dev/null +++ b/sources/GuiElements/GeneralSettingsPage.cpp @@ -0,0 +1,188 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page offrant différentes option pour l'entretien de la ZT + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "GeneralSettingsPage.h" +#include +#include "GlobalDefine.h" +#include +#include +#include "Zonetest.h" +#include +#include +#include +#include +#include "ZTLog.h" + + + +CGeneralSettingsPage::CGeneralSettingsPage(QGraphicsWidget *Parent) +{ + Q_UNUSED(Parent) + + + mProgramHandle = 0; + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QBrush BackgroundBrush(QColor(245, 245, 255)); + mBackgroundRect->setBrush(BackgroundBrush); + + QGraphicsTextItem *Title = new QGraphicsTextItem("Paramètres généraux",this); + QFont font; + font.setPointSize(18); + Title->setFont(font); + Title->setPos(40,10); + + Title = new QGraphicsTextItem("Ajuster date & heure",this); + Title->setFont(font); + Title->setPos(270,80); + + mCancelButton = new CTextButtonWidget("Fermer"); + mCancelButton->setParentItem(this); + mCancelButton->setPos(700,550); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + QGraphicsProxyWidget *Proxy = new QGraphicsProxyWidget(this); + mCalendarWidget = new QCalendarWidget(); + Proxy->setWidget(mCalendarWidget); + Proxy->setPos(100,150); + + mTimeEdit = new QTimeEdit(); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mTimeEdit); + Proxy->setPos(475,150); + mTimeEdit->setTime(QTime::currentTime()); + mTimeEdit->setDisplayFormat("hh:mm"); + + mApplyDateTimeBtn = new CTextButtonWidget("Changer date & heure"); + mApplyDateTimeBtn->setParentItem(this); + mApplyDateTimeBtn->setPos(450,250); + connect(mApplyDateTimeBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + QGraphicsRectItem *Frame = new QGraphicsRectItem(80,70,600,300,this); + QPen FramePen; + FramePen.setWidth(3); + Frame->setPen(FramePen); + + + Title = new QGraphicsTextItem("Seuil Pneu de Guidage",this); + Title->setFont(font); + Title->setPos(270,400); + Frame = new QGraphicsRectItem(80,405,600,175,this); + Frame->setPen(FramePen); + + mPGTresholdValueSpinBox = new QSpinBox(); + Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mPGTresholdValueSpinBox); + Proxy->setPos(125,500); + mPGTresholdValueSpinBox->resize(70,30); + mPGTresholdValueSpinBox->setMinimum(1); + mPGTresholdValueSpinBox->setMaximum(2000); + mPGTresholdValueSpinBox->setValue(255); + + mPGValueSetBtn = new CTextButtonWidget("Changer Seuil",0,30); + mPGValueSetBtn->setParentItem(this); + mPGValueSetBtn->setPos(200,500); + connect(mPGValueSetBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mActualPGTresholdValueText = new QGraphicsTextItem(this); + mActualPGTresholdValueText->setPos(125,450); + font.setPointSize(14); + mActualPGTresholdValueText->setFont(font); + mActualPGTresholdValueText->setPlainText("Valeur actuelle : 255"); + +} + +void CGeneralSettingsPage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + + + mBackgroundRect->setRect(boundingRect()); +} + +void CGeneralSettingsPage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mCancelButton) + { + mProgramHandle->CloseGeneralSettingsPage(); + hide(); + } + else if(BtnPtr == mApplyDateTimeBtn) + { + + time_t time_data = time(0); + struct tm* tm_ptr = localtime(&time_data); + + tm_ptr->tm_min = mTimeEdit->time().minute(); + tm_ptr->tm_hour = mTimeEdit->time().hour(); + tm_ptr->tm_mday = mCalendarWidget->selectedDate().day(); + tm_ptr->tm_mon = mCalendarWidget->selectedDate().month()-1; + tm_ptr->tm_year = mCalendarWidget->selectedDate().year()-1900; + + const struct timeval tv = {mktime(tm_ptr),0}; + if(settimeofday(&tv,0) < 0) + { + qDebug("Settimeofday failed"); + CZTLog::instance()->AddLogString("Échec du changement de la date & de l'heure",true); + } + else + { + if ( system("/sbin/hwclock --systohc") < 0 ) + { + //qDebug("hwclock sync failed"); + CZTLog::instance()->AddLogString("Échec du changement de la date & de l'heure (hwsync failure)",true); + } + else + CZTLog::instance()->AddLogString(QString().sprintf("Changement de date & heure: %s %s",mCalendarWidget->selectedDate().toString("yyyy/MM/dd").toUtf8().data(),mTimeEdit->time().toString("hh:mm").toUtf8().data()),true); + } + } + else if(BtnPtr == mPGValueSetBtn) + { + CZTLog::instance()->AddLogString(QString().sprintf("Seuil PG changé. Ancien: %d, Nouveau: %d",mProgramHandle->GetPGTreshold(),mPGTresholdValueSpinBox->value()),true); + mProgramHandle->SetPGTreshold(mPGTresholdValueSpinBox->value()); + mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold())); + } +} + +void CGeneralSettingsPage::showEvent(QShowEvent *event) +{ + Q_UNUSED(event) + mTimeEdit->setTime(QTime::currentTime()); + mActualPGTresholdValueText->setPlainText(QString().sprintf("Valeur seuil PG actuelle %d",mProgramHandle->GetPGTreshold())); + mPGTresholdValueSpinBox->setValue(mProgramHandle->GetPGTreshold()); +} + +//Grab the mouse if the user clicks outside buttons +void CGeneralSettingsPage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void CGeneralSettingsPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} diff --git a/sources/GuiElements/GeneralSettingsPage.h b/sources/GuiElements/GeneralSettingsPage.h new file mode 100644 index 0000000..5b9d4c5 --- /dev/null +++ b/sources/GuiElements/GeneralSettingsPage.h @@ -0,0 +1,79 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131122 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef GENERALSETTINGSPAGE_H +#define GENERALSETTINGSPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "ZTSimulator.h" +#include "TextButtonWidget.h" +#include +#include +#include + + +class CZoneTest; + +class CGeneralSettingsPage : public CGuiPage +{ +Q_OBJECT +public: + CGeneralSettingsPage(QGraphicsWidget *Parent = 0); + + CZoneTest *mProgramHandle; + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void showEvent ( QShowEvent * event ); + + +private: + QGraphicsRectItem *mBackgroundRect; + CTextButtonWidget *mCancelButton; + CTextButtonWidget *mApplyDateTimeBtn; + + QCalendarWidget *mCalendarWidget; + QTimeEdit *mTimeEdit; + + + QSpinBox *mPGTresholdValueSpinBox; + CTextButtonWidget *mPGValueSetBtn; + QGraphicsTextItem *mActualPGTresholdValueText; + + +public slots: + void ButtonClicked(CTextButtonWidget *); + +}; + +#endif // GENERALSETTINGSPAGE_H diff --git a/sources/GuiElements/GraphCursorWidget.cpp b/sources/GuiElements/GraphCursorWidget.cpp new file mode 100644 index 0000000..f0b116b --- /dev/null +++ b/sources/GuiElements/GraphCursorWidget.cpp @@ -0,0 +1,138 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Dessine une ligne verticale et garde certaines information sur la position du + curseur + + + Utilisée dans la page de visualisation des passages de train.. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GraphCursorWidget.h" +#include +#include + +CVerticalGraphCursorWidget::CVerticalGraphCursorWidget(qreal Height,QGraphicsItem *Parent) +{ + setParentItem(Parent); + resize(3,Height); + mLine.setLine(0,0,0,Height); + mColor = Qt::blue; + mCursorTime = 0; + mCursorSet = false; +} + +void CVerticalGraphCursorWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + QPen pen; + pen.setWidth(1); + pen.setColor(mColor); + painter->setPen(pen); + + painter->drawLine(mLine); + +// if(mWidth != 0) +// painter->drawLine(mHLine); + +} + +qreal CVerticalGraphCursorWidget::GetPixelPos() +{ + return pos().x(); +} +quint64 CVerticalGraphCursorWidget::GetTime() +{ + return mCursorTime; +} +void CVerticalGraphCursorWidget::SetTime(quint64 time) +{ + mCursorTime = time; +} +bool CVerticalGraphCursorWidget::IsCursorSet() +{ + return mCursorSet; +} +void CVerticalGraphCursorWidget::ClearCursor() +{ + mCursorSet = false; + hide(); +} +void CVerticalGraphCursorWidget::SetCursor() +{ + mCursorSet = true; +} + + +//--------------------------------------------- + + + + + +CHorizontalGraphCursorWidget::CHorizontalGraphCursorWidget(qreal Width,QGraphicsItem *Parent) +{ + setParentItem(Parent); + resize(3,Width); + mLine.setLine(0,0,Width,0); + mColor = Qt::blue; + mCursorSet = false; +} + +void CHorizontalGraphCursorWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + QPen pen; + pen.setWidth(1); + pen.setColor(mColor); + painter->setPen(pen); + + painter->drawLine(mLine); + +// if(mWidth != 0) +// painter->drawLine(mHLine); + +} + +qreal CHorizontalGraphCursorWidget::GetPixelPos() +{ + return pos().y(); +} +bool CHorizontalGraphCursorWidget::IsCursorSet() +{ + return mCursorSet; +} +void CHorizontalGraphCursorWidget::ClearCursor() +{ + mCursorSet = false; + hide(); +} +void CHorizontalGraphCursorWidget::SetCursor() +{ + mCursorSet = true; +} diff --git a/sources/GuiElements/GraphCursorWidget.h b/sources/GuiElements/GraphCursorWidget.h new file mode 100644 index 0000000..7e7d02a --- /dev/null +++ b/sources/GuiElements/GraphCursorWidget.h @@ -0,0 +1,76 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef GRAPHCURSORWIDGET_H +#define GRAPHCURSORWIDGET_H + +#include "GlobalDefine.h" +#include + +class CVerticalGraphCursorWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CVerticalGraphCursorWidget(qreal Height, QGraphicsItem *Parent = 0); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + qreal GetPixelPos(); + void SetColor(QColor color){mColor = color;} + quint64 GetTime(); + void SetTime(quint64 time); + bool IsCursorSet(); + void ClearCursor(); + void SetCursor(); + +private: + QLine mLine; + QColor mColor; + quint64 mCursorTime; + bool mCursorSet; +}; + +class CHorizontalGraphCursorWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CHorizontalGraphCursorWidget(qreal Width, QGraphicsItem *Parent = 0); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + qreal GetPixelPos(); + void SetColor(QColor color){mColor = color;} + bool IsCursorSet(); + void ClearCursor(); + void SetCursor(); + +private: + QLine mLine; + QColor mColor; + quint64 mCursorPos; + bool mCursorSet; +}; + +#endif // GRAPHCURSORWIDGET_H diff --git a/sources/GuiElements/GraphItem.cpp b/sources/GuiElements/GraphItem.cpp new file mode 100644 index 0000000..d9df71f --- /dev/null +++ b/sources/GuiElements/GraphItem.cpp @@ -0,0 +1,254 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe d'affichage d'un graphique discret (sondes magnétiques, pédales, etc.)La + fonction SetData permet d'associer la liste des transitions. La + fonction DisplayData() permet de fixer le timespan à afficher. La fonction détermine + quels points sont dans le span et crée une liste de lignes qui sont ensuite affichés + dans la fonction de rappel paint(). + + Utilisée dans la page de visualisation des passages de train. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131024 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GraphItem.h" +#include +#include +#include + +CGraphItem::CGraphItem(QGraphicsItem *Parent) +{ + setParentItem(Parent); + mDataSet = 0; + mStartTime = mStopTime = 0; + mDataValid = false; + mLabel = new QGraphicsTextItem(this); + mGraphPixmap = new QPixmap(boundingRect().width(),boundingRect().height()); +} + +CGraphItem::~CGraphItem() +{ + delete mGraphPixmap; +} + +void CGraphItem::SetData(QList *DataList) +{ + + mDataSet = DataList; + //Build the lines list +} + +unsigned int CGraphItem::DisplayData(quint64 StartTime, quint64 StopTime) +{ + if(mDataSet == 0) + return RET_OK; + + quint64 MinTime = mDataSet->first()->mTime; + quint64 MaxTime = mDataSet->last()->mTime; + + if(StartTime >= StopTime) + return RET_ERROR; + if(StartTime < MinTime) + return RET_ERROR; + if(StopTime > MaxTime) + return RET_ERROR; + + mStartTime = StartTime; + mStopTime = StopTime; + quint64 TimeSpan = StopTime - StartTime; + + //Find the index of the first and last point in the timespan. + int StartIndex = 0, StopIndex = 0; + quint64 StartDeltaTime, StopDeltaTime; + int i = 0; + bool StartFound = false, StopFound = false; + while(StartFound == false || StopFound == false) + { + if(i >= mDataSet->size()) + { + qDebug("GraphItem::Array overflow while searching for time index"); + return RET_ERROR; + } + + quint64 CurTime = mDataSet->at(i)->mTime; + if(CurTime <= StartTime) + { + StartIndex = i; + StartDeltaTime = CurTime - StartTime; + StartFound = true; + } + if(CurTime >= StopTime && !StopFound) + { + StopIndex = i; + StopDeltaTime = StopTime - mDataSet->at(StopIndex)->mTime; + StopFound = true; + } + + i++; + } + + + //Build the lines list + mLinesList.clear(); + qreal Width = boundingRect().width(); + qreal Height = boundingRect().height()-2; + qreal tick = (Width)/TimeSpan; //pixels per microsec + + qreal X1,X2,Y1,Y2; + + //Add all the lines to create the graph. When there is a transition + //the horizontal line must be continued to the next point and a vertical + //line must be drawn. + for(int i = StartIndex; i < StopIndex; i++) + { + QLine NewLine; + if(mDataSet->at(i)->mTime < StartTime) + X1 = 0; + else + X1 = (qreal)(mDataSet->at(i)->mTime - StartTime); + + Y1 = mDataSet->at(i)->mValue; + + if(mDataSet->at(i+1)->mTime > StopTime) + { + X2 = StopTime - StartTime; + Y2 = mDataSet->at(i)->mValue; //Do not draw the vertical line if the point outside the span is not the same value. + } + else + { + X2 = mDataSet->at(i+1)->mTime - StartTime; + Y2 = mDataSet->at(i+1)->mValue; + } + + //Reverse the Y axis + if(Y1 == 0) + Y1 = 1; + else + Y1 = 0; + if(Y2 == 0) + Y2 = 1; + else + Y2 = 0; + + + if(Y1 == Y2) //no transition + { + NewLine.setLine(X1*tick,Y1*Height+1,X2*tick,Y2*Height+1); + mLinesList.append(NewLine); + } + else //value transition... + { + NewLine.setLine(X1*tick,Y1*Height+1,X2*tick,Y1*Height+1); //horizontal line + mLinesList.append(NewLine); + NewLine.setLine(X2*tick,Y1*Height+1,X2*tick,Y2*Height+1); //vertical line + mLinesList.append(NewLine); + } + } + + mDataValid = true; + +//#ifndef WINDOWS_OS + mGraphPixmap->fill(QColor(245, 245, 255)); + QPainter *painter = new QPainter(mGraphPixmap); + painter->drawLines(mLinesList); + delete painter; +//#endif + + update(); + + return RET_OK; +} + +void CGraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + +// static int toto = 0; +// qDebug("CGraphItem::paint %d",toto++); + + if(mDataValid == false) + return ; + if(mDataSet == 0) + return; + if(mDataSet->size() == 0) + return; + +// painter->setClipRect(option->exposedRect); + +// QPen pen; +// pen.setWidth(1); + +// pen.setColor(Qt::red); +// painter->setPen(pen); +// painter->drawRect(boundingRect()); + +// pen.setColor(Qt::black); +// painter->setPen(pen); + +//#ifdef WINDOWS_OS +// painter->drawLines(mLinesList); +//#else + painter->drawPixmap(0,0,*mGraphPixmap); +//#endif +// for(int i = 0; i < mLinesList.size(); i++) +// { +// painter->drawEllipse(mLinesList.at(i).p1(),2,2); +// } + +} + +void CGraphItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); +} + + +void CGraphItem::mouseReleaseEvent( QGraphicsSceneMouseEvent * event) +{ + event->ignore(); +} + +void CGraphItem::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + //mBackgroundRect->setRect(boundingRect()); + delete mGraphPixmap; + mGraphPixmap = new QPixmap(boundingRect().width(),boundingRect().height()); + DisplayData(mStartTime,mStopTime); +} +void CGraphItem::SetLabel(QString label,int Offset) +{ + QFont font; + font.setBold(true); + mLabel->setFont(font); + mLabel->setPlainText(label); + mLabel->setPos(-Offset,boundingRect().height()/2 - mLabel->boundingRect().height()/2); +} + + +CGraphDiscreteDataPair::CGraphDiscreteDataPair(quint32 Value, quint64 Time): + mValue(Value), + mTime(Time) +{ +} diff --git a/sources/GuiElements/GraphItem.h b/sources/GuiElements/GraphItem.h new file mode 100644 index 0000000..67cda70 --- /dev/null +++ b/sources/GuiElements/GraphItem.h @@ -0,0 +1,56 @@ +#ifndef CGRAPHITEM_H +#define CGRAPHITEM_H + +#include +#include +#include +#include +#include +#include + +class CGraphDiscreteDataPair +{ +public: + CGraphDiscreteDataPair(quint32 Value, quint64 Time); + quint32 mValue; + quint64 mTime; +}; + + +class CGraphItem : public QGraphicsWidget +{ + Q_OBJECT +public: + CGraphItem(QGraphicsItem *Parent = 0); + ~CGraphItem(); + + QList *mDataSet; + QGraphicsRectItem *mBackgroundRect; + +// unsigned int DisplayData(quint32 StartIndex, quint32 StopIndex); + unsigned int DisplayData(quint64 StartTime, quint64 StopTime); + void SetData(QList *DataList); +// void UpdateDisplay(void); + void SetLabel(QString label,int Offset); + + virtual void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + +private: + //quint64 mTimeSpan; + //quint64 mOffset; + bool mDataValid; + //quint32 mStartIndex,mStopIndex; + quint64 mStartTime, mStopTime; + QVector mLinesList; + QGraphicsTextItem *mLabel; + + QPixmap *mGraphPixmap; + + + +}; + +#endif // CGRAPHITEM_H diff --git a/sources/GuiElements/GraphRulerWidget.cpp b/sources/GuiElements/GraphRulerWidget.cpp new file mode 100644 index 0000000..f035ead --- /dev/null +++ b/sources/GuiElements/GraphRulerWidget.cpp @@ -0,0 +1,222 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Élément graphique qui affiche une règle de graduation temporelle dans le bas + de la zone d'affichage. + + Utilisée dans la page de visualisation des passages de train. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131024 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "GraphRulerWidget.h" +#include +#include +#include + +CGraphRulerWidget::CGraphRulerWidget(qreal RulerPixelWidth, QGraphicsItem *Parent) +{ + setParentItem(Parent); + mPixelWidth = RulerPixelWidth; + mPixelPitch = RulerPixelWidth/RULER_NB_TICKS; + + mRulerPixmap = new QPixmap(RulerPixelWidth,boundingRect().height()+1); +} + +CGraphRulerWidget::~CGraphRulerWidget() +{ + delete mRulerPixmap; +} + +void CGraphRulerWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + painter->setClipRect(option->exposedRect); + painter->drawPixmap(0,0,*mRulerPixmap); + +// static int toto = 0; +// qDebug("CGraphRulerWidget::paint %d",toto++); + +// qreal x = 0; +// QRectF TextRect(0,0,100,10); +// QString TimeText; +// qreal tick = (mEndTime - mStartTime)/mPixelWidth; +// QFont font; +// font.setPixelSize(12); +// painter->setFont(font); +// for(int i = 0; i <= RULER_NB_TICKS; i++) +// { +// QLine line; +// if(i%20 == 0) +// { +// TimeText.clear(); +// line.setLine(x,0,x,10); //long line +// TextRect.moveCenter(QPoint(x,15)); +// qreal time = (x*tick) + mStartTime; + +// if(time < 1000) +// { +// QTextStream(&TimeText) << time << " ns"; +// } +// else +// { +// time /= 1000; +// if(time < 1000) +// { +// QTextStream(&TimeText) << time << " us"; +// } +// else +// { +// time /= 1000; +// if(time < 1000) +// { +// QTextStream(&TimeText) << time << " ms"; +// } +// else +// { +// time /= 1000; +// if(time < 1000) +// { +// QTextStream(&TimeText) << time << " s"; +// } +// } +// } + +// } + +// painter->drawText(TextRect,Qt::AlignCenter,TimeText); + +// } +// else +// { +// line.setLine(x,0,x,5); +// } +// painter->drawLine(line); +// x += mPixelPitch; +// } +} + +unsigned int CGraphRulerWidget::SetRange(quint64 StartTime, quint64 EndTime) +{ + if(StartTime > EndTime) + return false; + + mStartTime = StartTime; + mEndTime = EndTime; + + Render(); + + update(); + + return RET_OK; +} + +void CGraphRulerWidget::Render() +{ + qreal x = 0; + QRectF TextRect(0,0,100,10); + QString TimeText; + qreal tick = (mEndTime - mStartTime)/mPixelWidth; + QFont font; + + mRulerPixmap->fill(Qt::white); + QPainter *painter = new QPainter(mRulerPixmap); + + font.setPixelSize(12); + painter->setFont(font); + for(int i = 0; i <= RULER_NB_TICKS; i++) + { + QLine line; + if(i%20 == 0) + { + TimeText.clear(); + line.setLine(x,0,x,10); //long line + + TextRect.moveCenter(QPoint(x,15)); + if(i == 0) + TextRect.moveLeft(x); + else if(i == RULER_NB_TICKS) + TextRect.moveRight(x); + + + qreal time = (x*tick) + mStartTime; + + if(time < 1000) + { + QTextStream(&TimeText) << time << " ns"; + } + else + { + time /= 1000; + if(time < 1000) + { + QTextStream(&TimeText) << time << " us"; + } + else + { + time /= 1000; + if(time < 1000) + { + QTextStream(&TimeText) << time << " ms"; + } + else + { + time /= 1000; + if(time < 1000) + { + QTextStream(&TimeText) << time << " s"; + } + } + } + + } + + if(i == 0) + painter->drawText(TextRect,Qt::AlignLeft | Qt::AlignVCenter,TimeText); + else if(i == RULER_NB_TICKS) + painter->drawText(TextRect,Qt::AlignRight | Qt::AlignVCenter,TimeText); + else + painter->drawText(TextRect,Qt::AlignCenter,TimeText); + + } + else + { + line.setLine(x,0,x,5); + } + painter->drawLine(line); + x += mPixelPitch; + } + + delete painter; + +} + +void CGraphRulerWidget::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + + delete mRulerPixmap; + mRulerPixmap = new QPixmap(mPixelWidth,boundingRect().height()+1); +} diff --git a/sources/GuiElements/GraphRulerWidget.h b/sources/GuiElements/GraphRulerWidget.h new file mode 100644 index 0000000..1a2bb2b --- /dev/null +++ b/sources/GuiElements/GraphRulerWidget.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131030 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef GRAPHRULERWIDGET_H +#define GRAPHRULERWIDGET_H + +#include "GlobalDefine.h" +#include + +#define RULER_NB_TICKS 200 + +class CGraphRulerWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CGraphRulerWidget(qreal RulerPixelWidth,QGraphicsItem *Parent = 0); + ~CGraphRulerWidget(); + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + unsigned int SetRange(quint64 StartTime, quint64 EndTime); + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + +private: + qreal mPixelWidth; + quint64 mStartTime, mEndTime; + qreal mPixelPitch; + + QPixmap *mRulerPixmap; + + void Render(); +}; + +#endif // GRAPHRULERWIDGET_H diff --git a/sources/GuiElements/GuiPage.cpp b/sources/GuiElements/GuiPage.cpp new file mode 100644 index 0000000..6292cf6 --- /dev/null +++ b/sources/GuiElements/GuiPage.cpp @@ -0,0 +1,42 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe de base d'une page de l'interface graphique (GUI = Graphics User Interface). + Une page contient les éléments graphiques affichés à l'écran. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "Guipage.h" +#include + + +CGuiPage::CGuiPage() +{ + +} + +void CGuiPage::ShowPage() +{ + +} diff --git a/sources/GuiElements/Guipage.h b/sources/GuiElements/Guipage.h new file mode 100644 index 0000000..a49adc8 --- /dev/null +++ b/sources/GuiElements/Guipage.h @@ -0,0 +1,52 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 201212120 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef GUIPAGE_H +#define GUIPAGE_H + +#include +#include +#include "GlobalDefine.h" + +class CGuiPage : public QGraphicsWidget +{ + Q_OBJECT + + +public: + + + CGuiPage(); + + virtual void ShowPage(); + + + +}; + +#endif // GUIPAGE_H diff --git a/sources/GuiElements/LedWidget.cpp b/sources/GuiElements/LedWidget.cpp new file mode 100644 index 0000000..300b0d9 --- /dev/null +++ b/sources/GuiElements/LedWidget.cpp @@ -0,0 +1,77 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Affiche un bitmap d'une DEL verte (allumée ou éteinte). + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131024 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + + +#include "LedWidget.h" +#include + +CLedWidget::CLedWidget(QString Label,QGraphicsItem *Parent) +{ + + setParentItem(Parent); + mLabel = new QGraphicsTextItem(this); + mLedOnPixmap = new QGraphicsPixmapItem(this); + mLedONImage.load("./Images/green-led-on-md.png"); + + mLedOffPixmap = new QGraphicsPixmapItem(this); + mLedOFFImage.load("./Images/green-led-off-md.png"); + + mLabel->setPlainText(Label); + mLabel->adjustSize(); + + LedOFF(); + + resize(25,25); + +} + +void CLedWidget::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + + mLedOnPixmap->setPixmap(QPixmap().fromImage(mLedONImage).scaled(boundingRect().width(),boundingRect().height())); + mLedOffPixmap->setPixmap(QPixmap().fromImage(mLedOFFImage).scaled(boundingRect().width(),boundingRect().height())); + mLabel->setPos((boundingRect().width()/2) - ((QFontMetrics(mLabel->font()).width(mLabel->toPlainText()))/2),boundingRect().height()); +} + +void CLedWidget::LedOFF() +{ + mLedOnPixmap->hide(); + mLedOffPixmap->show(); +} + +void CLedWidget::LedON() +{ + mLedOnPixmap->show(); + mLedOffPixmap->hide(); +} + +void CLedWidget::SetLed(bool ON) +{ + if(ON == true) + LedON(); + else + LedOFF(); +} diff --git a/sources/GuiElements/LedWidget.h b/sources/GuiElements/LedWidget.h new file mode 100644 index 0000000..5d66e9f --- /dev/null +++ b/sources/GuiElements/LedWidget.h @@ -0,0 +1,25 @@ +#ifndef LEDWIDGET_H +#define LEDWIDGET_H + +#include "GlobalDefine.h" +#include + +class CLedWidget : public QGraphicsWidget +{ + Q_OBJECT + +public: + CLedWidget(QString Label,QGraphicsItem *Parent = 0); + + QGraphicsTextItem *mLabel; + QImage mLedONImage,mLedOFFImage; + QGraphicsPixmapItem *mLedOnPixmap,*mLedOffPixmap; + + void LedON(); + void LedOFF(); + void SetLed(bool ON); + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); +}; + +#endif // LEDWIDGET_H diff --git a/sources/GuiElements/LogViewPage.cpp b/sources/GuiElements/LogViewPage.cpp new file mode 100644 index 0000000..dae2152 --- /dev/null +++ b/sources/GuiElements/LogViewPage.cpp @@ -0,0 +1,1269 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page de visualisation des passages de train. C'est cette classe qui gère + la création et l'affichage des éléments graphiques ainsi que les événements + de l'utilisateur. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131024 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "LogViewPage.h" +#include +#include "Zonetest.h" +#include + + +CLogViewPage::CLogViewPage(QGraphicsWidget *Parent) +{ + setParentItem(Parent); + + setAcceptsHoverEvents(true); + + + + mProgramHandle = 0; + mZoomValue = 100; + mStartTime = mStopTime = 0; + mCurTimeSpan = 0; + mMinTime = mMaxTime = 0; + mCurPixelTickValue = 1; + mMouseDragging = false; + mViewType = UNKNOWN_LOG_TYPE; + mPGTreshold = 0; + mCtrlKeyDown = false; + mShiftKeyDown = false; + + + setFlag(QGraphicsItem::ItemIsFocusable); + + + mStaticCursor1Pos = mStaticCursor2Pos = 0; + mCursorPos = 0; + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QPen rectpen; + QBrush BackgroundBrush(QColor(245, 245, 255)); + mBackgroundRect->setBrush(BackgroundBrush); + + + mCancelButton = new CTextButtonWidget("Fermer"); + mCancelButton->setParentItem(this); + mCancelButton->setPos(850,700); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + //Setup ZT1 plots + qreal PlotsHeight = ((GRAPH_ZONE_HEIGHT - 60) / (ZT1_DISCREET_PLOTTABLE_NB_PARAM + ZT1_ANALOG_PLOTTABLE_NB_PARAM + 1));//SDF analog plot is 3 units high, so add 2 units for this plot (hence the +2) + PlotsHeight -= (20 + (10/(ZT1_DISCREET_PLOTTABLE_NB_PARAM + ZT1_ANALOG_PLOTTABLE_NB_PARAM))) ; //space between plots + int CurPlot = 0; + for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT1DiscreetPlots[param].mParamID = param; + mZT1DiscreetPlots[param].mDataSet = new QList; + + CGraphItem * NewGraph = new CGraphItem(this); + //NewGraph->setPos(GRAPH_ZONE_X_OFFSET,param * (40 + 20)+10); + NewGraph->setPos(GRAPH_ZONE_X_OFFSET,CurPlot++ * (PlotsHeight + 20) + 10); + NewGraph->resize(GRAPH_ZONE_WIDTH,PlotsHeight); + + mZT1DiscreetPlots[param].mPlotGaph = NewGraph; + mZT1DiscreetPlots[param].mPlotGaph->SetData(mZT1DiscreetPlots[param].mDataSet); + } + mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_S1_PARAM].mPlotGaph->SetLabel("S1",GRAPH_ZONE_X_OFFSET); + mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_S2_PARAM].mPlotGaph->SetLabel("S2",GRAPH_ZONE_X_OFFSET); + mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_PPINT_PARAM].mPlotGaph->SetLabel("PP Int",GRAPH_ZONE_X_OFFSET); + mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_PPEXT_PARAM].mPlotGaph->SetLabel("PP Ext",GRAPH_ZONE_X_OFFSET); + //mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_PG_PARAM].mPlotGaph->SetLabel("PG",GRAPH_ZONE_X_OFFSET); + mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_FN_PARAM].mPlotGaph->SetLabel("FN",GRAPH_ZONE_X_OFFSET); + mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_CI_PARAM].mPlotGaph->SetLabel("CI",GRAPH_ZONE_X_OFFSET); + mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_ZT1_CDV_PARAM].mPlotGaph->SetLabel("CDV",GRAPH_ZONE_X_OFFSET); + + for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + mZT1AnalogPlots[param].mParamID = param; + mZT1AnalogPlots[param].mDataSet = new QList; + + CAnalogGraphItem *NewGraph = new CAnalogGraphItem(this); + // NewGraph->setPos(GRAPH_ZONE_X_OFFSET,(param+DISCREET_PLOTTABLE_NB_PARAM)*(40+20)+10); + NewGraph->setPos(GRAPH_ZONE_X_OFFSET,CurPlot++ * (PlotsHeight + 20) + 10); + NewGraph->resize(GRAPH_ZONE_WIDTH,PlotsHeight); + + mZT1AnalogPlots[param].mPlotGaph = NewGraph; + mZT1AnalogPlots[param].mPlotGaph->SetData(mZT1AnalogPlots[param].mDataSet); + } + mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGINT_PARAM].mPlotGaph->SetLabel("PG Int",GRAPH_ZONE_X_OFFSET); + mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGEXT_PARAM].mPlotGaph->SetLabel("PG Ext",GRAPH_ZONE_X_OFFSET); + mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_TRAIN_SPEED_PARAM].mPlotGaph->SetLabel("Vitesse",GRAPH_ZONE_X_OFFSET); + mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGCOMBINED_PARAM].mPlotGaph->SetLabel("Détection",GRAPH_ZONE_X_OFFSET); + mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_SDF_DATA_PARAM].mPlotGaph->SetLabel("SDF",GRAPH_ZONE_X_OFFSET); + mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_SDF_DATA_PARAM].mPlotGaph->resize(GRAPH_ZONE_WIDTH,PlotsHeight*3); //JFM: make SDF plot 3 times higher to help visualization. + + //Setup ZT2 Plots + PlotsHeight = ((GRAPH_ZONE_HEIGHT - 60) / (ZT2_DISCREET_PLOTTABLE_NB_PARAM + ZT2_ANALOG_PLOTTABLE_NB_PARAM)); + PlotsHeight -= (20 + (10/(ZT2_DISCREET_PLOTTABLE_NB_PARAM + ZT2_ANALOG_PLOTTABLE_NB_PARAM))) ; //space between plots + CurPlot = 0; + for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT2DiscreetPlots[param].mParamID = param; + mZT2DiscreetPlots[param].mDataSet = new QList; + + CGraphItem * NewGraph = new CGraphItem(this); + //NewGraph->setPos(GRAPH_ZONE_X_OFFSET,param * (40 + 20)+10); + NewGraph->setPos(GRAPH_ZONE_X_OFFSET,CurPlot++ * (PlotsHeight + 20) + 10); + NewGraph->resize(900,PlotsHeight); + + mZT2DiscreetPlots[param].mPlotGaph = NewGraph; + mZT2DiscreetPlots[param].mPlotGaph->SetData(mZT2DiscreetPlots[param].mDataSet); + } + mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_S1_PARAM].mPlotGaph->SetLabel("S1",GRAPH_ZONE_X_OFFSET); + mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_PPEXT_PARAM].mPlotGaph->SetLabel("PP Ext",GRAPH_ZONE_X_OFFSET); + mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_PPINT_PARAM].mPlotGaph->SetLabel("PP Int",GRAPH_ZONE_X_OFFSET); + mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_CI_PARAM].mPlotGaph->SetLabel("CI",GRAPH_ZONE_X_OFFSET); + mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_APPROACH_CDV_PARAM].mPlotGaph->SetLabel("CDV App.",GRAPH_ZONE_X_OFFSET); + mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_CDV_PARAM].mPlotGaph->SetLabel("CDV",GRAPH_ZONE_X_OFFSET); + + mVCursor = new CVerticalGraphCursorWidget(GRAPH_ZONE_HEIGHT,this); + mVCursor->setPos(0,0); + mVCursor->resize(3,GRAPH_ZONE_HEIGHT); + mVCursor->setZValue(2); + + mHCursor = new CHorizontalGraphCursorWidget(GRAPH_ZONE_WIDTH,this); + mHCursor->setPos(0,0); + mHCursor->resize(GRAPH_ZONE_WIDTH,3); + mHCursor->setZValue(2); + +// mCursorPosTxt = new QGraphicsTextItem(this); +// mCursorPosTxt->setPos(650,690); + + + mCursorsZoomButton = new CTextButtonWidget("Zoom curseurs"); + mCursorsZoomButton->setParentItem(this); + mCursorsZoomButton->setPos(10,700); + connect(mCursorsZoomButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mZoomInButton = new CTextButtonWidget(" +",0,25,25); + mZoomInButton->setParentItem(this); + mZoomInButton->setPos(95,730); + connect(mZoomInButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mZoomOutButton = new CTextButtonWidget(" -",0,25,25); + mZoomOutButton->setParentItem(this); + mZoomOutButton->setPos(10,730); + connect(mZoomOutButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mZoomResetButton = new CTextButtonWidget(" R",0,25,25); + mZoomResetButton->setParentItem(this); + mZoomResetButton->setPos(50,730); + connect(mZoomResetButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mStaticCursor1 = new CVerticalGraphCursorWidget(GRAPH_ZONE_HEIGHT,this); + mStaticCursor1->setPos(0,0); + mStaticCursor1->setZValue(1); + mStaticCursor1->SetColor(QColor(Qt::red)); + mStaticCursor1->hide(); + + mStaticCursor2 = new CVerticalGraphCursorWidget(GRAPH_ZONE_HEIGHT,this); + mStaticCursor2->setPos(0,0); + mStaticCursor2->setZValue(1); + mStaticCursor2->SetColor(QColor(Qt::green)); + mStaticCursor2->hide(); + + mStaticCursorDeltaTimeTxt = new QGraphicsTextItem(this); + mStaticCursorDeltaTimeTxt->setPos(130,700); + mStaticCursorDeltaTimeTxt->setPlainText("Delta curseurs: ?"); + + mCursor1TimeTxt = new QGraphicsTextItem(this); + mCursor1TimeTxt->setPlainText("Position curseur 1 : ?"); + mCursor1TimeTxt->setPos(130,720); + mCursor2TimeTxt = new QGraphicsTextItem(this); + mCursor2TimeTxt->setPlainText("Position curseur 2 : ?"); + mCursor2TimeTxt->setPos(130,740); + mPassageStats1Txt = new QGraphicsTextItem(this); + mPassageStats1Txt->setPos(350,700); + mPassageStats1Txt->setPlainText("Date & heure: \nStation : \nPosition : "); + mPassageStats2Txt = new QGraphicsTextItem(this); + mPassageStats2Txt->setPos(600,700); + mPassageStats2Txt->setPlainText("Vitesse Max : Mph\nVitesse Min: Mph\nSeuil PG : "); + + mRuler = new CGraphRulerWidget(GRAPH_ZONE_WIDTH,this); + mRuler->setZValue(1); + mRuler->setPos(GRAPH_ZONE_X_OFFSET,670); + mRuler->resize(GRAPH_ZONE_WIDTH,20); + + mRankRuler = new CRankRulerWidget(GRAPH_ZONE_WIDTH,this); + mRankRuler->setZValue(1); + mRankRuler->resize(GRAPH_ZONE_WIDTH,10); + mRankRuler->setPos(GRAPH_ZONE_X_OFFSET,655); + mRankRuler->SetLabel("Rang:",GRAPH_ZONE_X_OFFSET); + + mEventRuler = new CEventRulerWidget(GRAPH_ZONE_WIDTH,this); + mEventRuler->setZValue(1); + mEventRuler->resize(GRAPH_ZONE_WIDTH,10); + mEventRuler->setPos(GRAPH_ZONE_X_OFFSET,640); + mEventRuler->SetLabel("Décl:",GRAPH_ZONE_X_OFFSET); + + DestroyData(); + + mScrollRefreshTimer.start(); +} + +CLogViewPage::~CLogViewPage() +{ + DestroyData(); +} + +void CLogViewPage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + mBackgroundRect->setRect(boundingRect()); +} + +void CLogViewPage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mCancelButton) + { + DestroyData(); + mProgramHandle->LogViewCloseRequest(); + } + else if(BtnPtr == mCursorsZoomButton) + { + if(mStaticCursor1->IsCursorSet() && mStaticCursor2->IsCursorSet()) + ShowSpan(mStaticCursor1->GetPixelPos(),mStaticCursor2->GetPixelPos()); + } + else if(BtnPtr == mZoomInButton) + { + ZoomIn(false); + } + else if(BtnPtr == mZoomOutButton) + { + ZoomOut(false); + } + else if(BtnPtr == mZoomResetButton) + { + ShowSpan(mMinTime,mMaxTime); + } +} + + +void CLogViewPage::SetLogData(CLogElement *element) +{ + + DestroyData(); + mLogElement = element; + mViewType = mLogElement->mZTLogType; + mStaticCursor1->ClearCursor(); + mStaticCursor2->ClearCursor(); + mStaticCursorDeltaTimeTxt->setPlainText("Delta : ?"); + + + if(mViewType == ZT1_LOG_TYPE) + { + CZT1LogElement *ZT1LogElement = (CZT1LogElement*)element; + int CurRank = 0; + quint64 mRankStartTime = 0; + bool Done; + mPassageStation = ZT1LogElement->mStationName; + mPassageDateTime = ZT1LogElement->mPassageDateTime.toString("yyyy/MM/dd hh:mm:ss"); + qreal MaxTrainSpeed = 0, MinTrainSpeed = 10000; + + //Build all the datasets from the raw data. + + //JFM 2016-05-31 + //Check for invalid data in the last slot... + if(ZT1LogElement->mZTLogData.at(ZT1LogElement->mZTLogData.size()-1)->mTimestamp < ZT1LogElement->mZTLogData.at(ZT1LogElement->mZTLogData.size()-2)->mTimestamp) + { + delete ZT1LogElement->mZTLogData.at(ZT1LogElement->mZTLogData.size()-1); + ZT1LogElement->mZTLogData.remove(ZT1LogElement->mZTLogData.size()-1); + } + + //Discreet signals + for(int i = 0; i < ZT1LogElement->mZTLogData.size(); i++) + { + for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + CGraphDiscreteDataPair *DataSet = new CGraphDiscreteDataPair(0,ZT1LogElement->mZTLogData.at(i)->mTimestamp); + + if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData != 0) + { + if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mRank > (unsigned int)CurRank) + { + if(CurRank == 0) + { + mRankStartTime = ZT1LogElement->mZTLogData.at(i)->mTimestamp; + CurRank = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mRank; + } + else + { + mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT1LogElement->mZTLogData.at(i)->mTimestamp); + mRankStartTime = ZT1LogElement->mZTLogData.at(i)->mTimestamp; + CurRank = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mRank; + mRankStartTime = ZT1LogElement->mZTLogData.at(i)->mTimestamp; + + } + } + + + switch(param) + { + case ZT1_DISCREET_PLOTTABLE_S1_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mS1; + break; + } + case ZT1_DISCREET_PLOTTABLE_S2_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mS2; + break; + } + case ZT1_DISCREET_PLOTTABLE_PPINT_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPInt; + break; + } + case ZT1_DISCREET_PLOTTABLE_PPEXT_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPExt; + break; + } +// case ZT1_DISCREET_PLOTTABLE_PG_PARAM: +// { +// DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPG; +// break; +// } + case ZT1_DISCREET_PLOTTABLE_FN_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mFN; + break; + } + case ZT1_DISCREET_PLOTTABLE_CI_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mFN; + break; + } + case ZT1_DISCREET_PLOTTABLE_ZT1_CDV_PARAM: + { + break; + } + } + } + else if(i > 0) //if there is no data available, use the previous value... + { + DataSet->mValue = mZT1DiscreetPlots[param].mDataSet->at(i-1)->mValue; + + if(CurRank > 0 && Done == false) + { + Done = true; + mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT1LogElement->mZTLogData.at(i-1)->mTimestamp); + } + } + switch(param) + { + case ZT1_DISCREET_PLOTTABLE_CI_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mCIZT1; + break; + } + case ZT1_DISCREET_PLOTTABLE_ZT1_CDV_PARAM: + { + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mCDVARM_ZT1; + break; + } + } + + mZT1DiscreetPlots[param].mDataSet->append(DataSet); + } + + for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + CGraphAnalogDataPair *DataSet = new CGraphAnalogDataPair(0,ZT1LogElement->mZTLogData.at(i)->mTimestamp); + + if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData != 0) + { + switch(param) + { + case ZT1_ANALOG_PLOTTABLE_PGEXT_PARAM: + { + DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue; + break; + } + case ZT1_ANALOG_PLOTTABLE_PGINT_PARAM: + { + DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue; + break; + } + case ZT1_ANALOG_PLOTTABLE_TRAIN_SPEED_PARAM: + { + + DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mTrainSpeed; + if(DataSet->mValue > MaxTrainSpeed) + MaxTrainSpeed = DataSet->mValue; + + if(DataSet->mValue != 0 && DataSet->mValue < MinTrainSpeed) + MinTrainSpeed = DataSet->mValue; + + break; + } + case ZT1_ANALOG_PLOTTABLE_PGCOMBINED_PARAM: + { + qint32 PI = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue,PE = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue; + + qint32 offsetint = ZT1LogElement->mFlags.mIntPGOffset; + qint32 offsetext = ZT1LogElement->mFlags.mExtPGOffset; + qint32 tempint = (PI - offsetint); + qint32 tempext = (PE - offsetext); + qint32 Quadra = tempint*tempext; + DataSet->mValue = (qreal)Quadra; + //qDebug("%f",DataSet->mValue); + + break; + } + case ZT1_ANALOG_PLOTTABLE_SDF_DATA_PARAM: + { + if(ZT1LogElement->mFlags.mAnalogTracePresent == true) + { + DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mAnalogData/* * 10 / 4096*/; //JFM 20140821 + } + break; + } + } + } + else //No analog data... set to 0 + { + DataSet->mValue = 0; + } + mZT1AnalogPlots[param].mDataSet->append(DataSet); + } + } + + for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + mZT1AnalogPlots[param].mPlotGaph->SetAbsoluteLimits(ZT1LogElement->mThreadDataStartTime,ZT1LogElement->mThreadDataEndTime); + } + + mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_PGCOMBINED_PARAM].mPlotGaph->AddHorizontalLine(ZT1LogElement->mFlags.mPGTresholdValue); + mPGTreshold = ZT1LogElement->mFlags.mPGTresholdValue; + + // mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT1LogElement->mZTLogData.last()->mTimestamp); + + mMinTime = mStartTime = mZT1DiscreetPlots[0].mDataSet->first()->mTime; + mMaxTime = mZT1DiscreetPlots[0].mDataSet->last()->mTime; + + if(ZT1LogElement->mZTDetections.size() == 0) + { + mEventRuler->ClearRuler(); + } + else + { + for(int event = 0; event < ZT1LogElement->mZTDetections.size(); event++) + { + mEventRuler->AddEventItem(CZTData::GetShortErrorString(ZT1LogElement->mZTDetections.at(event)->mDetectionID),ZT1LogElement->mZTDetections.at(event)->mTimeStamp); + } + } + + mPassageStats2Txt->setPlainText(QString().sprintf("Vitesse Max : %.3f Mph\nVitesse Min: %.3f Mph\nSeuil PG : %d",MaxTrainSpeed,MinTrainSpeed,mPGTreshold)); + + } + else if(mViewType == ZT2_LOG_TYPE) + { + int CurRank = 0; + quint64 mRankStartTime = 0; + + + CZT2LogElement *ZT2LogElement = (CZT2LogElement*)element; + mPassageDateTime = ZT2LogElement->mPassageDateTime.toString("yyyy/MM/dd hh:mm:ss");; + mPassageStation = ZT2LogElement->mStationName; + mPassageStats2Txt->setPlainText("Vitesse Max : N/A\nVitesse Min: N/A\nSeuil PG : N/A"); + + for(int i = 0; i < ZT2LogElement->mZTLogData.size(); i++) + { + for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + CGraphDiscreteDataPair *DataSet = new CGraphDiscreteDataPair(0,ZT2LogElement->mZTLogData.at(i)->mTimestamp); + if(ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData != 0) + { + if(ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mRank > (unsigned int)CurRank) + { + if(CurRank == 0) + { + mRankStartTime = ZT2LogElement->mZTLogData.at(i)->mTimestamp; + CurRank = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mRank; + } + else + { + mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT2LogElement->mZTLogData.at(i)->mTimestamp); + mRankStartTime = ZT2LogElement->mZTLogData.at(i)->mTimestamp; + CurRank = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mRank; + mRankStartTime = ZT2LogElement->mZTLogData.at(i)->mTimestamp; + + } + } + + + switch(param) + { + case ZT2_DISCREET_PLOTTABLE_S1_PARAM: + { + DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mS1; + break; + } + case ZT2_DISCREET_PLOTTABLE_PPEXT_PARAM: + { + DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mPPExt; + break; + } + case ZT2_DISCREET_PLOTTABLE_PPINT_PARAM: + { + DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mZT2ThreadData->mPPInt; + break; + } + + } + } + else if(i > 0) //if there is no data available, use the previous value... + { + DataSet->mValue = mZT2DiscreetPlots[param].mDataSet->at(i-1)->mValue; + } + switch(param) + { + case ZT2_DISCREET_PLOTTABLE_CI_PARAM: + { + DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mCIZT2; + break; + } + case ZT2_DISCREET_PLOTTABLE_CDV_PARAM: + { + DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mCDVARM_ZT2; + break; + } + case ZT2_DISCREET_PLOTTABLE_APPROACH_CDV_PARAM: + { + DataSet->mValue = ZT2LogElement->mZTLogData.at(i)->mCDVApproach_ZT2; + } + } + + mZT2DiscreetPlots[param].mDataSet->append(DataSet); + } + +// for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) +// { +// CGraphAnalogDataPair *DataSet = new CGraphAnalogDataPair(0,ZT1LogElement->mZTLogData.at(i)->mTimestamp); +// if(ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData != 0) +// { +// switch(param) +// { +// case ZT1_ANALOG_PLOTTABLE_PGEXT_PARAM: +// { +// DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue; +// break; +// } +// case ZT1_ANALOG_PLOTTABLE_PGINT_PARAM: +// { +// DataSet->mValue = (qreal)ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue; +// break; +// } +// case ZT1_ANALOG_PLOTTABLE_TRAIN_SPEED_PARAM: +// { + +// DataSet->mValue = ZT1LogElement->mZTLogData.at(i)->mZT1ThreadData->mTrainSpeed; +// // if(DataSet->mValue == 0) +// // DataSet->mValue = -1; +// break; +// } +// } +// } +// else //No analog data... set to 0 +// { +// DataSet->mValue = 0; +// } +// mZT1AnalogPlots[param].mDataSet->append(DataSet); +// } + } + + mRankRuler->AddRankItem(QString().sprintf("%d",CurRank),mRankStartTime,ZT2LogElement->mZTLogData.last()->mTimestamp); + + mMinTime = mStartTime = mZT2DiscreetPlots[0].mDataSet->first()->mTime; + mMaxTime = mZT2DiscreetPlots[0].mDataSet->last()->mTime; + + if(ZT2LogElement->mZTDetections.size() == 0) + { + mEventRuler->ClearRuler(); + } + else + { + for(int event = 0; event < ZT2LogElement->mZTDetections.size(); event++) + { + mEventRuler->AddEventItem(CZTData::GetShortErrorString(ZT2LogElement->mZTDetections.at(event)->mDetectionID),ZT2LogElement->mZTDetections.at(event)->mTimeStamp); + } + } + + } + else + { + return; + } + + mStopTime = mMaxTime; + mTotalTimeSpan = mMaxTime - mMinTime; + mCurTimeSpan = mStopTime - mStartTime; + + mCurPixelTickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; //pixels per microsecs + mCursorPos = mStartTime; + + mPassageStats1Txt->setPlainText(QString().sprintf("Date & heure: %s\nStation : %s\nPosition : %s",mPassageDateTime.toUtf8().data(),mPassageStation.toUtf8().data()," ")); + + ShowSpan(mStartTime,mStopTime); + + ShowPlots(mViewType); + +// for(int param = 0; param < DISCREET_PLOTTABLE_NB_PARAM; param++) +// { +// mZT1DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); +// } +} + +void CLogViewPage::ShowPlots(unsigned int ViewType) +{ + if(ViewType == ZT1_LOG_TYPE) + { + for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT1DiscreetPlots[param].mPlotGaph->show(); + } + for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + mZT1AnalogPlots[param].mPlotGaph->show(); + } + for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT2DiscreetPlots[param].mPlotGaph->hide(); + } + for(int param = 0; param < ZT2_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + // mZT1AnalogPlots[param].mPlotGaph->show(); + } + } + else if(ViewType == ZT2_LOG_TYPE) + { + for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT1DiscreetPlots[param].mPlotGaph->hide(); + } + for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + mZT1AnalogPlots[param].mPlotGaph->hide(); + } + for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT2DiscreetPlots[param].mPlotGaph->show(); + } + for(int param = 0; param < ZT2_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + // mZT1AnalogPlots[param].mPlotGaph->show(); + } + } +} + +void CLogViewPage::DestroyData() +{ + for(int item = 0; item < ZT1_DISCREET_PLOTTABLE_NB_PARAM; item++) + { + for(int i = 0; i < mZT1DiscreetPlots[item].mDataSet->size(); i++) + { + delete mZT1DiscreetPlots[item].mDataSet->at(i); + } + mZT1DiscreetPlots[item].mDataSet->clear(); + } + + for(int item = 0; item < ZT1_ANALOG_PLOTTABLE_NB_PARAM; item++) + { + for(int i = 0; i < mZT1AnalogPlots[item].mDataSet->size(); i++) + { + delete mZT1AnalogPlots[item].mDataSet->at(i); + } + mZT1AnalogPlots[item].mDataSet->clear(); + } + + for(int item = 0; item < ZT2_DISCREET_PLOTTABLE_NB_PARAM; item++) + { + for(int i = 0; i < mZT2DiscreetPlots[item].mDataSet->size(); i++) + { + delete mZT2DiscreetPlots[item].mDataSet->at(i); + } + mZT2DiscreetPlots[item].mDataSet->clear(); + } + + for(int item = 0; item < ZT2_ANALOG_PLOTTABLE_NB_PARAM; item++) + { +// for(int i = 0; i < mZT2AnalogPlots[item].mDataSet->size(); i++) +// { +// delete mZT1AnalogPlots[item].mDataSet->at(i); +// } +// mZT1AnalogPlots[item].mDataSet->clear(); + } + + mRankRuler->ClearRuler(); + mEventRuler->ClearRuler(); +} + +void CLogViewPage::ZoomIn(bool CenterOnCursor) +{ + + //First, compute a zoom centered on the center of the area + qint64 NewSpan = mCurTimeSpan - (mCurTimeSpan/5); + if(NewSpan < 1000000) + { + NewSpan = mCurTimeSpan; //stop zooming + } + qint64 delta = mCurTimeSpan - NewSpan; + quint64 StartTime = mStartTime + delta/2; + quint64 StopTime = StartTime + NewSpan; + if(StopTime > mMaxTime) + { + StopTime = mMaxTime; + StartTime = StopTime - NewSpan; + } + + if(CenterOnCursor) + { +#ifdef ZOOM_CENTERED_ON_CURSOR + + //Now let's find how many pixels have moved from the cursor + //by finding the position of the cursor time in the new timespan + quint64 CursorTime = GetTimeForPixel(mCursorPos); + + //Convert time to pixels (in the new timespan) + quint64 AbsoluteTime = CursorTime - StartTime; + qreal PixelsPernSecs = (qreal)GRAPH_ZONE_WIDTH/(NewSpan); + qreal Pixel = AbsoluteTime * PixelsPernSecs; + + Pixel += GRAPH_ZONE_X_OFFSET; + + //Find from how much pixels we have moved + qreal DeltaX = Pixel - mCursorPos; + + //convert this to an amount of time + qint64 DeltaTime = ((qint64)DeltaX * NewSpan)/GRAPH_ZONE_WIDTH; + + //Shift the timespan to center the zoom on the cursor. + StartTime += DeltaTime; + if(StartTime < mMinTime) + { + StartTime = mMinTime; + } + StopTime = StartTime + NewSpan; + if(StopTime > mMaxTime) + { + StopTime = mMaxTime; + StartTime = StopTime - NewSpan; + } + +#endif + } + + ShowSpan(StartTime,StopTime); +} + +void CLogViewPage::ZoomOut(bool CenterOnCursor) +{ + qint64 NewSpan = mCurTimeSpan + (mCurTimeSpan/5); + if(NewSpan > (qint64)(mMaxTime - mMinTime)) + { + ShowSpan(mMinTime,mMaxTime); + } + else + { + + qint64 delta = NewSpan - mCurTimeSpan; + + qint64 StartTime = mStartTime - delta/2; + + if(StartTime < (qint64)mMinTime/* || StartTime < 0*/) + { + StartTime = mMinTime; + } + quint64 StopTime = StartTime + NewSpan; + if(StopTime > mMaxTime) + { + StopTime = mMaxTime; + StartTime = StopTime - NewSpan; + } + + if(CenterOnCursor == true) + { +#ifdef ZOOM_CENTERED_ON_CURSOR + quint64 CursorTime = GetTimeForPixel(mCursorPos); + + //Convert time to pixels (in the new timespan) + quint64 AbsoluteTime = CursorTime - StartTime; + qreal PixelsPernSecs = (qreal)GRAPH_ZONE_WIDTH/(NewSpan); + qreal Pixel = AbsoluteTime * PixelsPernSecs; + + Pixel += GRAPH_ZONE_X_OFFSET; + + //Find from how much pixels we have moved + qreal DeltaX = Pixel - mCursorPos; + + //convert this to an amount of time + qint64 DeltaTime = ((qint64)DeltaX * NewSpan)/GRAPH_ZONE_WIDTH; + + //Shift the timespan to center the zoom on the cursor. + StartTime += DeltaTime; + if(StartTime < (qint64)mMinTime/* || StartTime < 0*/) + { + StartTime = mMinTime; + } + StopTime = StartTime + NewSpan; + if(StopTime > mMaxTime) + { + StopTime = mMaxTime; + StartTime = StopTime - NewSpan; + } +#endif + } + + ShowSpan(StartTime,StopTime); + } +} + +void CLogViewPage::SetZoom(int ZoomValue) +{ + Q_UNUSED(ZoomValue) +} + +//Grab the mouse if the user clicks outside buttons +void CLogViewPage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + + if(event->button() == Qt::LeftButton) + { + mMouseDragging = true; + mMouseMoved = false; + } + event->accept(); +} +void CLogViewPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + + if(event->button() == Qt::LeftButton) + { + mMouseDragging = false; + + if(mMouseMoved == false) + { + mStaticCursor1->setPos(event->pos().x(),0); + mStaticCursor1->SetTime(GetTimeForPixel(event->pos().x())); + mStaticCursor1->SetCursor(); + mStaticCursor1->show(); + UpdateStaticCursorsDeltaTime(); + mCursor1TimeTxt->setPlainText(QString().sprintf("Position curseur 1 : %d ms",(int)(mStaticCursor1->GetTime()/1000000))); + } + } + if(event->button() == Qt::RightButton) + { + mStaticCursor2->setPos(event->pos().x(),0); + mStaticCursor2->SetTime(GetTimeForPixel(event->pos().x())); + mStaticCursor2->SetCursor(); + mStaticCursor2->show(); + mCursor2TimeTxt->setPlainText(QString().sprintf("Position curseur 2 : %d ms",(int)(mStaticCursor2->GetTime()/1000000))); + UpdateStaticCursorsDeltaTime(); + } + + event->accept(); +} +void CLogViewPage::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if(mMouseDragging) + { + + DragPlots(event->lastPos().x() - event->pos().x()); + +// mMouseMoved = true; +// qreal Drag = event->lastPos().x() - event->pos().x(); +// //qreal Drag = 50; +// if(Drag != 0) +// { +// qreal TickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; +// qreal temp = TickValue/Drag; +// //quint64 usecsDrag = 1/(mCurPixelTickValue/Drag); +// qint64 usecsDrag = 1/temp; +// ScrollGraphs(usecsDrag); +// } + } + + AdjustMouseCursorPos(event->pos().x(),event->pos().y()); + event->accept(); + +} + +void CLogViewPage::DragPlots(qreal DragValue) +{ + mMouseMoved = true; + qreal Drag = DragValue; + //qreal Drag = 50; + if(Drag != 0) + { + qreal TickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; + qreal temp = TickValue/Drag; + //quint64 usecsDrag = 1/(mCurPixelTickValue/Drag); + qint64 usecsDrag = 1/temp; + ScrollGraphs(usecsDrag); + } +} + + +bool CLogViewPage::eventFilter(QObject *obj, QEvent *event) +{ + if(isVisible()) //Check if event is coming from us + { + if(event->type() == QEvent::KeyPress) + { + QKeyEvent *KeyEvent = static_cast(event); + + if(KeyEvent->key() == Qt::Key_Left) + { + AdjustMouseCursorPos(mVCursor->GetPixelPos() - 1,mHCursor->GetPixelPos()); + return true; //keep the keystroke + } + if(KeyEvent->key() == Qt::Key_Right) + { + AdjustMouseCursorPos(mVCursor->GetPixelPos() + 1,mHCursor->GetPixelPos()); + return true; //keep the keystroke + } + if(KeyEvent->key() == Qt::Key_Control) + { + mCtrlKeyDown = true; + return true; + } + if(KeyEvent->key() == Qt::Key_Shift) + { + mShiftKeyDown = true; + return true; + } + } + else if(event->type() == QEvent::KeyRelease) + { + QKeyEvent *KeyEvent = static_cast(event); + if(KeyEvent->key() == Qt::Key_Control) + { + mCtrlKeyDown = false; + return true; + } + if(KeyEvent->key() == Qt::Key_Shift) + { + mShiftKeyDown = false; + return true; + } + } + } + + return QObject::eventFilter(obj,event); + +} + +void CLogViewPage::wheelEvent(QGraphicsSceneWheelEvent *event) +{ + + //Zoom must be higher than 100 (100%) + //That is full scale. + //int Zoom; + if(event-> delta() < 0) + { + ZoomOut(); +// Zoom = mZoomValue - ZOOM_TICK; +// if(Zoom < 100) +// Zoom = 100; + } + else + { + ZoomIn(); +// Zoom = mZoomValue + ZOOM_TICK; + } + +// mZoomValue = Zoom; + +// SetZoom(Zoom); + event->accept(); +} + +void CLogViewPage::ScrollGraphs(qint64 Delta) +{ + quint64 CurTimeSpan = mStopTime - mStartTime; + + + if(Delta > 0) + { + + + if(mStopTime + Delta >= mMaxTime) + { + mStopTime = mMaxTime; + } + else + { + mStopTime += Delta; + } + + mStartTime = mStopTime - CurTimeSpan; + + } + else + { +// if(mStartTime == mMinTime) +// return; + + //Delta is negative !! + qint64 start = mStartTime + Delta; + if(start <= (qint64)mMinTime) + { + mStartTime = mMinTime; + } + else + { + mStartTime += Delta; + } + mStopTime = mStartTime + CurTimeSpan; + } + +// qDebug() << "StartTime = " << mStartTime << "StopTime = " << mStopTime << "delta= " << Delta; + + if(mScrollRefreshTimer.elapsed() > 33) //limit the scroll redraw to 30FPS + { + ShowSpan(mStartTime,mStopTime); + mScrollRefreshTimer.start(); + } +// for(int param = 0; param < DISCREET_PLOTTABLE_NB_PARAM; param++) +// { +// mZT1DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); +// } +} + + +void CLogViewPage::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + AdjustMouseCursorPos(event->pos().x(),event->pos().y()); + + if(mShiftKeyDown) + { + qreal Drag = event->lastPos().x() - event->pos().x(); + DragPlots(Drag); + AdjustMouseCursorPos(event->pos().x(),event->pos().y()); + } + else if(mCtrlKeyDown) + { + qreal Drag = event->lastPos().y() - event->pos().y(); + if(Drag != 0) + { + if(Drag > 0) + { + ZoomIn(); + } + else + { + ZoomOut(); + } + + } + } + +// mCursorPos = event->pos().x(); +// if(mCursorPos < GRAPH_ZONE_X_OFFSET) +// mCursorPos = GRAPH_ZONE_X_OFFSET; +// else if(mCursorPos > GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET) +// mCursorPos = GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET; + +// mCursor->setPos(mCursorPos,0); +// int CursorTime = GetTimeForPixel(mCursorPos)/1000000; +// mCursorPosTxt->setPlainText(QString().sprintf("%d ms",CursorTime)); +} + +qreal CLogViewPage::GetPixelForTime(quint64 Time) +{ + quint64 AbsoluteTime = Time - mStartTime; + qreal PixelsPernSecs = (qreal)GRAPH_ZONE_WIDTH/(mStopTime - mStartTime); + qreal Pixel = AbsoluteTime * PixelsPernSecs; + + return Pixel+GRAPH_ZONE_X_OFFSET; +} + +quint64 CLogViewPage::GetTimeForPixel(qreal PixelPos) +{ + PixelPos -= GRAPH_ZONE_X_OFFSET; + qreal nSecsPerPixels = (mStopTime - mStartTime)/GRAPH_ZONE_WIDTH; + quint64 AbsoluteTimeForPixel = PixelPos*nSecsPerPixels; + quint64 Time = mStartTime + AbsoluteTimeForPixel; + + return Time; +} + +unsigned int CLogViewPage::ShowSpan(qreal PixelPos1, qreal PixelPos2) +{ + return ShowSpan(GetTimeForPixel(PixelPos1),GetTimeForPixel(PixelPos2)); +} +unsigned int CLogViewPage::ShowSpan(quint64 TimePos1, quint64 TimePos2) +{ + if(TimePos1 > TimePos2) + { + mStartTime = TimePos2; + mStopTime = TimePos1; + } + else + { + mStartTime = TimePos1; + mStopTime = TimePos2; + } + + mCurTimeSpan = mStopTime - mStartTime; + mCurPixelTickValue = (qreal)GRAPH_ZONE_WIDTH/(qreal)mCurTimeSpan; //pixels per microsecs + + if(mViewType == ZT1_LOG_TYPE) + { + for(int param = 0; param < ZT1_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT1DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); + } + for(int param = 0; param < ZT1_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + mZT1AnalogPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); + } + } + else if(mViewType == ZT2_LOG_TYPE) + { + for(int param = 0; param < ZT2_DISCREET_PLOTTABLE_NB_PARAM; param++) + { + mZT2DiscreetPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); + } + for(int param = 0; param < ZT2_ANALOG_PLOTTABLE_NB_PARAM; param++) + { + // mZT2AnalogPlots[param].mPlotGaph->DisplayData(mStartTime,mStopTime); + } + } + else + return RET_ERROR; + + AdjustStaticCursorsPos(); + mRuler->SetRange(mStartTime,mStopTime); + mRankRuler->SetRange(mStartTime,mStopTime); + mEventRuler->SetRange(mStartTime,mStopTime); + + return RET_OK; +} + +unsigned int CLogViewPage::AdjustStaticCursorsPos() +{ + if(mStaticCursor1->IsCursorSet()) + { + quint64 CursorTime = mStaticCursor1->GetTime(); + if(CursorTime < mStartTime || CursorTime > mStopTime) + { + mStaticCursor1->hide(); + } + else + { + qreal newpos = GetPixelForTime(CursorTime); + mStaticCursor1->setPos(newpos,0); + mStaticCursor1->show(); + } + } + if(mStaticCursor2->IsCursorSet()) + { + quint64 CursorTime = mStaticCursor2->GetTime(); + if(CursorTime < mStartTime || CursorTime > mStopTime) + { + mStaticCursor2->hide(); + } + else + { + qreal newpos = GetPixelForTime(CursorTime); + mStaticCursor2->setPos(newpos,0); + mStaticCursor2->show(); + } + } + return RET_OK; +} + +unsigned int CLogViewPage::AdjustMouseCursorPos(qreal PosX, qreal PosY) +{ + mCursorPos = PosX; + if(mCursorPos < GRAPH_ZONE_X_OFFSET) + mCursorPos = GRAPH_ZONE_X_OFFSET; + else if(mCursorPos > GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET) + mCursorPos = GRAPH_ZONE_WIDTH + GRAPH_ZONE_X_OFFSET; + + qreal HCursorPos = PosY; + if(HCursorPos > GRAPH_ZONE_HEIGHT) + HCursorPos = GRAPH_ZONE_HEIGHT; + + + mVCursor->setPos(mCursorPos,0); + mHCursor->setPos(GRAPH_ZONE_X_OFFSET,HCursorPos); + // mCursor->update(); + int CursorTime = GetTimeForPixel(mCursorPos)/1000000; + mPassageStats1Txt->setPlainText(QString().sprintf("Date & heure: %s\nStation : %s\nPosition : %d ms",mPassageDateTime.toUtf8().data(),mPassageStation.toUtf8().data(),CursorTime)); +// mCursorPosTxt->setPlainText(QString().sprintf("%d ms",CursorTime)); + + for(int i = 0; i < ZT1_ANALOG_PLOTTABLE_NB_PARAM; i++) + mZT1AnalogPlots[i].mPlotGaph->GetValueForTime(GetTimeForPixel(mCursorPos)); + + update(mVCursor->boundingRect()); + update(mHCursor->boundingRect()); + return RET_OK; +} + +unsigned int CLogViewPage::UpdateStaticCursorsDeltaTime() +{ + if(mStaticCursor1->IsCursorSet() == true && mStaticCursor2->IsCursorSet() == true) + { + QString Temp; + quint64 Cur1,Cur2; + qint64 Diff; + Cur1 = mStaticCursor1->GetTime(); + Cur2 = mStaticCursor2->GetTime(); + Diff = Cur1 - Cur2; + //qreal Delta = (qreal)(mStaticCursor1->GetTime() - mStaticCursor2->GetTime()); + qreal Delta = Diff; + if(Delta < 0) + Delta *= -1; + + if(Delta/1000000000 > 1) + { + QTextStream(&Temp) << "Delta: " << Delta/1000000000 << " s"; + } + else if(Delta/1000000 > 1) + { + QTextStream(&Temp) << "Delta: " << Delta/1000000 << " ms"; + } + else if(Delta/1000 > 1) + { + QTextStream(&Temp) << "Delta: " << Delta/1000 << " us"; + } + else + { + QTextStream(&Temp) << "Delta: " << Delta << " ns"; + } + + mStaticCursorDeltaTimeTxt->setPlainText(Temp); + } + + return RET_OK; + +} diff --git a/sources/GuiElements/LogViewPage.h b/sources/GuiElements/LogViewPage.h new file mode 100644 index 0000000..7268ef4 --- /dev/null +++ b/sources/GuiElements/LogViewPage.h @@ -0,0 +1,204 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131024 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef LOGVIEWPAGE_H +#define LOGVIEWPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "TextButtonWidget.h" +#include "LogMgr.h" +#include +#include "GraphItem.h" +//#include "qcustomplot.h" +#include "GraphCursorWidget.h" +#include "GraphRulerWidget.h" +#include "AnalogGraphItem.h" +#include "RankRulerWidget.h" +#include "EventsRulerWidget.h" +#include + +#define GRAPH_ZONE_WIDTH 880//900 +#define GRAPH_ZONE_HEIGHT 700 +#define GRAPH_ZONE_X_OFFSET 70 //50 +#define MIN_TIMESPAN 1000 //1 millisecond + +#define ZOOM_TICK 10 +#define SCROLL_TICK 1 +#define ZOOM_CENTERED_ON_CURSOR + +class CZoneTest; + +enum eZT1DiscreetPlottableParamID +{ + ZT1_DISCREET_PLOTTABLE_S1_PARAM, + ZT1_DISCREET_PLOTTABLE_S2_PARAM, + ZT1_DISCREET_PLOTTABLE_PPINT_PARAM, + ZT1_DISCREET_PLOTTABLE_PPEXT_PARAM, + //ZT1_DISCREET_PLOTTABLE_PG_PARAM, + ZT1_DISCREET_PLOTTABLE_FN_PARAM, + ZT1_DISCREET_PLOTTABLE_CI_PARAM, + ZT1_DISCREET_PLOTTABLE_ZT1_CDV_PARAM, + + ZT1_DISCREET_PLOTTABLE_NB_PARAM +}; + +enum eZT1AnalogPlottableParamID +{ + ZT1_ANALOG_PLOTTABLE_PGINT_PARAM, + ZT1_ANALOG_PLOTTABLE_PGEXT_PARAM, + ZT1_ANALOG_PLOTTABLE_PGCOMBINED_PARAM, + ZT1_ANALOG_PLOTTABLE_TRAIN_SPEED_PARAM, + ZT1_ANALOG_PLOTTABLE_SDF_DATA_PARAM, + + + ZT1_ANALOG_PLOTTABLE_NB_PARAM +}; + +enum eZT2DiscreetPlottableParamID +{ + ZT2_DISCREET_PLOTTABLE_S1_PARAM, + ZT2_DISCREET_PLOTTABLE_PPEXT_PARAM, + ZT2_DISCREET_PLOTTABLE_PPINT_PARAM, + ZT2_DISCREET_PLOTTABLE_CI_PARAM, + ZT2_DISCREET_PLOTTABLE_APPROACH_CDV_PARAM, + ZT2_DISCREET_PLOTTABLE_CDV_PARAM, + + ZT2_DISCREET_PLOTTABLE_NB_PARAM +}; + +enum eZT2AnalogPlottableParamID +{ + ZT2_ANALOG_PLOTTABLE_NB_PARAM +}; + + +class CDiscreetPlottableItem +{ +public: + unsigned int mParamID; + QList *mDataSet; + CGraphItem *mPlotGaph; +}; + +class CAnalogPlottableItem +{ +public: + unsigned int mParamID; + QList *mDataSet; + CAnalogGraphItem *mPlotGaph; +}; + + + +class CLogViewPage : public CGuiPage +{ +Q_OBJECT +public: + CLogViewPage(QGraphicsWidget *Parent = 0); + ~CLogViewPage(); + + CZoneTest *mProgramHandle; + CLogElement *mLogElement; + CDiscreetPlottableItem mZT1DiscreetPlots[ZT1_DISCREET_PLOTTABLE_NB_PARAM]; + CAnalogPlottableItem mZT1AnalogPlots[ZT1_ANALOG_PLOTTABLE_NB_PARAM]; + CDiscreetPlottableItem mZT2DiscreetPlots[ZT2_DISCREET_PLOTTABLE_NB_PARAM]; + + void SetLogData(CLogElement *element); + void DestroyData(); + + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void wheelEvent(QGraphicsSceneWheelEvent *event); + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + virtual bool eventFilter(QObject *obj, QEvent *event); + + + +private: + + QGraphicsRectItem *mBackgroundRect; + CTextButtonWidget *mCancelButton; + CTextButtonWidget *mCursorsZoomButton, *mZoomInButton, *mZoomOutButton, *mZoomResetButton; + int mZoomValue; + quint64 mStartTime, mStopTime; + quint64 mCurTimeSpan; + quint64 mTotalTimeSpan; + quint64 mMinTime, mMaxTime; + qreal mCurPixelTickValue; + qint32 mPGTreshold; + CVerticalGraphCursorWidget *mStaticCursor1, *mStaticCursor2, *mVCursor; + CHorizontalGraphCursorWidget *mHCursor; + QGraphicsTextItem *mCursorPosTxt; + QGraphicsTextItem *mStaticCursorDeltaTimeTxt, *mCursor1TimeTxt, *mCursor2TimeTxt; + QGraphicsTextItem *mPassageStats1Txt,*mPassageStats2Txt; + QString mPassageDateTime, mPassageStation; + + CGraphRulerWidget *mRuler; + CRankRulerWidget *mRankRuler; + CEventRulerWidget *mEventRuler; + unsigned int mViewType; + + int mStaticCursor1Pos, mStaticCursor2Pos; + int mCursorPos; + + bool mMouseDragging; + bool mMouseMoved; + bool mCtrlKeyDown; + bool mShiftKeyDown; + + QElapsedTimer mScrollRefreshTimer; + + void SetZoom(int ZoomValue); + void ZoomIn(bool CenterOnCursor = true); + void ZoomOut(bool CenterOnCursor = true); + void ScrollGraphs(qint64 Delta); + quint64 GetTimeForPixel(qreal PixelPos); + qreal GetPixelForTime(quint64 Time); + unsigned int ShowSpan(qreal PixelPos1, qreal PixelPos2); + unsigned int ShowSpan(quint64 TimePos1, quint64 TimePos2); + unsigned int AdjustStaticCursorsPos(); + unsigned int AdjustMouseCursorPos(qreal PosX, qreal PosY); + unsigned int UpdateStaticCursorsDeltaTime(); + void ShowPlots(unsigned int ViewType); + void DragPlots(qreal DragValue); + + + +public slots: + void ButtonClicked(CTextButtonWidget *); + +}; + +#endif // LOGVIEWPAGE_H diff --git a/sources/GuiElements/LogsListPage.cpp b/sources/GuiElements/LogsListPage.cpp new file mode 100644 index 0000000..22ce276 --- /dev/null +++ b/sources/GuiElements/LogsListPage.cpp @@ -0,0 +1,857 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page affichant la liste des passages de train. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "LogsListPage.h" +#include +#include "Zonetest.h" +#include "TrainLogFileMgr.h" +#include +#include "ZTLog.h" + + +CLogsListPage::~CLogsListPage() +{ +// delete mListParsingTimer; + delete mLogArchiverThread; + delete mLogArchiverWorkerThread; +} + +CLogsListPage::CLogsListPage(QGraphicsWidget *Parent) +{ + setParentItem(Parent); + mProgramHandle = 0; + mUSBDetected = false; + mShowZT1Items = mShowZT2Items = mShowNoDetections = true; + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QBrush BackgroundBrush(QColor(245, 245, 255)); + mBackgroundRect->setBrush(BackgroundBrush); + + mCancelButton = new CTextButtonWidget("Fermer"); + mCancelButton->setParentItem(this); + mCancelButton->setPos(810,550); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mLogsTable = new QTableWidget(0,3); + QGraphicsProxyWidget *TableProxy = new QGraphicsProxyWidget(this); + TableProxy->setWidget(mLogsTable); + TableProxy->setPos(3,20); + TableProxy->resize(300,550); + mLogsTable->resize(300,550); + mLogsTable->setSelectionBehavior(QAbstractItemView::SelectRows); + mLogsTable->setSelectionMode(QAbstractItemView::SingleSelection); + mLogsTable->setHorizontalHeaderLabels(QStringList() << "Date du passage" << "Décl." << "Type"); +// connect(mLogsTable,SIGNAL(cellClicked(int,int)),this,SLOT(LogsTableCellClicked(int,int))); + connect(mLogsTable,SIGNAL(cellDoubleClicked(int,int)),SLOT(TableDoubleClicked(int,int))); + //connect(mLogsTable,SIGNAL(currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)),this,SLOT(TableCurItemChanged(QTableWidgetItem*,QTableWidgetItem*))); + connect(mLogsTable,SIGNAL(itemSelectionChanged()),this,SLOT(LogsTableCellSelected(/*int,int*/))); + + + mSummaryText = new QGraphicsTextItem(this); + QFont textfont; + textfont.setPointSize(12); + mSummaryText->setFont(textfont); + mSummaryText->setPlainText("Statistiques du passage:"); + mSummaryText->setPos(350,20); + + QGraphicsProxyWidget *CheckBoxProxy = new QGraphicsProxyWidget(this); + mShowZT1ItemsChkBx = new QCheckBox("Masquer ZT1"); + CheckBoxProxy->setWidget(mShowZT1ItemsChkBx); + CheckBoxProxy->setPos(320,550); + mShowZT1ItemsChkBx->setChecked(false); + connect(mShowZT1ItemsChkBx,SIGNAL(stateChanged(int)),this,SLOT(CheckBoxClicked(int))); + + CheckBoxProxy = new QGraphicsProxyWidget(this); + mShowZT2ItemsChkBx = new QCheckBox("Masquer ZT2"); + CheckBoxProxy->setWidget(mShowZT2ItemsChkBx); + //CheckBoxProxy->setPos(410,550); + CheckBoxProxy->setPos(320,570); + mShowZT2ItemsChkBx->setChecked(false); + connect(mShowZT2ItemsChkBx,SIGNAL(stateChanged(int)),this,SLOT(CheckBoxClicked(int))); + + CheckBoxProxy = new QGraphicsProxyWidget(this); + mShowNoDetectionsChkBx = new QCheckBox("Seulement\ndéclenchements"); + CheckBoxProxy->setWidget(mShowNoDetectionsChkBx); + CheckBoxProxy->setPos(450,550); + mShowNoDetectionsChkBx->setChecked(false); + connect(mShowNoDetectionsChkBx,SIGNAL(stateChanged(int)),this,SLOT(CheckBoxClicked(int))); + + mListParsingTimer = new QTimer(); + connect(mListParsingTimer,SIGNAL(timeout()),this,SLOT(ParsingTimerExipred())); + + mUSBRefreshTimer = new QTimer(); + mUSBRefreshTimer->setSingleShot(false); + connect(mUSBRefreshTimer,SIGNAL(timeout()),this,SLOT(CheckUSBKey())); + + QGraphicsRectItem *Frame = new QGraphicsRectItem(650,50,200,80,this); + QPen FramePen; + FramePen.setWidth(3); + Frame->setPen(FramePen); + + QGraphicsTextItem *Label = new QGraphicsTextItem(this); + Label->setPlainText("Sélection"); + Label->setPos(650,25); + Label->setFont(textfont); + + mViewLogDataButton = new CTextButtonWidget("Voir"); + mViewLogDataButton->setParentItem(this); + mViewLogDataButton->setPos(730,60); + connect(mViewLogDataButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mExportCSVLogButton = new CTextButtonWidget("Générer CSV"); + mExportCSVLogButton->setParentItem(this); + mExportCSVLogButton->setPos(700,95); + connect(mExportCSVLogButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + mExportCSVLogButton->hide(); + + Label = new QGraphicsTextItem(this); + Label->setPlainText("Sauvegarde des passages"); + Label->setPos(650,150); + Label->setFont(textfont); + + Frame = new QGraphicsRectItem(650,175,200,80,this); + Frame->setPen(FramePen); + + mArchiveFilesButton = new CTextButtonWidget("Archiver tout"); + mArchiveFilesButton->setParentItem(this); + mArchiveFilesButton->setPos(700,185); + connect(mArchiveFilesButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + mArchiveFilesButton->hide(); + + mEraseFilesCheckbox = new QCheckBox("Conserver les passages"); + CheckBoxProxy = new QGraphicsProxyWidget(this); + CheckBoxProxy->setWidget(mEraseFilesCheckbox); + CheckBoxProxy->setPos(660,220); + mEraseFilesCheckbox->hide(); + + + mInsertUSBKeyText = new QGraphicsTextItem("Veuillez insérer\nune clef USB",this); + mInsertUSBKeyText->setPos(675,190); + mInsertUSBKeyText->setFont(textfont); + + mLogArchiverWorkerThread = new CLogFileArchiverThread(); + mLogArchiverThread = new QThread(); + mLogArchiverWorkerThread->moveToThread(mLogArchiverThread); + connect(mLogArchiverThread,SIGNAL(started()),mLogArchiverWorkerThread,SLOT(ArchiveLogs())); + connect(mLogArchiverWorkerThread,SIGNAL(LogArchivingFinished()),this,SLOT(LogsArchivingFinished())); + +} + +unsigned int CLogsListPage::ArchiveAllFiles() +{ +// QString PathName = mUSBDrivePtr->GetDrivePath(); +// PathName += "/ArchiveLogZT_"; +// PathName += mProgramHandle->GetStationShortName(); +// PathName += QDateTime::currentDateTime().toString("_yyyyMMdd"); +// QDir TargetDir(PathName); + +// TargetDir.mkdir(PathName); //If the directory does not exist, it will be created. + +// //copy files +// QStringList LogFilters; +// LogFilters << "*.bin" << "*.csv"; +// QDir LogDir("./Trains/"); + +// int NbFiles = 0; +// LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); +// LogDir.setNameFilters(LogFilters); +// LogDir.setSorting(QDir::Name); +// for(int i = 0; i < LogDir.entryInfoList().size(); i++) +// { +// QString DestFileName = PathName; +// DestFileName += "/"; +// DestFileName += LogDir.entryInfoList().at(i).fileName(); +// if(QFile::copy(LogDir.entryInfoList().at(i).absoluteFilePath(),DestFileName)) +// { +// NbFiles++; +// } +// } + +// //Copy the ZTLog file each time. +// QString DestFileName = PathName; +// DestFileName += "/ZTLog.txt"; +// CZTLog::instance()->CopyLogFile(DestFileName,true); + +// system("sync"); + +// CZTLog::instance()->AddLogString(QString().sprintf("%d fichiers de passage archivés dans le répertoire %s",NbFiles,PathName.toUtf8().data()),true); + +// if(mEraseFilesCheckbox->checkState() == Qt::Checked) +// { +// DeleteAllFiles(); +// system("sync"); +// mEraseFilesCheckbox->setChecked(false); +// } + + + mArchiveFilesButton->hide(); + mInsertUSBKeyText->setPlainText("Copie en cours\nN'enlevez pas la clef"); + mInsertUSBKeyText->show(); + mEraseFilesCheckbox->hide(); + + mLogArchiverWorkerThread->SetPathInfo(mUSBDrivePtr->GetDrivePath(),mProgramHandle->GetStationShortName()); + + QString PathName = mUSBDrivePtr->GetDrivePath(); + PathName += "/ArchiveLogZT_"; + PathName += mProgramHandle->GetStationShortName(); + PathName += QDateTime::currentDateTime().toString("_yyyyMMdd"); + QDir TargetDir(PathName); + + TargetDir.mkdir(PathName); //If the directory does not exist, it will be created. + + QString DestFileName = PathName; + DestFileName += "/ZTLog.txt"; + CZTLog::instance()->CopyLogFile(DestFileName,true); + + mLogArchiverThread->start(); + + + + return RET_OK; +} + +unsigned int CLogsListPage::DeleteAllFiles() +{ + QStringList LogFilters; + LogFilters << "*.bin" << "*.csv"; + QDir LogDir("./Trains/"); + + LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + LogDir.setNameFilters(LogFilters); + LogDir.setSorting(QDir::Name); + + for(int i = 0; i < LogDir.entryInfoList().size(); i++) + { + QFile::remove(LogDir.entryInfoList().at(i).absoluteFilePath()); + } + + CZTLog::instance()->AddLogString("Tous les fichiers de passages ont été effacés",true); + + mLogMgrHandle->ParseLogs(); + RefreshList(); + + return RET_OK; +} + +void CLogsListPage::NewTrainLogFileSaved() +{ + RefreshList(true); +} + +void CLogsListPage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + mBackgroundRect->setRect(boundingRect()); +} + +void CLogsListPage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mCancelButton) + { + mSummaryText->setPlainText("Statistiques du passage:"); + hide(); + } + else if(BtnPtr == mViewLogDataButton) + { + if(mLogMgrHandle->GetLogsCount() == 0) + return; + + //int cursel = mLogsTable->currentItem()->data(Qt::UserRole).toInt(); + int cursel = GetCurSelectedItemIndexInTable(); + if(cursel == -1) + return; + + CLogElement* Element = mLogMgrHandle->GetLogsList()->at(cursel); + //qDebug("Sel: %d, Type : %d",cursel,Element->mZTLogType); + mProgramHandle->LogViewRequest(mLogMgrHandle->LoadLogData(Element)); + mLogMgrHandle->FreeLogData(Element); + + + } + else if(BtnPtr == mExportCSVLogButton) + { + if(mLogMgrHandle->GetLogsCount() == 0) + return; + + QString Filename; + //int cursel = mLogsTable->currentItem()->data(Qt::UserRole).toInt(); + int cursel = GetCurSelectedItemIndexInTable(); + if(cursel == -1) + return; + + CLogElement* Element = mLogMgrHandle->GetLogsList()->at(cursel); + mLogMgrHandle->LoadLogData(Element); + if(Element->mZTLogType == ZT1_LOG_TYPE) + { + CZT1LogElement *temp = (CZT1LogElement*)Element; + Filename = temp->mLogFileName.replace("bin","csv"); + CTrainLogFileMgr::instance()->SaveCSVFile(Filename,&temp->mZTLogData,&temp->mFlags,&temp->mZTDetections,temp->mStationName); + } + else + { + CZT2LogElement *temp = (CZT2LogElement*)Element; + Filename = temp->mLogFileName.replace("bin","csv"); + CTrainLogFileMgr::instance()->SaveCSVFile(Filename,&temp->mZTLogData,&temp->mZTDetections,temp->mStationName); + } + mLogMgrHandle->FreeLogData(Element); + } + else if(BtnPtr == mArchiveFilesButton) + { + ArchiveAllFiles(); + } +} + +unsigned int CLogsListPage::BindPointers(CUSBDriveInterface *USBDriveIF) +{ + mUSBDrivePtr = USBDriveIF; + mUSBRefreshTimer->start(1000); + mLogArchiverWorkerThread->mLogMgrHandle = mLogMgrHandle; + return RET_OK; +} + +unsigned int CLogsListPage::RefreshList(bool KeepSelectedCell) +{ + + QString SelectedCellText; + if(KeepSelectedCell == true) + { + + QList list = mLogsTable->selectedItems(); + + if(list.size() == 0) + { + KeepSelectedCell = false; + } + + for(int i = 0; i < list.size(); i++) + { + if(list.at(i)->column() == 0) + { + SelectedCellText = list.at(i)->text(); + qDebug("Selected cell text: %s",SelectedCellText.toAscii().data()); + break; + } + } + + } + + ClearTable(); + + mShowZT1Items = (mShowZT1ItemsChkBx->checkState() == Qt::Unchecked); + mShowZT2Items = (mShowZT2ItemsChkBx->checkState() == Qt::Unchecked); + mShowNoDetections = (mShowNoDetectionsChkBx->checkState() == Qt::Unchecked); + + mLogsTable->setRowCount(mLogMgrHandle->GetLogsCount()); + + if(mLogMgrHandle->GetLogsCount() == 0) + return RET_OK; + + int CurRow = 0; + + QList *LogsList = mLogMgrHandle->GetLogsList(); + for(unsigned int i = 0; i < mLogMgrHandle->GetLogsCount(); i++) + { + if(LogsList->at(i)->mZTLogType == ZT1_LOG_TYPE && mShowZT1Items == true) + { + CZT1LogElement *ZT1LogElement = (CZT1LogElement*)LogsList->at(i); + + int NbDetections = ZT1LogElement->mZTDetections.size(); + if(mShowNoDetections == false && NbDetections == 0) + { + } + else + { + QTableWidgetItem * NewItem = new QTableWidgetItem(ZT1LogElement->mPassageDateTime.toString("yyyy/MM/dd - hh:mm:ss")); + QVariant ID(QVariant::Int); + ID.setValue(i); + NewItem->setData(Qt::UserRole,ID); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,0,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("%d",NbDetections)); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,1,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("ZT1")); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,2,NewItem); + + CurRow++; + } + + + + } + else if(LogsList->at(i)->mZTLogType == ZT2_LOG_TYPE && mShowZT2Items == true) + { + CZT2LogElement *ZT2LogElement = (CZT2LogElement*)LogsList->at(i); + + int NbDetections = ZT2LogElement->mZTDetections.size(); + if(mShowNoDetections == false && NbDetections == 0) + { + } + else + { + QTableWidgetItem * NewItem = new QTableWidgetItem(ZT2LogElement->mPassageDateTime.toString("yyyy/MM/dd - hh:mm:ss")); + QVariant ID(QVariant::Int); + ID.setValue(i); + NewItem->setData(Qt::UserRole,ID); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,0,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("%d",ZT2LogElement->mZTDetections.size())); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,1,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("ZT2")); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,2,NewItem); + + CurRow++; + } + } + } + + mLogsTable->setRowCount(CurRow); + + mLogsTable->setColumnWidth(0,150); + mLogsTable->setColumnWidth(1,50); + mLogsTable->setColumnWidth(2,50); + + mLogsTable->sortItems(0,Qt::DescendingOrder); + + if(KeepSelectedCell == true) + { + QList Items = mLogsTable->findItems(SelectedCellText,Qt::MatchFixedString); + if(Items.size() != 0) + { + mLogsTable->setCurrentCell(Items.at(0)->row(),0); + qDebug("Found cell text: %s",Items.at(0)->text().toAscii().data()); + } + else + { + mLogsTable->setCurrentCell(0,0); + } + + } + else + { + mLogsTable->setCurrentCell(0,0); + } +// LogsTableCellClicked(0,0); + + + return RET_OK; + +} + +void CLogsListPage::ClearTable() +{ + for(int Col = 0; Col < mLogsTable->columnCount(); Col++) + { + for(int Row = 0; Row < mLogsTable->rowCount(); Row++) + { + delete mLogsTable->item(Row,Col); + } + } + mLogsTable->clearContents(); + mLogsTable->setRowCount(0); +} + +//void CLogsListPage::LogsTableCellClicked(int row, int column) +//{ +// return; +// Q_UNUSED(column); +// Q_UNUSED(row); + +//// int rowcount = mLogsTable->rowCount(); +//// if(rowcount == 0) +//// return; + +////// qDebug("Selection : %d",row); +//// QList *LogsList = mLogMgrHandle->GetLogsList(); + +//// float MeanSpeed = 0.0; +//// QString Summary; +//// int ItemIndex = mLogsTable->item(row,0)->data(Qt::UserRole).toInt(); +//// ShowItemSummary(LogsList->at(ItemIndex)); +//} + +void CLogsListPage::ShowItemSummary(CLogElement *Element) +{ + float MeanSpeed; + QString Summary; + if(Element->mZTLogType == ZT1_LOG_TYPE) + { +// //CZT1LogElement *ZT1LogElement = (CZT1LogElement*) LogsList->at(row); + CZT1LogElement *ZT1LogElement = (CZT1LogElement*) Element; + + MeanSpeed = ZT1LogElement->mMeanSpeed; + QString Problem = "Non"; + if(ZT1LogElement->mFlags.mIsProblematicPassage == 1) + { + Problem = "Oui"; + } + + + Summary.sprintf("Statistiques du passage:\n\nDate: %s\nHeure: %s\nTrain : %s\nNombre d'éléments: %d\nVitesse moyenne : %f mph\nPassage problématique: %s\n\nDéclenchements: \n", + ZT1LogElement->mPassageDateTime.toString("yyyy/MM/dd").toAscii().data(), + ZT1LogElement->mPassageDateTime.toString("hh:mm:ss").toAscii().data(), + CZTData::GetTrainTypeString(ZT1LogElement->mTrainType), + ZT1LogElement->mNbElements, + MeanSpeed, + Problem.toUtf8().data()); + + if(ZT1LogElement->mZTDetections.size() > 0) + { + for(int i = 0; i < ZT1LogElement->mZTDetections.size(); i++) + { + QString temp; + if(ZT1LogElement->mZTDetections.at(i)->mDetectionID == DETECTION_FN_DETECTION) + { + temp.sprintf("%s au bogie %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); + } + else + { + temp.sprintf("%s au rang %d\n",CZTData::GetErrorString(ZT1LogElement->mZTDetections.at(i)->mDetectionID),ZT1LogElement->mZTDetections.at(i)->mRank); + } + Summary += temp; + if(i >= MAX_DETECTION_LIST_NBR - 1) + { + temp = " -- Autres déclenchements non affichés --"; + Summary += temp; + break; + } + } + } + else + Summary += "Aucun déclenchement"; + } + //else if(LogsList->at(row)->mZTLogType == ZT2_LOG_TYPE) + else if(Element->mZTLogType == ZT2_LOG_TYPE) + { + //CZT2LogElement *ZT2LogElement = (CZT2LogElement*) LogsList->at(row); + CZT2LogElement *ZT2LogElement = (CZT2LogElement*) Element; + QString Problem = "Non"; + if(ZT2LogElement->mFlags.mIsProblematicPassage == 1) + { + Problem = "Oui"; + } + + Summary.sprintf("Statistiques du passage:\n\nDate: %s\nHeure: %s\nNombre d'éléments: %d\nPassage problématique: %s\n\n\n\nDéclenchements: \n", + ZT2LogElement->mPassageDateTime.toString("yyyy/MM/dd").toAscii().data(), + ZT2LogElement->mPassageDateTime.toString("hh:mm:ss").toAscii().data(), + ZT2LogElement->mNbElements, + Problem.toUtf8().data()); + + if(ZT2LogElement->mZTDetections.size() > 0) + { + for(int i = 0; i < ZT2LogElement->mZTDetections.size(); i++) + { + QString temp; + temp.sprintf("%s au rang %d\n",CZTData::GetErrorString(ZT2LogElement->mZTDetections.at(i)->mDetectionID),ZT2LogElement->mZTDetections.at(i)->mRank); + Summary += temp; + if(i >= MAX_DETECTION_LIST_NBR-1) + { + temp = " -- Autres déclenchements non affichés --"; + Summary += temp; + break; + } + } + } + else + Summary += "Aucun déclenchement"; + + } + mSummaryText->setPlainText(Summary); +} + +void CLogsListPage::ParsingTimerExipred() +{ + if(mLogMgrHandle->ParseNextLog() == false) + { + mListParsingTimer->stop(); + } + else + { + int CurRow = mLogsTable->rowCount(); + mLogsTable->setRowCount(CurRow+1); + + QList *LogsList = mLogMgrHandle->GetLogsList(); + //for(unsigned int i = 0; i < mLogMgrHandle->GetLogsCount(); i++) + { + if(LogsList->last()->mZTLogType == ZT1_LOG_TYPE && mShowZT1Items == true) + { + CZT1LogElement *ZT1LogElement = (CZT1LogElement*)LogsList->last(); + + int NbDetections = ZT1LogElement->mZTDetections.size(); + if(mShowNoDetections == false && NbDetections == 0) + { + } + else + { + QTableWidgetItem * NewItem = new QTableWidgetItem(ZT1LogElement->mPassageDateTime.toString("yyyy/MM/dd - hh:mm:ss")); + NewItem->setData(Qt::UserRole,QVariant(LogsList->size()-1)); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,0,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("%d",NbDetections)); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,1,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("ZT1")); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,2,NewItem); + } + } + else if(LogsList->last()->mZTLogType == ZT2_LOG_TYPE && mShowZT2Items == true) + { + CZT2LogElement *ZT2LogElement = (CZT2LogElement*)LogsList->last(); + + int NbDetections = ZT2LogElement->mZTDetections.size(); + if(mShowNoDetections == false && NbDetections == 0) + { + } + else + { + QTableWidgetItem * NewItem = new QTableWidgetItem(ZT2LogElement->mPassageDateTime.toString("yyyy/MM/dd - hh:mm:ss")); + NewItem->setData(Qt::UserRole,QVariant(LogsList->size()-1)); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,0,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("%d",ZT2LogElement->mZTDetections.size())); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,1,NewItem); + + NewItem = new QTableWidgetItem(QString().sprintf("ZT2")); + NewItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + mLogsTable->setItem(CurRow,2,NewItem); + } + } + } + +// mLogsTable->setRowCount(CurRow+1); + + mLogsTable->setColumnWidth(0,150); + mLogsTable->setColumnWidth(1,50); + mLogsTable->setColumnWidth(2,50); + + + mLogsTable->sortItems(0); + + mListParsingTimer->start(20); + +// mLogsTable->setCurrentCell(0,0); +// LogsTableCellClicked(0,0); + } +} + +void CLogsListPage::CheckUSBKey() +{ + if(mUSBDrivePtr->IsDriveDetected() != mUSBDetected) + { + mUSBDetected = mUSBDrivePtr->IsDriveDetected(); + + if(mUSBDetected == true) + { + mInsertUSBKeyText->hide(); + mArchiveFilesButton->show(); + mEraseFilesCheckbox->setCheckState(Qt::Unchecked); + mEraseFilesCheckbox->show(); + } + else + { + mInsertUSBKeyText->setPlainText("Veuillez insérer\nune clef USB"); + mInsertUSBKeyText->show(); + mArchiveFilesButton->hide(); + mEraseFilesCheckbox->hide(); + } + } + +} + +//Grab the mouse if the user clicks outside buttons +void CLogsListPage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void CLogsListPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void CLogsListPage::CheckBoxClicked(int state) +{ + Q_UNUSED(state) + RefreshList(); +} + +void CLogsListPage::TableDoubleClicked(int row, int col) +{ + Q_UNUSED(col) + Q_UNUSED(row) + ButtonClicked(mViewLogDataButton); +} +//void CLogsListPage::TableCurItemChanged(QTableWidgetItem *Current, QTableWidgetItem *Prev) +//{ +// int rowcount = mLogsTable->rowCount(); +// if(rowcount == 0) +// return; + +// if(Prev == Current) +// return; + +// QList *LogsList = mLogMgrHandle->GetLogsList(); +// int Selection = Current->data(Qt::UserRole).toInt(); +// CLogElement *SelectedElement = LogsList->at(Selection); +// ShowItemSummary(SelectedElement); +//// qDebug("Changed %d",Selection); + +//} + +void CLogsListPage::LogsTableCellSelected(/*int row, int col*/) +{ + int Selection = GetCurSelectedItemIndexInTable(); + + if(Selection == -1) + return; + + QList *LogsList = mLogMgrHandle->GetLogsList(); + CLogElement *SelectedElement = LogsList->at(Selection); + ShowItemSummary(SelectedElement); +} + +int CLogsListPage::GetCurSelectedItemIndexInTable() +{ + QList list = mLogsTable->selectedItems(); + + if(list.size() == 0) + return - 1; + + int Selection = -1; + for(int i = 0; i < list.size(); i++) + { + if(list.at(i)->column() == 0) + { + Selection = list.at(i)->data(Qt::UserRole).toInt(); + break; + } + } + + return Selection; +} + +void CLogsListPage::LogsArchivingFinished() +{ + +// CZTLog::instance()->DeleteLogFile(); + + if(mEraseFilesCheckbox->checkState() == Qt::Unchecked) + { + mLogMgrHandle->DeleteErrorLogs(); + } + + //The "sync" command has been moved in the thread instead of pausing the watchdog... + +// The file syncing can take a lot of time (the "sync" command syncs ALL of the file system). +// So we must disable the watchdog to avoid a computer reboot. +// mProgramHandle->PauseInternalWatchdog(); +// system("sync"); +// mProgramHandle->ResumeInternalWatchdog(); + + + RefreshList(); + mLogArchiverThread->quit(); + if(mEraseFilesCheckbox->checkState() == Qt::Unchecked) + { + mProgramHandle->ResetTriggerCount(); + mProgramHandle->ResetNbPassages(); + } + mInsertUSBKeyText->hide(); + mArchiveFilesButton->show(); + mEraseFilesCheckbox->show(); + CZTLog::instance()->DeleteLogFile(); +} + + + + +////// Thread implementation ////////////// + +CLogFileArchiverThread::CLogFileArchiverThread() +{ + mDrivePath = ""; +} + +void CLogFileArchiverThread::SetPathInfo(QString DrivePath,QString StationName) +{ + mDrivePath = DrivePath; + mStationName = StationName; +} + +void CLogFileArchiverThread::ArchiveLogs() +{ + + QString PathName = mDrivePath; + PathName += "/ArchiveLogZT_"; + PathName += mStationName; + PathName += QDateTime::currentDateTime().toString("_yyyyMMdd"); + QDir TargetDir(PathName); + + TargetDir.mkdir(PathName); //If the directory does not exist, it will be created. + + //copy files + QStringList LogFilters; + LogFilters << "*.bin" << "*.csv"; + QDir LogDir("./Trains/"); + + int NbFiles = 0; + LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + LogDir.setNameFilters(LogFilters); + LogDir.setSorting(QDir::Name); + for(int i = 0; i < LogDir.entryInfoList().size(); i++) + { + QString DestFileName = PathName; + DestFileName += "/"; + DestFileName += LogDir.entryInfoList().at(i).fileName(); + if(QFile::copy(LogDir.entryInfoList().at(i).absoluteFilePath(),DestFileName)) + { + NbFiles++; + } + } + + ///JFM: Is it dangerous to access these from the thread ? +// CZTLog::instance()->DeleteLogFile(); +// mLogMgrHandle->DeleteErrorLogs(); + /// Moved outside of threads + + system("sync"); + + CZTLog::instance()->AddLogString(QString().sprintf("%d fichiers de passage archivés dans le répertoire %s",NbFiles,PathName.toUtf8().data()),true); + + emit LogArchivingFinished(); +} diff --git a/sources/GuiElements/LogsListPage.h b/sources/GuiElements/LogsListPage.h new file mode 100644 index 0000000..75d9faa --- /dev/null +++ b/sources/GuiElements/LogsListPage.h @@ -0,0 +1,134 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131024 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef LOGSLISTPAGE_H +#define LOGSLISTPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "TextButtonWidget.h" +#include "LogMgr.h" +#include +#include +#include "USBDriveInterface.h" +#include + +#define MAX_DETECTION_LIST_NBR 7 + +class CZoneTest; + + +class CLogFileArchiverThread : public QObject +{ + Q_OBJECT +public: + CLogFileArchiverThread(); + void SetPathInfo(QString DrivePath,QString StationName); + + CLogMgr *mLogMgrHandle; + +public slots: + void ArchiveLogs(); + +private: + + QString mDrivePath; + QString mStationName; + + +signals: + void LogArchivingFinished(); + +}; + + +class CLogsListPage : public CGuiPage +{ +Q_OBJECT +public: + virtual ~CLogsListPage(); + CLogsListPage(QGraphicsWidget *Parent = 0); + + + CZoneTest *mProgramHandle; + CLogMgr *mLogMgrHandle; + + unsigned int RefreshList(bool KeepSelectedCell = false); + unsigned int BindPointers(CUSBDriveInterface *USBDriveIF); + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + +private: + + QGraphicsRectItem *mBackgroundRect; + CTextButtonWidget *mCancelButton; + QTableWidget *mLogsTable; + QGraphicsTextItem *mSummaryText; + CTextButtonWidget *mViewLogDataButton; + CTextButtonWidget *mExportCSVLogButton; + CTextButtonWidget *mArchiveFilesButton; + QGraphicsTextItem *mInsertUSBKeyText; + QCheckBox *mShowZT1ItemsChkBx, *mShowZT2ItemsChkBx, *mShowNoDetectionsChkBx, *mRemoveErrorLogsChkBx; + QTimer *mListParsingTimer; + CUSBDriveInterface *mUSBDrivePtr; + QTimer *mUSBRefreshTimer; + QCheckBox *mEraseFilesCheckbox; + + CLogFileArchiverThread *mLogArchiverWorkerThread; + QThread *mLogArchiverThread; + + bool mShowZT1Items,mShowZT2Items,mShowNoDetections,mUSBDetected; + + void ClearTable(); + unsigned int ArchiveAllFiles(); + unsigned int DeleteAllFiles(); + void ShowItemSummary(CLogElement*); + int GetCurSelectedItemIndexInTable(void); + + +public slots: + void ButtonClicked(CTextButtonWidget *); +// void LogsTableCellClicked(int, int); + void CheckBoxClicked(int); + void TableDoubleClicked(int,int); + void ParsingTimerExipred(); + void CheckUSBKey(); + void LogsArchivingFinished(); +// void TableCurItemChanged(QTableWidgetItem*,QTableWidgetItem*); + void LogsTableCellSelected(/*int, int*/); + void NewTrainLogFileSaved(); + +}; + + +#endif // LOGSLISTPAGE_H diff --git a/sources/GuiElements/MaintenancePage.cpp b/sources/GuiElements/MaintenancePage.cpp new file mode 100644 index 0000000..af24537 --- /dev/null +++ b/sources/GuiElements/MaintenancePage.cpp @@ -0,0 +1,457 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page offrant différentes option pour l'entretien de la ZT + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "MaintenancePage.h" +#include +#include "GlobalDefine.h" +#include +#include +#include "Zonetest.h" +#include +#include +#include +#include "ZTData.h" +#include +#include "ZTLog.h" +#include "ZTData.h" + + +CMaintenancePage::CMaintenancePage(QGraphicsWidget *Parent) +{ + Q_UNUSED(Parent) + + + mProgramHandle = 0; + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QBrush BackgroundBrush(QColor(245, 245, 255)); + mBackgroundRect->setBrush(BackgroundBrush); + + QGraphicsTextItem *Title = new QGraphicsTextItem("Entretien de la Zone Tests",this); + QFont font; + font.setPointSize(18); + Title->setFont(font); + Title->setPos(40,10); + + + mMaintenanceActivationBtn = new CToggleButtonWidget("./Images/Slider_Green.png","./Images/Slider_Red.png",this); + mMaintenanceActivationBtn->setPos(45,65); + mMaintenanceActivationBtn->resize(50,30); + connect(mMaintenanceActivationBtn,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(ActivationBtnToggled(CToggleButtonWidget*))); + + mWatchdogEnableBtn = new CToggleButtonWidget("./Images/Slider_Green.png","./Images/Slider_Red.png",this); + mWatchdogEnableBtn->setPos(700,350); + mWatchdogEnableBtn->resize(50,30); + connect(mWatchdogEnableBtn,SIGNAL(ButtonToggled(CToggleButtonWidget*)),this,SLOT(WatchdogEnableBtnToggled(CToggleButtonWidget*))); + + + Title = new QGraphicsTextItem("Activer mode entretien",this); + font.setPointSize(16); + Title->setFont(font); + Title->setPos(100,60); + + mCancelButton = new CTextButtonWidget("Fermer"); + mCancelButton->setParentItem(this); + mCancelButton->setPos(700,550); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mGenerateAlarmBtn = new CTextButtonWidget("Envoyer Alarme",0,30); + mGenerateAlarmBtn->setParentItem(this); + mGenerateAlarmBtn->setPos(540,170); + connect(mGenerateAlarmBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mClearAlarmButton = new CTextButtonWidget("Acquitter Alarme",0,30); + mClearAlarmButton->setParentItem(this); + mClearAlarmButton->setPos(540,210); + mClearAlarmButton->hide(); + connect(mClearAlarmButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + QGraphicsProxyWidget *Proxy = new QGraphicsProxyWidget(this); + mAlarmTypeList = new QComboBox(); + Proxy->setWidget(mAlarmTypeList); + Proxy->setPos(100,200); + QStringList AlarmTypes; + AlarmTypes << "Erreur de comptage ZT1" + << "Détection Frotteur Négatif" + << "Détection Pneu de Guidage" + << "Détection Pneu Porteur Intérieur ZT1" + << "Détection Pneu Porteur Extérieur ZT1" + << "Erreur de comptage ZT2" + << "Détection Pneu Porteur Intérieur ZT2" + << "Détection Pneu Porteur Extérieur ZT2" + << "Panne Équipement ZT1" + << "Panne Équipement ZT2"; + + mAlarmTypeList->addItems(AlarmTypes); + mAlarmTypeList->resize(300,30); + connect(mAlarmTypeList,SIGNAL(currentIndexChanged(int)),this,SLOT(AlarmTypeSelectionChanged(int))); + Proxy->setZValue(2); + mAlarmDescription = new QGraphicsTextItem(this); + mAlarmDescription->setPos(100,170); + mAlarmDescription->setPlainText("Type d'alarme"); + + + Proxy = new QGraphicsProxyWidget(this); + mAlarmRankSpinBox = new QSpinBox(); + Proxy->setWidget(mAlarmRankSpinBox); + Proxy->setPos(420,200); + mAlarmRankSpinBox->resize(100,30); + mRankDescription = new QGraphicsTextItem(this); + mRankDescription->setPos(420,170); + mRankDescription->setPlainText("Rang"); + + QPen FramePen; + FramePen.setWidth(3); + + + mAlarmsFrame = new QGraphicsRectItem(80,120,650,130,this); + mAlarmsFrame->setPen(FramePen); + + mFctDescription = new QGraphicsTextItem(this); + mFctDescription->setPos(200,120); + mFctDescription->setPlainText("Génération d'alarmes au PCC"); + font.setPointSize(18); + mFctDescription->setFont(font); + + mWatchdogDisableDescription = new QGraphicsTextItem(this); + mWatchdogDisableDescription->setPos(694,310); + mWatchdogDisableDescription->setFont(font); + mWatchdogDisableDescription->setPlainText("Vigie"); + + int yoffset = 30; + + mPPFrame = new QGraphicsRectItem(80,250+yoffset,550,280,this); + mPPFrame->setPen(FramePen); + + mPPTitle = new QGraphicsTextItem("Activation des pédales pneu porteur",this); + mPPTitle->setFont(font); + mPPTitle->setPos(150,250+yoffset); + + + + + font.setPointSize(14); + mPPIZT1Description = new QGraphicsTextItem("Pédale intérieure ZT1",this); + mPPIZT1Description->setFont(font); + mPPIZT1Description->setPos(100,300+15+yoffset); + mZT1PPIStatus = new CONOFFStatusWidget(""); + mZT1PPIStatus->setParentItem(this); + mZT1PPIStatus->setPos(320,300+yoffset); + + mPPEZT1Description = new QGraphicsTextItem("Pédale extérieure ZT1",this); + mPPEZT1Description->setFont(font); + mPPEZT1Description->setPos(100,350+15+yoffset); + mZT1PPEStatus = new CONOFFStatusWidget(""); + mZT1PPEStatus->setParentItem(this); + mZT1PPEStatus->setPos(320,350+yoffset); + + mPPIZT2Description = new QGraphicsTextItem("Pédale intérieure ZT2",this); + mPPIZT2Description->setFont(font); + mPPIZT2Description->setPos(100,400+15+yoffset); + mZT2PPIStatus = new CONOFFStatusWidget(""); + mZT2PPIStatus->setParentItem(this); + mZT2PPIStatus->setPos(320,400+yoffset); + + mPPEZT2Description = new QGraphicsTextItem("Pédale extérieure ZT2",this); + mPPEZT2Description->setFont(font); + mPPEZT2Description->setPos(100,450+15+yoffset); + mZT2PPEStatus = new CONOFFStatusWidget(""); + mZT2PPEStatus->setParentItem(this); + mZT2PPEStatus->setPos(320,450+yoffset); + + mMaintenanceModeAutoExitTimer = new QTimer(); + mMaintenanceModeAutoExitTimer->setSingleShot(true); + connect(mMaintenanceModeAutoExitTimer,SIGNAL(timeout()),this,SLOT(AutoExit())); + + mAlarmRankSpinBox->setValue(1); + mAlarmRankSpinBox->setMinimum(1); + mAlarmRankSpinBox->setMaximum(1); + mRankDescription->setPlainText("N/A"); + + HideMaintenanceItems(); +} + +void CMaintenancePage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + + + mBackgroundRect->setRect(boundingRect()); +} + +void CMaintenancePage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mCancelButton) + { + hide(); + } + else if(BtnPtr == mGenerateAlarmBtn) + { + GenerateTK(); + } + else if(BtnPtr == mClearAlarmButton) + { + if(mProgramHandle->ClearMaintenanceCurTKRequest() == RET_OK) + { + CZTLog::instance()->AddLogString("[Mode entretien] Acquitement MANUEL d'une TK au PCC.",true); + } + else + { + mClearAlarmButton->hide(); + } + + + } + +} + +void CMaintenancePage::AlarmTypeSelectionChanged(int index) +{ + switch(index) + { + + case DETECTION_PG_DETECTION: + case DETECTION_PPI_DETECTION: + case DETECTION_PPE_DETECTION: + case DETECTION_ZT2_PPI_DETECTION: + case DETECTION_ZT2_PPE_DETECTION: + { + mAlarmRankSpinBox->setValue(1); + mAlarmRankSpinBox->setMinimum(1); + mAlarmRankSpinBox->setMaximum(36); + mRankDescription->setPlainText("Rang"); + break; + } + case DETECTION_FN_DETECTION: + { + mAlarmRankSpinBox->setValue(1); + mAlarmRankSpinBox->setMinimum(1); + mAlarmRankSpinBox->setMaximum(18); + mRankDescription->setPlainText("Bogie"); + break; + } + case DETECTION_MAGNETIC_SENSOR_COUNT: + case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT: + case DETECTION_PEQ1_DETECTION: + case DETECTION_PEQ2_DETECTION: + { + mAlarmRankSpinBox->setValue(1); + mAlarmRankSpinBox->setMinimum(1); + mAlarmRankSpinBox->setMaximum(1); + mRankDescription->setPlainText("N/A"); + break; + } + } +} + +void CMaintenancePage::ActivationBtnToggled(CToggleButtonWidget *Btn) +{ + + if(Btn->GetButtonState() == TOGGLE_BUTTON_ON) + { + if(mProgramHandle->EnterMaintenanceModeRequest() == true) + { + ShowMaintenanceItems(); + mMaintenanceModeAutoExitTimer->start(MAINTENANCE_AUTO_EXIT_TIMEOUT); + CZTLog::instance()->AddLogString("-----------------------------------------------",true); + CZTLog::instance()->AddLogString("Mode entretien activé: Zone Tests hors service",true); + } + else + { + QString str = "Le mode entretien ne peut être activé si:\n- ZT1 ou ZT2 sont activées\n- Un train est sur le CDV d'approche (ZT1 ou ZT2)\n- Des TK sont en cours d'émission\n- La calibration PG est activée"; + QMessageBox::information(0,"Mode Entretien non disponible",str); + Btn->SetButtonState(TOGGLE_BUTTON_OFF); + } + } + else + { + mProgramHandle->ExitMaintenanceModeRequest(); + HideMaintenanceItems(); + mZT1PPEStatus->SetOFF(); + mZT1PPIStatus->SetOFF(); + mZT2PPEStatus->SetOFF(); + mZT2PPIStatus->SetOFF(); + mMaintenanceModeAutoExitTimer->stop(); + CZTLog::instance()->AddLogString("Mode entretien désactivé: Zone Tests en service.",true); + CZTLog::instance()->AddLogString("-------------------------------------------------",true); + } +} + +void CMaintenancePage::WatchdogEnableBtnToggled(CToggleButtonWidget *Btn) +{ + if(Btn->GetButtonState() == TOGGLE_BUTTON_ON) + { + CZTLog::instance()->AddLogString("[Mode entretien] Vigie réactivée.",true); + mProgramHandle->SetWatchdogEnabled(true); + } + else + { + CZTLog::instance()->AddLogString("[Mode entretien] Vigie désactivée.",true); + mProgramHandle->SetWatchdogEnabled(false); + } +} + +void CMaintenancePage::ShowMaintenanceItems() +{ + mGenerateAlarmBtn->show(); + mAlarmTypeList->show(); + mAlarmRankSpinBox->show(); + mAlarmDescription->show(); + mRankDescription->show(); + mFctDescription->show(); + + mPPIZT1Description->show(); + mPPEZT1Description->show(); + mZT1PPEStatus->show(); + mZT1PPIStatus->show(); + if(mProgramHandle->IsZT2PresentInStation()) + { + mPPIZT2Description->show(); + mPPEZT2Description->show(); + mZT2PPEStatus->show(); + mZT2PPIStatus->show(); + } + mPPTitle->show(); + mWatchdogDisableDescription->show(); + + mAlarmsFrame->show(); + mPPFrame->show(); + + mWatchdogEnableBtn->SetButtonState(TOGGLE_BUTTON_ON); + mWatchdogEnableBtn->show(); + + mCancelButton->hide(); +} + +void CMaintenancePage::HideMaintenanceItems() +{ + + mGenerateAlarmBtn->hide(); + mClearAlarmButton->hide(); + mAlarmTypeList->hide(); + mAlarmRankSpinBox->hide(); + mAlarmDescription->hide(); + mRankDescription->hide(); + mFctDescription->hide(); + + mPPIZT1Description->hide(); + mPPEZT1Description->hide(); + mPPIZT2Description->hide(); + mPPEZT2Description->hide(); + mZT1PPEStatus->hide(); + mZT1PPIStatus->hide(); + mZT2PPEStatus->hide(); + mZT2PPIStatus->hide(); + mPPTitle->hide(); + mWatchdogDisableDescription->hide(); + + mAlarmsFrame->hide(); + mPPFrame->hide(); + + mWatchdogEnableBtn->hide(); + + mCancelButton->show(); + +} + +void CMaintenancePage::GenerateTK() +{ + int AlarmID = mAlarmTypeList->currentIndex(); + if(AlarmID < 0 || AlarmID >= DETECTION_MAX_DETECTION_ID) + return; + int Rank = mAlarmRankSpinBox->value(); + + mProgramHandle->SendTKToPCC(AlarmID,Rank); + + CZTLog::instance()->AddLogString(QString().sprintf("[Mode entretien] Émission manuelle d'une alarme au PCC: %s au rang %d",CZTData::GetErrorString(AlarmID),Rank),true); +} + +void CMaintenancePage::TKOutputChanged(bool ZT1Active, bool ZT2Active) +{ + if(ZT1Active || ZT2Active) + { + mClearAlarmButton->show(); + } + else + { + mClearAlarmButton->hide(); + } +} + +void CMaintenancePage::PPActivated(unsigned int PedalID) +{ + switch(PedalID) + { + case MAINTENANCE_PPI_ZT1_ID: + { + mZT1PPIStatus->SetON(); + CZTLog::instance()->AddLogString("[Mode entretien] Pneu porteur intérieur ZT1 détecté. TK envoyée au PCC",true); + break; + } + case MAINTENANCE_PPE_ZT1_ID: + { + mZT1PPEStatus->SetON(); + CZTLog::instance()->AddLogString("[Mode entretien] Pneu porteur extérieur ZT1 détecté. TK envoyée au PCC",true); + break; + } + case MAINTENANCE_PPI_ZT2_ID: + { + mZT2PPIStatus->SetON(); + CZTLog::instance()->AddLogString("[Mode entretien] Pneu porteur intérieur ZT2 détecté. TK envoyée au PCC",true); + break; + } + case MAINTENANCE_PPE_ZT2_ID: + { + mZT2PPEStatus->SetON(); + CZTLog::instance()->AddLogString("[Mode entretien] Pneu porteur extérieur ZT2 détecté. TK envoyée au PCC",true); + break; + } + } +} + +void CMaintenancePage::AutoExit() +{ + mMaintenanceActivationBtn->SetButtonState(TOGGLE_BUTTON_OFF); + mProgramHandle->ExitMaintenanceModeRequest(); + HideMaintenanceItems(); + mZT1PPEStatus->SetOFF(); + mZT1PPIStatus->SetOFF(); + mZT2PPEStatus->SetOFF(); + mZT2PPIStatus->SetOFF(); + CZTLog::instance()->AddLogString("Désactivation automatique du mode entretien: Zone Tests en service.",true); +} + +//Grab the mouse if the user clicks outside buttons +void CMaintenancePage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void CMaintenancePage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} diff --git a/sources/GuiElements/MaintenancePage.h b/sources/GuiElements/MaintenancePage.h new file mode 100644 index 0000000..bd49256 --- /dev/null +++ b/sources/GuiElements/MaintenancePage.h @@ -0,0 +1,101 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131122 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef MAINTENANCEPAGE_H +#define MAINTENANCEPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "ZTSimulator.h" +#include "TextButtonWidget.h" +#include +#include +#include "ToggleButtonWidget.h" +#include "ONOFFStatusWidget.h" + +class CZoneTest; + + +#define MAINTENANCE_AUTO_EXIT_TIMEOUT (int)7200000 //Exit after 2 hours. + +enum ePPId +{ + MAINTENANCE_PPI_ZT1_ID, + MAINTENANCE_PPE_ZT1_ID, + MAINTENANCE_PPI_ZT2_ID, + MAINTENANCE_PPE_ZT2_ID +}; + +class CMaintenancePage : public CGuiPage +{ +Q_OBJECT +public: + CMaintenancePage(QGraphicsWidget *Parent = 0); + + CZoneTest *mProgramHandle; + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + +private: + QGraphicsRectItem *mBackgroundRect; + CTextButtonWidget *mCancelButton, *mGenerateAlarmBtn, *mClearAlarmButton; + + QComboBox *mAlarmTypeList; + QSpinBox *mAlarmRankSpinBox; + QGraphicsTextItem *mAlarmDescription, *mRankDescription, *mFctDescription, *mWatchdogDisableDescription; + QGraphicsTextItem *mPPIZT1Description, *mPPIZT2Description, *mPPEZT1Description, *mPPEZT2Description, *mPPTitle; + CToggleButtonWidget *mMaintenanceActivationBtn; + CToggleButtonWidget *mWatchdogEnableBtn; + CONOFFStatusWidget *mZT1PPIStatus, *mZT1PPEStatus, *mZT2PPIStatus, *mZT2PPEStatus; + QTimer *mMaintenanceModeAutoExitTimer; + + QGraphicsRectItem *mPPFrame, *mAlarmsFrame; + + void GenerateTK(); + void ShowMaintenanceItems(); + void HideMaintenanceItems(); + + + +public slots: + void ButtonClicked(CTextButtonWidget *); + void AlarmTypeSelectionChanged(int); + void ActivationBtnToggled(CToggleButtonWidget*); + void PPActivated(unsigned int); + void AutoExit(); + void WatchdogEnableBtnToggled(CToggleButtonWidget*); + void TKOutputChanged(bool,bool); + +}; + +#endif // OPTIONSPAGE_H diff --git a/sources/GuiElements/ONOFFStatusWidget.cpp b/sources/GuiElements/ONOFFStatusWidget.cpp new file mode 100755 index 0000000..09d8cc8 --- /dev/null +++ b/sources/GuiElements/ONOFFStatusWidget.cpp @@ -0,0 +1,85 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + . + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130306 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ONOFFStatusWidget.h" +#include +#define ON_OFF_WIDGET_SIZE 30 + +CONOFFStatusWidget::CONOFFStatusWidget(QString Label) +{ + mONLedOffPixmap = new QGraphicsPixmapItem(QPixmap("./Images/green-led-off-md.png").scaled(ON_OFF_WIDGET_SIZE,ON_OFF_WIDGET_SIZE),this); + mONLedOnPixmap = new QGraphicsPixmapItem(QPixmap("./Images/green-led-on-md.png").scaled(ON_OFF_WIDGET_SIZE,ON_OFF_WIDGET_SIZE),this); + mOFFLedOffPixmap = new QGraphicsPixmapItem(QPixmap("./Images/red-led-off-md.png").scaled(ON_OFF_WIDGET_SIZE,ON_OFF_WIDGET_SIZE),this); + mOFFLedOnPixmap = new QGraphicsPixmapItem(QPixmap("./Images/red-led-on-md.png").scaled(ON_OFF_WIDGET_SIZE,ON_OFF_WIDGET_SIZE),this); + + mOFFLedOffPixmap->setPos(0,20); + mOFFLedOnPixmap->setPos(0,20); + mONLedOffPixmap->setPos(30,20); + mONLedOnPixmap->setPos(30,20); + + mONLedOnPixmap->hide(); + mOFFLedOffPixmap->hide(); + + mLabel = new QGraphicsTextItem(this); + mLabel->setPlainText(Label); + mLabel->setPos(5,0); + + + +} + +CONOFFStatusWidget::~CONOFFStatusWidget() +{ +} + +void CONOFFStatusWidget::SetON() +{ + mONLedOnPixmap->show(); + mONLedOffPixmap->hide(); + mOFFLedOnPixmap->hide(); + mOFFLedOffPixmap->show(); +} + +void CONOFFStatusWidget::SetOFF() +{ + mONLedOnPixmap->hide(); + mONLedOffPixmap->show(); + mOFFLedOnPixmap->show(); + mOFFLedOffPixmap->hide(); +} + +void CONOFFStatusWidget::Toggle() +{ + if(mONLedOnPixmap->isVisible()) + { + SetOFF(); + } + else + { + SetON(); + } +} diff --git a/sources/GuiElements/ONOFFStatusWidget.h b/sources/GuiElements/ONOFFStatusWidget.h new file mode 100755 index 0000000..cc7ffac --- /dev/null +++ b/sources/GuiElements/ONOFFStatusWidget.h @@ -0,0 +1,32 @@ +#ifndef ONOFFSTATUSWIDGET_H +#define ONOFFSTATUSWIDGET_H + +#include +#include +#include + +class CONOFFStatusWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + + CONOFFStatusWidget(QString Lable = QString()); + ~CONOFFStatusWidget(); + + QGraphicsTextItem *mLabel; + QGraphicsPixmapItem *mONLedOnPixmap,*mONLedOffPixmap; + QGraphicsPixmapItem *mOFFLedOnPixmap,*mOFFLedOffPixmap; + + void SetON(); + void SetOFF(); + void Toggle(); + + + +public slots: + + + +}; + +#endif // ONOFFSTATUSWIDGET_H diff --git a/sources/GuiElements/OptionsPage.cpp b/sources/GuiElements/OptionsPage.cpp new file mode 100644 index 0000000..215a8de --- /dev/null +++ b/sources/GuiElements/OptionsPage.cpp @@ -0,0 +1,136 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page de sélection des options (sélection des fonctions de détection, ingénierie, + mode entretien, etc.). + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "OptionsPage.h" +#include +#include "GlobalDefine.h" +#include +#include +#include "Zonetest.h" +#include +#include + + + +COptionsPage::COptionsPage(QGraphicsWidget *Parent) +{ + Q_UNUSED(Parent) + + mProgramHandle = 0; + mZTSimulatorPtr = 0; + + + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QBrush BackgroundBrush(QColor(245, 245, 255)); + mBackgroundRect->setBrush(BackgroundBrush); + + QGraphicsTextItem *Title = new QGraphicsTextItem("Choisissez une option",this); + QFont font; + font.setPointSize(18); + Title->setFont(font); + Title->setPos(40,10); + + mZTFunctionsButton = new CTextButtonWidget("Fonctions Détection"); + mZTFunctionsButton->setParentItem(this); + mZTFunctionsButton->setPos(50,60); + connect(mZTFunctionsButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mZTMaintenanceModeButton = new CTextButtonWidget("Mode entretien"); + mZTMaintenanceModeButton->setParentItem(this); + mZTMaintenanceModeButton->setPos(50,100); + connect(mZTMaintenanceModeButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mZTEngineeringButton = new CTextButtonWidget("Ingénierie"); + mZTEngineeringButton->setParentItem(this); + mZTEngineeringButton->setPos(50,140); + connect(mZTEngineeringButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mZTGeneralSettingsButton = new CTextButtonWidget("Paramètres"); + mZTGeneralSettingsButton->setParentItem(this); + mZTGeneralSettingsButton->setPos(50,180); + connect(mZTGeneralSettingsButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mZTLogViewButton = new CTextButtonWidget("Fichier LOG"); + mZTLogViewButton->setParentItem(this); + mZTLogViewButton->setPos(50,220); + connect(mZTLogViewButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + + mCancelButton = new CTextButtonWidget("Fermer"); + mCancelButton->setParentItem(this); + mCancelButton->setPos(50,260); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + +} + +void COptionsPage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + mBackgroundRect->setRect(boundingRect()); +} + +void COptionsPage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mZTFunctionsButton) + { + mProgramHandle->ZTFunctionsOptionSelected(); + + } + else if(BtnPtr == mZTMaintenanceModeButton) + { + mProgramHandle->ZTMaintenanceOptionSeleced(); + } + else if(BtnPtr == mCancelButton) + { + hide(); + } + else if(BtnPtr == mZTEngineeringButton) + { + mProgramHandle->OpenEngineeringPageRequest(); + } + else if(BtnPtr == mZTGeneralSettingsButton) + { + mProgramHandle->OpenGeneralSettingsPage(); + } + else if(BtnPtr == mZTLogViewButton) + { + mProgramHandle->ShowZTLogViewerPage(); + } +} + +//Grab the mouse if the user clicks outside buttons +void COptionsPage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void COptionsPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} diff --git a/sources/GuiElements/OptionsPage.h b/sources/GuiElements/OptionsPage.h new file mode 100644 index 0000000..d74c9aa --- /dev/null +++ b/sources/GuiElements/OptionsPage.h @@ -0,0 +1,73 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef OPTIONSPAGE_H +#define OPTIONSPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "ZTSimulator.h" +#include "TextButtonWidget.h" + + +class CZoneTest; + +class COptionsPage : public CGuiPage +{ +Q_OBJECT +public: + COptionsPage(QGraphicsWidget *Parent = 0); + CPushButton *mToolsPushButton; + + + CZoneTest *mProgramHandle; + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + +private: + CZTSimulator *mZTSimulatorPtr; + QGraphicsRectItem *mBackgroundRect; + CTextButtonWidget *mZTFunctionsButton; + CTextButtonWidget *mZTMaintenanceModeButton; + CTextButtonWidget *mZTEngineeringButton; + CTextButtonWidget *mZTGeneralSettingsButton; + CTextButtonWidget *mZTLogViewButton; + CTextButtonWidget *mCancelButton; + + +public slots: + void ButtonClicked(CTextButtonWidget *); + +}; + +#endif // OPTIONSPAGE_H diff --git a/sources/GuiElements/PasswordPrompt.cpp b/sources/GuiElements/PasswordPrompt.cpp new file mode 100644 index 0000000..663045b --- /dev/null +++ b/sources/GuiElements/PasswordPrompt.cpp @@ -0,0 +1,152 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page qui demande à l'utlisateur d'entrer un mot de passe. + + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "PasswordPrompt.h" +#include +#include +#include "ZTLog.h" +#include "EngLog.h" +#include + + +CPasswordPrompt::CPasswordPrompt(QGraphicsItem *Parent) +{ + setParentItem(Parent); + setGeometry(0,0,1024,768); + + QGraphicsRectItem *BckgndRect = new QGraphicsRectItem(this); + BckgndRect->setRect(0,0,1024,768); + BckgndRect->setBrush(QBrush(QColor(Qt::lightGray))); + + mAcceptBtn = new CTextButtonWidget("OK"); + mAcceptBtn->setParentItem(this); + mAcceptBtn->setPos(400,300); + connect(mAcceptBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonPressed(CTextButtonWidget*))); + + mCancelBtn = new CTextButtonWidget("Annuler"); + mCancelBtn->setParentItem(this); + mCancelBtn->setPos(530,300); + connect(mCancelBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonPressed(CTextButtonWidget*))); + + mLineEditWidget = new QLineEdit(); + mLineEditWidget->setEchoMode(QLineEdit::Password); + QGraphicsProxyWidget *Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mLineEditWidget); + Proxy->setPos(400,250); + + QGraphicsTextItem *Label = new QGraphicsTextItem(this); + Label->setPlainText("Veuillez entrer le mot de passe:"); + Label->setPos(400,220); + + mPassword.clear(); + mPassword = DEFAULT_PASSWORD; + LoadPasswordFile(); + + hide(); +} + +void CPasswordPrompt::RequestPassword() +{ + mLineEditWidget->setFocus(); + show(); +} + +void CPasswordPrompt::ButtonPressed(CTextButtonWidget *Btn) +{ + if(Btn == mAcceptBtn) + { + if(mLineEditWidget->text() == mPassword) + { + mLineEditWidget->clear(); + emit PasswordValid(); + } + else + { + CZTLog::instance()->AddLogString("Tentative de mot de passe invalide.",true); + CEngLog::instance()->AddLogString(QString().sprintf("Tentative de mot de passe invalide %s.",mLineEditWidget->text().toLatin1().data()),1); + + mLineEditWidget->clear(); + } + } + else if(Btn == mCancelBtn) + { + mLineEditWidget->clear(); + emit Canceled(); + } +} + +bool CPasswordPrompt::LoadPasswordFile() +{ + QFile *ZTPasswordFile = new QFile("./Configuration/ZT.pwd"); + if (!ZTPasswordFile->open(QIODevice::ReadOnly | QIODevice::Text)) + { + CEngLog::instance()->AddLogString("Fichier de mot de passe invalide. Utilisation du mot de passe par défaut."); + delete ZTPasswordFile; + return false; + } + + QString string; + + string.clear(); + string = ZTPasswordFile->readLine(1024); + if(string.isEmpty()) + { + CEngLog::instance()->AddLogString("Fichier de mot de passe invalide. Utilisation du mot de passe par défaut."); + ZTPasswordFile->close(); + delete ZTPasswordFile; + return false; + } + + string.remove("\n"); //remove trailing "\n" characters inserted by QFile.readline + mPassword.clear(); + mPassword = string; + + ZTPasswordFile->close(); + delete ZTPasswordFile; + + return true; + +} + +void CPasswordPrompt::keyPressEvent(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Return) + { + ButtonPressed(mAcceptBtn); + } +} + +void CPasswordPrompt::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->accept(); +} + +void CPasswordPrompt::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + event->accept(); +} diff --git a/sources/GuiElements/PasswordPrompt.h b/sources/GuiElements/PasswordPrompt.h new file mode 100644 index 0000000..87344f6 --- /dev/null +++ b/sources/GuiElements/PasswordPrompt.h @@ -0,0 +1,66 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef PASSWORDPROMPT_H +#define PASSWORDPROMPT_H + +#include +#include "TextButtonWidget.h" +#include +#include "GlobalDefine.h" + +class CPasswordPrompt : public QGraphicsWidget +{ + Q_OBJECT +public: + CPasswordPrompt(QGraphicsItem *Parent); + + void RequestPassword(); + + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void keyPressEvent(QKeyEvent *event); + +private: + CTextButtonWidget *mAcceptBtn, *mCancelBtn; + QLineEdit *mLineEditWidget; + QString mPassword; + + bool LoadPasswordFile(); + + +signals: + void PasswordValid(); + void Canceled(); + +public slots: + void ButtonPressed(CTextButtonWidget*); + + +}; + +#endif // PASSWORDPROMPT_H diff --git a/sources/GuiElements/PushButton.cpp b/sources/GuiElements/PushButton.cpp new file mode 100644 index 0000000..99b498d --- /dev/null +++ b/sources/GuiElements/PushButton.cpp @@ -0,0 +1,257 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Widget graphique Bouton qui consiste en une image sur laquelle l'on peut + cliquer. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130204 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "PushButton.h" +#include +#include +#include +#include +#include +#include +#include + +CPushButton::CPushButton(QGraphicsItem *Parent,QString NormalFileName, bool UseTextOverlay,int ButtonData) +{ + Q_UNUSED(ButtonData) + setParentItem(Parent); + + setAcceptHoverEvents(true); + + m_Normal = new QGraphicsPixmapItem(QPixmap(NormalFileName)); + + ClickTransparency = 1; + + //Inform QGraphicsItem of the geometry + setGeometry(m_Normal->boundingRect()); + + ispressed = false; + isFlashingValid = false; + mDisplayFlashIcon = false; + isreleasing = false; + UseOverlay = UseTextOverlay; + ButtonTextOverlay = ""; + + + timeLine = new QTimeLine(PRESS_EFFECT_FADE_TIMEOUT); + timeLine->setCurveShape(QTimeLine::EaseInCurve); + connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(TimeLine(qreal))); + +} + +CPushButton::~CPushButton() +{ + delete m_Normal; + delete timeLine; +} + +void CPushButton::paint(QPainter *Painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + +// Painter->setCompositionMode(QPainter::CompositionMode_DestinationOver); + /*if(isDown() || isChecked()) + { + m_Normal->paint(Painter,option,widget); + qDebug("Paint Called, button down"); + } + else if(underMouse()) + { + m_Hovered->paint(Painter,option,widget); + qDebug("Paint Called, hovered"); + } + else + { + m_Pressed->paint(Painter,option,widget); + qDebug("Paint Called, normal"); + }*/ + + + if(ispressed) + { + + //QRadialGradient gradient(50, 50, 50, 50, 50); + QRadialGradient gradient(m_Normal->boundingRect().center(),m_Normal->boundingRect().width()/2); + gradient.setColorAt(0, QColor::fromRgbF(1, 1, 1,1)); + gradient.setColorAt(1, QColor::fromRgbF(1, 1, 1,0)); + + QBrush brush(gradient); + // m_Pressed->paint(Painter,option,widget); + m_Normal->paint(Painter,option,widget); + Painter->setBrush(brush); + Painter->setPen(Qt::NoPen); + //Painter->drawEllipse(m_Normal->boundingRect()); + Painter->drawEllipse(m_Normal->boundingRect()); + + //qDebug("Paint Called, pressed"); + } + /* else if(ishovered) + { + m_Hovered->paint(Painter,option,widget); + // qDebug("Paint Called, hovered"); + }*/ + else + { + if(mDisplayFlashIcon) + { + m_Flashing->paint(Painter,option,widget); + } + else + { + + //draw button icon + m_Normal->paint(Painter,option,widget); + + //draw text overlay + QRectF textRect = m_Normal->boundingRect();//.adjusted(15, 10, -10, -15); + int flags = Qt::AlignHCenter | Qt::AlignVCenter; + + QFont font; + font.setPixelSize(16); + font.setBold(true); + Painter->setPen(Qt::red); + Painter->setFont(font); + Painter->drawText(textRect, flags, ButtonTextOverlay); + + //if necessary, draw halo animation + if(isreleasing) + { + //QRadialGradient gradient(50, 50, 50, 50, 50); + QRadialGradient gradient(m_Normal->boundingRect().center(),m_Normal->boundingRect().width()/2); + gradient.setColorAt(0, QColor::fromRgbF(1, 1, 1,ClickTransparency)); + gradient.setColorAt(1, QColor::fromRgbF(1, 1, 1, 0)); + + QBrush brush(gradient); + // m_Pressed->paint(Painter,option,widget); + m_Normal->paint(Painter,option,widget); + Painter->setBrush(brush); + Painter->setPen(Qt::NoPen); + //Painter->drawEllipse(m_Normal->boundingRect()); + Painter->drawEllipse(m_Normal->boundingRect()); + } + + } + // qDebug("Paint Called, normal"); + } + + +} + +void CPushButton::hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) +{ + event->accept(); + update(); + // qDebug("Hover Enter Called"); +} +void CPushButton::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ) +{ + event->accept(); + update(); + // qDebug("Hover Leave Called"); +} +void CPushButton::mousePressEvent ( QGraphicsSceneMouseEvent * event ) +{ + Q_UNUSED(event) + // + ispressed = true; + update(); + emit pressed(this); + + + // qDebug("Mouse Press Event"); + //event->ignore(); + +} +void CPushButton::mouseReleaseEvent( QGraphicsSceneMouseEvent * event) +{ + Q_UNUSED(event) + ispressed = false; + + emit released(this); + isreleasing = true; + + timeLine->start(); + // qDebug("Button Mouse Release Event"); + +} + +void CPushButton::StartFlashing() +{ + mFlashTimer->start(mFlashTimeout); +} +void CPushButton::StopFlashing() +{ + mFlashTimer->stop(); + mDisplayFlashIcon = false; +} +void CPushButton::setFlashingData(QString FlashFileName,int FlashDelay) +{ + QPixmap temp(FlashFileName); + QBitmap temp2 = temp.createMaskFromColor(QColor(255,255,255),Qt::MaskOutColor); +// temp.setMask(temp2); + m_Flashing = new QGraphicsPixmapItem(temp); + if(!m_Flashing) + { + isFlashingValid = false; + return; + } + isFlashingValid = true; + mFlashTimeout = FlashDelay; + mFlashTimer = new QTimer(this); + connect(mFlashTimer,SIGNAL(timeout()),this,SLOT(FlashButton())); + +} +void CPushButton::FlashButton() +{ + mDisplayFlashIcon = !mDisplayFlashIcon; + update(); +} + +void CPushButton::TimeLine(qreal value) +{ + ClickTransparency = 1-value; + + update(); + + if(value == 1) + { + isreleasing = false; + emit clicked(this); + } + + +} + +void CPushButton::SetTextOverlay(QString Text) +{ + ButtonTextOverlay = Text.left(MAX_OVERLAY_TEXT_LENGTH); + update(); +} + +void CPushButton::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + m_Normal->setPixmap(m_Normal->pixmap().scaled(event->newSize().width(),event->newSize().height())); +} diff --git a/sources/GuiElements/PushButton.h b/sources/GuiElements/PushButton.h new file mode 100644 index 0000000..6aa1310 --- /dev/null +++ b/sources/GuiElements/PushButton.h @@ -0,0 +1,77 @@ +#ifndef PUSHBUTTON_H +#define PUSHBUTTON_H + +//#include +#include +#include +#include +class QGraphicsPixmapItem; +#include +#include + +class QTimer; + +#define PRESS_EFFECT_FADE_TIMEOUT 200 +#define MAX_OVERLAY_TEXT_LENGTH 3 + +class CPushButton : public QGraphicsWidget +{ + Q_OBJECT +public: + CPushButton(QGraphicsItem *Parent, QString NormalFileName,bool UseTextOverlay = false, int ButtonData = 0); + virtual ~CPushButton(); + + void setFlashingData(QString FlashingFileName,int FlashingDelay); + void StartFlashing(void); + void StopFlashing(void); + void SetTextOverlay(QString Text); + void SetButtonData(unsigned long int ButtonData){mButtonData = ButtonData;} + unsigned long int GetBUttonData(){return mButtonData;} + + + void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + // QRectF boundingRect() const; + + bool ispressed; + bool isreleasing; + bool isFlashingValid; + bool mDisplayFlashIcon; + bool UseOverlay; + QTimer *mFlashTimer; + int mFlashTimeout; + QString ButtonTextOverlay; + unsigned long int mButtonData; + + protected: + //virtual void paintEvent(QPaintEvent *e); + virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event ); + virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event ); + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + + private: + QTimeLine *timeLine; + qreal ClickTransparency; + + signals: + void clicked(CPushButton *ButtonPtr); + void pressed(CPushButton *ButtonPtr); + void released(CPushButton *ButtonPtr); + + public slots: + void FlashButton(); + void TimeLine(qreal value); + + private: + QGraphicsPixmapItem *m_Normal; + QGraphicsPixmapItem *m_Pressed; + QGraphicsPixmapItem *m_Hovered; + QGraphicsPixmapItem *m_Flashing; + + + + +}; + +#endif // PUSHBUTTON_H diff --git a/sources/GuiElements/RankRulerWidget.cpp b/sources/GuiElements/RankRulerWidget.cpp new file mode 100644 index 0000000..4cda3d1 --- /dev/null +++ b/sources/GuiElements/RankRulerWidget.cpp @@ -0,0 +1,287 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Élément graphique qui affiche une règle qui indique le décompte des rangs + du train dans le temps. Ce qui permet de savoir à quel rang un événement + est survenu lors de la consultation d'un passage de train. + + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "RankRulerWidget.h" +#include +#include +#include + +CRankRulerWidget::~CRankRulerWidget() +{ + delete mRulerPixmap; +} + +CRankRulerWidget::CRankRulerWidget(qreal RulerPixelWidth, QGraphicsItem *Parent) +{ + setParentItem(Parent); + mPixelWidth = RulerPixelWidth; + mLabel = new QGraphicsTextItem(this); + + mRulerPixmap = new QPixmap(boundingRect().width(),boundingRect().height()); +} + +void CRankRulerWidget::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + + delete mRulerPixmap; + mRulerPixmap = new QPixmap(boundingRect().width(),boundingRect().height()); + Render(); +} + +void CRankRulerWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget) + + painter->setClipRect(option->exposedRect); + painter->drawPixmap(0,0,*mRulerPixmap); + +// if(mRankItems.isEmpty()) +// return; +// QFont font; +// font.setPixelSize(12); +// painter->setFont(font); +// qreal pitch = mPixelWidth/(mEndTime - mStartTime); //pixel/ns + +// int StartIndex = 0,EndIndex = 0; +// bool StartFound = false; + +// for(int i = 0; i < mRankItems.size(); i++) +// { +// if(StartFound == false) +// { +// if(mStartTime <= mRankItems.at(i).mStartTime) +// { +// StartIndex = i; +// StartFound = true; +// } +// } + +// if(mRankItems.at(i).mEndTime <= mEndTime) +// { +// EndIndex = i; +// } +// } + +// if(StartIndex > 0) +// { +// if(mStartTime < mRankItems.at(StartIndex).mStartTime) +// { +// QRectF LabelRect; +// qreal StartPixel = 0;//mStartTime * pitch; +// qreal EndPixel = (mRankItems.at(StartIndex).mStartTime - mStartTime) * pitch; +// qreal Height = boundingRect().height(); + +// LabelRect.setRect(StartPixel,0,(EndPixel-StartPixel),Height); +// painter->drawLine(StartPixel,0,StartPixel,Height); +// painter->drawLine(EndPixel,0,EndPixel,Height); +// painter->drawText(LabelRect,mRankItems.at(StartIndex-1).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); + +// } +// } + +// for(int i = StartIndex; i <= EndIndex; i++) +// { +// QRectF LabelRect; +// qreal StartPixel = (mRankItems.at(i).mStartTime - mStartTime) * pitch; + +// qreal EndPixel; +// if(mRankItems.at(i).mEndTime > mEndTime) +// EndPixel = (mEndTime - mStartTime) * pitch; +// else +// EndPixel = (mRankItems.at(i).mEndTime - mStartTime) * pitch; + +// qreal Height = boundingRect().height(); + +// LabelRect.setRect(StartPixel,0,(EndPixel-StartPixel),Height); +// painter->drawLine(StartPixel,0,StartPixel,Height); +// painter->drawLine(EndPixel,0,EndPixel,Height); +// painter->drawText(LabelRect,mRankItems.at(i).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); +// } +// if(EndIndex < mRankItems.size()-1) +// { +// if(mEndTime > mRankItems.at(EndIndex).mStartTime) +// { +// QRectF LabelRect; +// qreal StartPixel = (mRankItems.at(EndIndex).mEndTime - mStartTime) * pitch; +// qreal EndPixel = (mEndTime - mStartTime) * pitch; +// qreal Height = boundingRect().height(); + +// LabelRect.setRect(StartPixel,0,(EndPixel-StartPixel),Height); +// painter->drawLine(StartPixel,0,StartPixel,Height); +// painter->drawLine(EndPixel,0,EndPixel,Height); +//// if(EndIndex == StartIndex) +//// painter->drawText(LabelRect,mRankItems.at(EndIndex).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); +//// else +// painter->drawText(LabelRect,mRankItems.at(EndIndex+1).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); + +// } +// } +} + +void CRankRulerWidget::Render() +{ + + if(mRankItems.isEmpty()) + return; + + mRulerPixmap->fill(Qt::white); + QPainter *painter = new QPainter(mRulerPixmap); + + QFont font; + font.setPixelSize(12); + painter->setFont(font); + qreal pitch = mPixelWidth/(mEndTime - mStartTime); //pixel/ns + + + + int StartIndex = 0,EndIndex = 0; + bool StartFound = false; + + for(int i = 0; i < mRankItems.size(); i++) + { + if(StartFound == false) + { + if(mStartTime <= mRankItems.at(i).mStartTime) + { + StartIndex = i; + StartFound = true; + } + } + + if(mRankItems.at(i).mEndTime <= mEndTime) + { + EndIndex = i; + } + } + + if(StartIndex > 0) + { + if(mStartTime < mRankItems.at(StartIndex).mStartTime) + { + QRectF LabelRect; + qreal StartPixel = 0;//mStartTime * pitch; + qreal EndPixel = (mRankItems.at(StartIndex).mStartTime - mStartTime) * pitch; + qreal Height = boundingRect().height(); + + LabelRect.setRect(StartPixel,0,(EndPixel-StartPixel),Height); + painter->drawLine(StartPixel,0,StartPixel,Height); + painter->drawLine(EndPixel,0,EndPixel,Height); + painter->drawText(LabelRect,mRankItems.at(StartIndex-1).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); + + } + } + + for(int i = StartIndex; i <= EndIndex; i++) + { + QRectF LabelRect; + qreal StartPixel = (mRankItems.at(i).mStartTime - mStartTime) * pitch; + + qreal EndPixel; + if(mRankItems.at(i).mEndTime > mEndTime) + EndPixel = (mEndTime - mStartTime) * pitch; + else + EndPixel = (mRankItems.at(i).mEndTime - mStartTime) * pitch; + + qreal Height = boundingRect().height(); + + LabelRect.setRect(StartPixel,0,(EndPixel-StartPixel),Height); + painter->drawLine(StartPixel,0,StartPixel,Height); + painter->drawLine(EndPixel,0,EndPixel,Height); + painter->drawText(LabelRect,mRankItems.at(i).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); + } + if(EndIndex < mRankItems.size()-1) + { + if(mEndTime > mRankItems.at(EndIndex).mStartTime) + { + QRectF LabelRect; + qreal StartPixel = (mRankItems.at(EndIndex).mEndTime - mStartTime) * pitch; + qreal EndPixel = (mEndTime - mStartTime) * pitch; + qreal Height = boundingRect().height(); + + LabelRect.setRect(StartPixel,0,(EndPixel-StartPixel),Height); + painter->drawLine(StartPixel,0,StartPixel,Height); + painter->drawLine(EndPixel,0,EndPixel,Height); +// if(EndIndex == StartIndex) +// painter->drawText(LabelRect,mRankItems.at(EndIndex).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); +// else + painter->drawText(LabelRect,mRankItems.at(EndIndex+1).mLabel,Qt::AlignHCenter | Qt::AlignVCenter); + + } + } + + delete painter; +} + + +unsigned int CRankRulerWidget::SetRange(quint64 StartTime, quint64 EndTime) +{ + if(StartTime > EndTime) + return false; + + if(mRankItems.isEmpty()) + return false; + + + mStartTime = StartTime; + mEndTime = EndTime; + mTimeOffset = mRankItems.first().mStartTime; + + Render(); + + update(); + + return RET_OK; +} + +unsigned int CRankRulerWidget::AddRankItem(QString Rank, quint64 StartTime, quint64 EndTime) +{ + CRankWidgetItem NewItem; + NewItem.mLabel = Rank; + NewItem.mStartTime = StartTime; + NewItem.mEndTime = EndTime; + + mRankItems.append(NewItem); + return RET_OK; +} + +void CRankRulerWidget::SetLabel(QString Label, int Offset) +{ + QFont font; + font.setBold(true); + mLabel->setFont(font); + mLabel->setPlainText(Label); + mLabel->setPos(-Offset,boundingRect().height()/2 - mLabel->boundingRect().height()/2); +} + +void CRankRulerWidget::ClearRuler() +{ + mRankItems.clear(); +} diff --git a/sources/GuiElements/RankRulerWidget.h b/sources/GuiElements/RankRulerWidget.h new file mode 100644 index 0000000..51fae4c --- /dev/null +++ b/sources/GuiElements/RankRulerWidget.h @@ -0,0 +1,74 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131030 JFM + Verision d'origine. + +### 20131107 Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef RANKRULERWIDGET_H +#define RANKRULERWIDGET_H + +#include "GlobalDefine.h" +#include + +class CRankWidgetItem +{ +public: + QString mLabel; + quint64 mStartTime; + quint64 mEndTime; +}; + +class CRankRulerWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CRankRulerWidget(qreal RulerPixelWidth,QGraphicsItem *Parent = 0); + ~CRankRulerWidget(); + + + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + unsigned int SetRange(quint64 StartTime, quint64 EndTime); + unsigned int AddRankItem(QString Rank,quint64 StartTime,quint64 EndTime); + void SetLabel(QString Label,int Offset); + void ClearRuler(); + void resizeEvent(QGraphicsSceneResizeEvent *event); + + +private: + qreal mPixelWidth; + quint64 mStartTime, mEndTime, mTimeOffset; + qreal mPixelPitch; + QGraphicsTextItem *mLabel; + + QPixmap *mRulerPixmap; + + QList mRankItems; + + + void Render(); + +}; + +#endif // RANKRULERWIDGET_H diff --git a/sources/GuiElements/SimpleTextBoxWidget.cpp b/sources/GuiElements/SimpleTextBoxWidget.cpp new file mode 100644 index 0000000..df2cdb1 --- /dev/null +++ b/sources/GuiElements/SimpleTextBoxWidget.cpp @@ -0,0 +1,149 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Widget animé qui affiche une boîte contenant du texte. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "SimpleTextBoxWidget.h" + +#include +#include + +CSimpleTextBoxWidget::CSimpleTextBoxWidget(QGraphicsItem *parent) + : QGraphicsWidget(parent) +{ + opacity = 1.0; + hide(); + //mText = "TEst"; + + + timeLine = new QTimeLine(500); + timeLine->setCurveShape(QTimeLine::EaseOutCurve); + connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(setValue(qreal))); + + resize(SCREEN_RES_WIDTH, SCREEN_RES_HEIGHT); + + QTransform transform; + + // transform.translate(160,120); + transform.translate(SCREEN_RES_WIDTH/2,SCREEN_RES_HEIGHT/2); + transform.scale(0,0); + //transform.translate(-160,-120); + transform.translate(-SCREEN_RES_WIDTH/2,-SCREEN_RES_HEIGHT/2); + setTransform(transform); +} + +CSimpleTextBoxWidget::~CSimpleTextBoxWidget() +{ + delete timeLine; +} + +void CSimpleTextBoxWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + QRectF BoxRect; + BoxRect.setWidth(SCREEN_RES_WIDTH - 200); + BoxRect.setHeight(SCREEN_RES_HEIGHT - 200); + BoxRect.moveCenter(QPoint(SCREEN_RES_WIDTH/2,SCREEN_RES_HEIGHT/2)); + // painter->setOpacity(opacity); + painter->setPen(QPen(Qt::black, 2)); + painter->setBrush(QColor(245, 245, 255, 200)); + painter->setClipRect(rect()); + // painter->drawRoundRect(25, 10, SCREEN_RES_WIDTH - 200, SCREEN_RES_HEIGHT - 200); + painter->drawRoundRect(BoxRect); + + QRectF textRect(BoxRect); + // textRect.moveCenter(QPoint(160,120)); + int flags = Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap; + + QFont font; + font.setPixelSize(30); + painter->setPen(Qt::black); + painter->setFont(font); + QString text = "Ceci est un test\nTexte multiligne"; + painter->drawText(textRect, flags, mText); + + //textRect.moveTop(textRect.top()+15); + //painter->drawText(textRect, flags, mCallerNumber); +} + + +//void CSimpleTextBoxWidget::mousePressEvent(QGraphicsSceneMouseEvent * event ) +//{ +// if(isVisible()) +// { +// HideCallerID(); +// event->accept(); +// } +// else +// { +// event->ignore(); +// } +//} + + +void CSimpleTextBoxWidget::setValue(qreal value) +{ + QTransform transform; + + + //QRectF BoxRect = rect(); + transform.translate(SCREEN_RES_WIDTH/2,SCREEN_RES_HEIGHT/2); + transform.scale(value,value); + transform.translate(-SCREEN_RES_WIDTH/2,-SCREEN_RES_HEIGHT/2); + setTransform(transform); + + if(value == 0 && timeLine->direction()== QTimeLine::Backward) + { + hide(); + } +} + +void CSimpleTextBoxWidget::ShowTextBox() +{ + show(); + timeLine->setDirection(QTimeLine::Forward); + timeLine->start(); + +} + +void CSimpleTextBoxWidget::HideTextBox() +{ + timeLine->setDirection(QTimeLine::Backward); + timeLine->start(); + //hide(); +} + +void CSimpleTextBoxWidget::InsertString(QString TextLine) +{ + if(!mText.isEmpty()) + mText += '\n'; + mText += TextLine; + update(rect()); +} + +void CSimpleTextBoxWidget::ClearText() +{ + mText.clear(); +} diff --git a/sources/GuiElements/SimpleTextBoxWidget.h b/sources/GuiElements/SimpleTextBoxWidget.h new file mode 100644 index 0000000..f3dd1fb --- /dev/null +++ b/sources/GuiElements/SimpleTextBoxWidget.h @@ -0,0 +1,66 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMPLETEXTBOXWIDGET_H +#define SIMPLETEXTBOXWIDGET_H + +#include "GlobalDefine.h" +//#include +#include +#include +#include + +class CSimpleTextBoxWidget : public QGraphicsWidget +{ +Q_OBJECT +public: + + + CSimpleTextBoxWidget(QGraphicsItem *parent = 0); + ~CSimpleTextBoxWidget(); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + void InsertString(QString TextLine); + void ClearText(void); + + + void ShowTextBox(void); + void HideTextBox(void); +protected: + // virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + +private Q_SLOTS: + void setValue(qreal value); + +private: + QTimeLine *timeLine; + qreal opacity; + QString mText; + +}; + +#endif //CALLERIDWIDGET_H diff --git a/sources/GuiElements/StatusBar.cpp b/sources/GuiElements/StatusBar.cpp new file mode 100644 index 0000000..e7e7082 --- /dev/null +++ b/sources/GuiElements/StatusBar.cpp @@ -0,0 +1,252 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Affiche une barre d'informations. + + Utilisé sur la page principale de la ZT. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "StatusBar.h" +#include +#include + +CStatusBar::CStatusBar(QGraphicsItem *Parent) +{ + + setParentItem(Parent); + resize(SCREEN_RES_WIDTH,25); + + mZT1StatusString = "INACTIVE"; + mZT2StatusString = "INACTIVE"; + mNbTrainsPass = 10; + mNbTriggers = 2; + + mZT1Status = mZT2Status = SB_ZT_INACTIVE_STATUS; + mCCModbusState = SB_MODBUS_NOT_PRESENT; + mSEIModbusState = SB_MODBUS_NOT_PRESENT; +// QGraphicsRectItem *temprect = new QGraphicsRectItem(this); +// temprect->setRect(boundingRect()); +// temprect->show(); +} + +void CStatusBar::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + + Q_UNUSED(widget) + + + painter->setClipRect(option->exposedRect); + + QPen RectPen(Qt::SolidLine); + RectPen.setWidth(2); + painter->setPen(RectPen); + painter->drawLine(boundingRect().topLeft(),boundingRect().topRight()); + + QFont font; + QString Text; + QRectF TextRect = boundingRect(); + QFontMetrics FontMetrics = painter->fontMetrics(); + //font.setPixelSize(1); + font.setPointSize(15); + painter->setFont(font); + + painter->setPen(Qt::black); + Text = "ZT1: "; + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + + switch(mZT1Status) + { + case SB_ZT_ACTIVE_STATUS: + { + Text = "ACTIVE"; + painter->setPen(Qt::red); + break; + } + case SB_ZT_INACTIVE_STATUS: + { + Text = "INACTIVE"; + painter->setPen(Qt::darkGreen); + break; + } + case SB_ZT_NOT_PRESENT_STATUS: + { + Text = "ABSENTE"; + painter->setPen(Qt::black); + break; + } + case SB_ZT_DISABLED_STATUS: + { + Text = "HORS SERVICE"; + painter->setPen(Qt::darkYellow); + break; + } + } + + font.setBold(true); + painter->drawText(TextRect,Qt::AlignLeft,Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + + + painter->setPen(Qt::black); + Text = "ZT2: "; + TextRect.adjust(20,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + switch(mZT2Status) + { + case SB_ZT_ACTIVE_STATUS: + { + Text = "ACTIVE"; + painter->setPen(Qt::red); + break; + } + case SB_ZT_INACTIVE_STATUS: + { + Text = "INACTIVE"; + painter->setPen(Qt::darkGreen); + break; + } + case SB_ZT_NOT_PRESENT_STATUS: + { + Text = "ABSENTE"; + painter->setPen(Qt::black); + break; + } + case SB_ZT_DISABLED_STATUS: + { + Text = "HORS SERVICE"; + painter->setPen(Qt::darkYellow); + break; + } + } + + font.setBold(true); + painter->drawText(TextRect,Qt::AlignLeft,Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + + + painter->setPen(Qt::black); + Text.clear(); + Text.sprintf("Passages:%d",mNbTrainsPass); + TextRect.adjust(20,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + + Text.clear(); + Text.sprintf("Déclenchements:%d",mNbTriggers); + TextRect.adjust(20,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + + if(mCCModbusState != SB_MODBUS_NOT_PRESENT || mSEIModbusState != SB_MODBUS_NOT_PRESENT) + { + painter->setPen(Qt::black); + Text.clear(); + Text.sprintf("Modbus:"); + TextRect.adjust(20,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + + if(mCCModbusState == SB_MODBUS_CONNECTED) + { + painter->setPen(Qt::darkGreen); + Text.clear(); + Text.sprintf("CC[Connecté]"); + TextRect.adjust(5,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + } + else if(mCCModbusState == SB_MODBUS_DISCONNECTED) + { + painter->setPen(Qt::red); + Text.clear(); + Text.sprintf("CC[Déconnecté]"); + TextRect.adjust(5,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + } + + if(mSEIModbusState == SB_MODBUS_CONNECTED) + { + painter->setPen(Qt::darkGreen); + Text.clear(); + Text.sprintf("SEI[Connecté]"); + TextRect.adjust(20,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + } + else if(mSEIModbusState == SB_MODBUS_DISCONNECTED) + { + painter->setPen(Qt::red); + Text.clear(); + Text.sprintf("SEI[Déconnecté]"); + TextRect.adjust(20,0,0,0); + painter->drawText(TextRect, Qt::AlignLeft, Text); + TextRect.adjust(painter->fontMetrics().width(Text),0,0,0); + } + } + +} + +unsigned int CStatusBar::SetNbPass(unsigned int Value) +{ + mNbTrainsPass = Value; + update(boundingRect()); + return RET_OK; +} + +unsigned int CStatusBar::SetNbTriggers(unsigned int Value) +{ + mNbTriggers = Value; + update(boundingRect()); + return RET_OK; +} + +unsigned int CStatusBar::SetZT1Status(unsigned int Status) +{ + mZT1Status = Status; + update(boundingRect()); + return RET_OK; +} + +unsigned int CStatusBar::SetZT2Status(unsigned int Status) +{ + mZT2Status = Status; + update(boundingRect()); + return RET_OK; +} + +unsigned int CStatusBar::SetCCModbusState(unsigned int State) +{ + mCCModbusState = State; + update(boundingRect()); + return RET_OK; +} +unsigned int CStatusBar::SetSEIModbusState(unsigned int State) +{ + mSEIModbusState = State; + update(boundingRect()); + return RET_OK; +} diff --git a/sources/GuiElements/StatusBar.h b/sources/GuiElements/StatusBar.h new file mode 100644 index 0000000..f4e7125 --- /dev/null +++ b/sources/GuiElements/StatusBar.h @@ -0,0 +1,71 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef STATUSBAR_H +#define STATUSBAR_H + +#include "GlobalDefine.h" +#include + +enum eZTStatus +{ + SB_ZT_ACTIVE_STATUS, + SB_ZT_INACTIVE_STATUS, + SB_ZT_NOT_PRESENT_STATUS, + SB_ZT_DISABLED_STATUS, + SB_ZT_MAX_STATUS +}; + +enum eModbusState +{ + SB_MODBUS_NOT_PRESENT, + SB_MODBUS_DISCONNECTED, + SB_MODBUS_CONNECTED +}; + +class CStatusBar : public QGraphicsWidget +{ + Q_OBJECT +public: + CStatusBar(QGraphicsItem *Parent = 0); + + void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + unsigned int SetZT1Status(unsigned int Status); + unsigned int SetZT2Status(unsigned int Status); + unsigned int SetNbPass(unsigned int Value); + unsigned int SetNbTriggers(unsigned int Value); + unsigned int SetCCModbusState(unsigned int State); + unsigned int SetSEIModbusState(unsigned int State); + +private: + QString mZT1StatusString, mZT2StatusString; + unsigned int mZT1Status, mZT2Status; + unsigned int mNbTrainsPass, mNbTriggers; + unsigned int mCCModbusState, mSEIModbusState; +}; + +#endif // STATUSBAR_H diff --git a/sources/GuiElements/SwitchCDVItem.cpp b/sources/GuiElements/SwitchCDVItem.cpp new file mode 100644 index 0000000..706bf37 --- /dev/null +++ b/sources/GuiElements/SwitchCDVItem.cpp @@ -0,0 +1,157 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Élément graphique qui affiche un CDV d'aiguillage. L'affichage change en fonction de l'état + du CDV (libre, occupé, itinéraire commandé) et de sa position (droite, renversée) + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130524 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SwitchCDVItem.h" +#include +#include "ZTData.h" +#include +#include "CDV.h" +#include "SwitchCDV.h" + +CSwitchCDVItem::CSwitchCDVItem(CCDV *CDVPtr,QGraphicsItem *Parent) + :CCDVItem(CDVPtr,Parent) +{ + mSwitchCDV = (CSwitchCDV*)CDVPtr; + mSwitchPosition = mSwitchCDV->GetSwitchState(); + + mNormalCDVRect = rect(); + mNormalPainterPath.addRect(rect()); + + + + + qreal nibble = rect().width()*0.25; + + int shim = 3; + int WaysSpascing = rect().height() + 10; + mReversedPainterPath.moveTo(0,pos().y()+WaysSpascing); + mReversedPainterPath.lineTo(nibble-shim,pos().y()+WaysSpascing); // -- + mReversedPainterPath.lineTo(rect().width()-nibble-shim,0); // / + mReversedPainterPath.lineTo(rect().width(),0); // -- + mReversedPainterPath.lineTo(rect().width(),rect().height()); // | + mReversedPainterPath.lineTo(rect().width()-nibble+shim,rect().height()); // __ + mReversedPainterPath.lineTo(nibble+shim,pos().y()+WaysSpascing+rect().height()); // / + mReversedPainterPath.lineTo(0,pos().y()+WaysSpascing+rect().height()); // __ + mReversedPainterPath.lineTo(0,pos().y()+WaysSpascing); // | + + + this->setGeometry(0,0,90,70); //Change geometry so we can draw the reversed switch + + + +} + +void CSwitchCDVItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + + painter->setBrush(*mCurBrush); + painter->setPen(Qt::black); + //painter->drawRect(CDVRect); + + if(mSwitchPosition == SWITCH_CDV_NORMAL_POSITION) + { + painter->drawPath(mNormalPainterPath); + } + else + { + painter->drawPath(mReversedPainterPath); + } + +// QRectF textRect(CDVRect.adjusted(-3,-3,-3,-3)); +// painter->drawRect(textRect); + + int flags = Qt::AlignHCenter | Qt::AlignVCenter/* | Qt::TextWordWrap*/; + + QFont font; +// font.setPointSizeF(9.5); + font.setPixelSize(13); + painter->setPen(Qt::black); + painter->setFont(font); + painter->drawText(mNormalCDVRect, flags, mCDVLabel); + +} + +unsigned int CSwitchCDVItem::SetState(unsigned int State) +{ + if(State >= CDV_STATE_UNKNOWN) + return RET_ERROR; + if(mCDVState == State) + return RET_OK; + + mCDVState = State; + switch(State) + { + case CDV_STATE_OCCUPIED: + { + mCurBrush = mCDVOccupiedBrush; + break; + } + case CDV_STATE_FREE: + { + mCurBrush = mCDVFreeBrush; + break; + } + case CDV_STATE_ITI_CMD: + { + mCurBrush = mCDVITICommandedBrush; + break; + } + } + + mSwitchPosition = mSwitchCDV->GetSwitchState(); + + + update(rect()); + + return RET_OK; +} + +//void CSwitchCDVItem::resizeEvent() +//{ +//// mNormalPainterPath = QPainterPath(); +//// mNormalPainterPath.addRect(rect()); +//// mReversedPainterPath = QPainterPath(); +//// mReversedPainterPath.addRect(rect()); +//} + +//void CSwitchCDVItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +//{ +// if(event->button() == Qt::LeftButton) +// { +// emit CDVRightClicked(this); +// } +//} + +//void CSwitchCDVItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +//{ +// Q_UNUSED(event) +//} + diff --git a/sources/GuiElements/SwitchCDVItem.h b/sources/GuiElements/SwitchCDVItem.h new file mode 100644 index 0000000..8bc820a --- /dev/null +++ b/sources/GuiElements/SwitchCDVItem.h @@ -0,0 +1,68 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "GlobalDefine.h" +#include +#include +#include "CDVItem.h" +#include + + +#ifndef SWITCHCDVITEM_H +#define SWITCHCDVITEM_H + +class CCDV; +class CSwitchCDV; + +class CSwitchCDVItem : public CCDVItem +{ + Q_OBJECT + +public: + CSwitchCDVItem(CCDV *CDVPtr,QGraphicsItem *Parent = 0); + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + unsigned int SetParameters(QString Label/*, unsigned int posx, unsigned int posy*/); + unsigned int SetState(unsigned int State); +// unsigned int UpdateState(); + +protected: +// virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); +// virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); +// virtual void resizeEvent(); + +private: + + CSwitchCDV *mSwitchCDV; + unsigned int mSwitchPosition; + QPainterPath mNormalPainterPath, mReversedPainterPath; + QRectF mNormalCDVRect; + +//signals: +// void CDVRightClicked(CCDVItem*); +}; + +#endif // SWITCHCDVITEM_H diff --git a/sources/GuiElements/TextButtonWidget.cpp b/sources/GuiElements/TextButtonWidget.cpp new file mode 100644 index 0000000..3072fc2 --- /dev/null +++ b/sources/GuiElements/TextButtonWidget.cpp @@ -0,0 +1,247 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Widget Bouton dans lequel est affiché du texte. Une image peut aussi être + affichée à l'intérieur du bouton. +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130306 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "TextButtonWidget.h" +#include +#include + +CTextButtonWidget::CTextButtonWidget(QString Text, int TextButtonData,int ButtonHeight,int ButtonWidth,int FontSize, QPixmap *ButtonImage) +{ + + if(ButtonImage) + { + mButtonImagePtr = ButtonImage; + } + else + mButtonImagePtr = 0; + + mIsPressed = false; + mWidgetText = Text; + mTextButtonData = TextButtonData; + mButtonHeight = ButtonHeight; + mBackgroundColor = QColor(245, 245, 255, 220); + + if(FontSize == 0) + mFontSize = mButtonHeight -10; + else + mFontSize = FontSize; + + //Fit widget size with text + + mTextFont.setPixelSize(mFontSize); + mTextFont.setBold(true); + + int IconOffset = 0; + QFontMetrics FontMetrics(mTextFont); + if(ButtonWidth == 0) + { + if(mButtonImagePtr != 0) + IconOffset = mButtonHeight + 5; + //mButtonWidth = FontMetrics.width(mWidgetText)+IconOffset + 10; + mButtonWidth = FontMetrics.boundingRect(mWidgetText).width()+IconOffset + 10; + } + else + mButtonWidth = ButtonWidth; + + resize(mButtonWidth,mButtonHeight); + + // setGeometry(0,0,TEXT_BUTTON_WIDGET_WIDTH,TEXT_BUTTON_WIDGET_HEIGHT); + setGeometry(0,0,rect().width(),rect().height()); + mIsSelected = false; + mWidgetOrigin.setX(0); + mWidgetOrigin.setY(0); + + mTimeLine = new QTimeLine(200,this); + mTimeLine->setCurveShape(QTimeLine::SineCurve); + connect(mTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(TimeLineEvent(qreal))); + + mButtonImagePtr = ButtonImage; + + //QRect WidgetRect(mWidgetOrigin.x(),mWidgetOrigin.y(),TEXT_BUTTON_WIDGET_WIDTH,TEXT_BUTTON_WIDGET_HEIGHT); + QRect WidgetRect(mWidgetOrigin.x(),mWidgetOrigin.y(),rect().width(),rect().height()); + +// QRectF textRect = WidgetRect.adjusted(5, 2, -2, -2); +// int flags = Qt::AlignVCenter | Qt::AlignLeft; + +} + +void CTextButtonWidget::CheckScrolling() +{ + int IconOffset = 0; + if(mButtonImagePtr != 0) + IconOffset = rect().height(); + + QFontMetrics FontMetrics(mTextFont); + if(FontMetrics.boundingRect(mWidgetText).width()+IconOffset > rect().width()) + { + mScrollingRequired = true; + mWidgetText.append(" "); + } + else + mScrollingRequired = false; +} + +void CTextButtonWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + PaintButtonWidget(painter,option,widget); +} +void CTextButtonWidget::PaintButtonWidget(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) +{ + Q_UNUSED(widget) + Q_UNUSED(option) +// painter->setOpacity(1); + if(mIsPressed) + painter->setPen(QPen(Qt::red, 2)); + else + painter->setPen(QPen(Qt::black, 2)); +// if(mIsAnimating) +// painter->setBrush(QColor(0, 50, 255, 220)); +// else + //painter->setBrush(QColor(245, 245, 255, 220)); + painter->setBrush(mBackgroundColor); + //QRect WidgetRect(mWidgetOrigin.x(),mWidgetOrigin.y(),TEXT_BUTTON_WIDGET_WIDTH,TEXT_BUTTON_WIDGET_HEIGHT); + QRect WidgetRect(mWidgetOrigin.x(),mWidgetOrigin.y(),rect().width(),rect().height()); + + //painter->drawRoundedRect(WidgetRect,10,10); + painter->drawRect(WidgetRect); + + QRectF textRect; + if(mButtonImagePtr) + textRect = WidgetRect.adjusted(rect().height() + 5, 2, -2, -2); //if there is an image, it will be square so text must begin at 5 + height of button (height determines size of image) + else + textRect = WidgetRect.adjusted(5, 2, -2, -2); + + int flags = Qt::AlignVCenter | Qt::AlignLeft; + +// QFont font; +// font.setPixelSize(mButtonHeight/2 - 10); +// font.setBold(true); + painter->setPen(QPen(Qt::black,1)); + painter->setFont(mTextFont); + painter->drawText(textRect, flags, mWidgetText); + + if(mButtonImagePtr) + { + painter->drawPixmap(WidgetRect.left(),WidgetRect.top(),mButtonImagePtr->scaled(rect().height(),rect().height())); + } + } + +void CTextButtonWidget::SetButtonImage(QPixmap *ButtonImage) +{ + if(ButtonImage != NULL) + { + mButtonImagePtr = ButtonImage; + update(rect()); + } +} + +void CTextButtonWidget::SetButtonText(QString ButtonText) +{ + mWidgetText = ButtonText; + update(rect()); +} + +void CTextButtonWidget::SetButtonPos(int x, int y) +{ + mWidgetOrigin.setX(x); + mWidgetOrigin.setY(y); +} + +void CTextButtonWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +// qDebug("Mouse pressed Text Button Widget"); +// mIsSelected = true; +// event->ignore(); +// update(); + +// qDebug("Mouse pressed Text Button Widget"); + mIsPressed = true; + update(rect()); + emit TxtButtonPressed(this); + // QGraphicsWidget::mousePressEvent(event); +} + +void CTextButtonWidget::SetBackgroundColor(QColor color) +{ + mBackgroundColor = color; + update(rect()); +} + +void CTextButtonWidget::mouseReleaseEvent( QGraphicsSceneMouseEvent * event) +{ + Q_UNUSED(event) +///* qDebug("Mouse released Text Button Widget"); +// mIsSelected = false; +// update(); +// if(isVisible()) +// emit clicked(this); +// event->ignore();*/ +// //qDebug("Start Timeline"); +// mIsAnimating = true; +// mTimeLine->start(); +// qDebug("Mouse released Text Button Widget"); + mIsPressed = false; + update(rect()); + emit TxtButtonReleased(this); + +// qDebug("Text Button Widget clicked"); + emit TxtButtonClicked(this); + + // QGraphicsWidget::mouseReleaseEvent(event); +} + +//void CTextButtonWidget::ButtonClicked() +//{ +// mIsSelected = false; +// qDebug("A button is clicked"); +//} + +void CTextButtonWidget::TimeLineEvent(qreal value) +{ + Q_UNUSED(value) +//// ClickTransparency = 255*value; + +// update(); + +// if(value == 0) +// { +// mIsAnimating = false; +// emit clicked(this); +// } +} + +void CTextButtonWidget::TickScrollingText() +{ + if(mScrollingRequired && isVisible()) + { + QChar Character = mWidgetText.at(mSongNameIndex); + mWidgetText.remove(mSongNameIndex,1); + mWidgetText.append(Character); + update(); + } +} diff --git a/sources/GuiElements/TextButtonWidget.h b/sources/GuiElements/TextButtonWidget.h new file mode 100644 index 0000000..e5d645a --- /dev/null +++ b/sources/GuiElements/TextButtonWidget.h @@ -0,0 +1,61 @@ +#ifndef TEXTBUTTONWIDGET_H +#define TEXTBUTTONWIDGET_H + +#include +#include +#include + +#define TEXT_BUTTON_WIDGET_WIDTH 280 +#define TEXT_BUTTON_WIDGET_HEIGHT 25 + +class CTextButtonWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CTextButtonWidget(QString Text, int TextButtonData = 0,int ButtonHeight = TEXT_BUTTON_WIDGET_HEIGHT,int ButtonWidth = 0,int FontSize = 0,QPixmap *ButtonImage = 0); + + QString mWidgetText; + QString mDisplayText; + int mTextButtonData; + bool mIsSelected; + QRectF mButtonsAreaWindow; + QTimeLine *mTimeLine; + bool mIsPressed; + bool mScrollingRequired; + qreal ClickTransparency; + int mSongNameIndex; + QPixmap *mButtonImagePtr; + unsigned int mButtonHeight; + unsigned int mButtonWidth; + unsigned int mFontSize; + QColor mBackgroundColor; + QFont mTextFont; + + void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + void SetButtonPos(int x, int y); + void PaintButtonWidget(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + void SetButtonImage(QPixmap *ButtonImage); + void SetButtonText(QString ButtonText); + void SetBackgroundColor(QColor color); + void CheckScrolling(void); + + + QPoint mWidgetOrigin; + + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + void ButtonClicked(void); + + public slots: + void TimeLineEvent(qreal value); + void TickScrollingText(); + + signals: + void TxtButtonClicked(CTextButtonWidget *TextButtonPtr); + void TxtButtonPressed(CTextButtonWidget *TextButtonPtr); + void TxtButtonReleased(CTextButtonWidget *TextButtonPtr); + + +}; + +#endif // TEXTBUTTONWIDGET_H diff --git a/sources/GuiElements/ToggleButtonWidget.cpp b/sources/GuiElements/ToggleButtonWidget.cpp new file mode 100644 index 0000000..9cde45b --- /dev/null +++ b/sources/GuiElements/ToggleButtonWidget.cpp @@ -0,0 +1,130 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Widget Bouton de style "toggle" qui affiche une image lorsqu'il est désactivé + et une autre image lorsqu'il est activé. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130306 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ToggleButtonWidget.h" +#include +#include + +CToggleButtonWidget::CToggleButtonWidget(QString ONImageFilePath, QString OFFImageFilePath,QGraphicsItem *Parent, QString Label) +{ + setParentItem(Parent); + mButtonState = TOGGLE_BUTTON_OFF; + + mONPixmap = new QGraphicsPixmapItem(QPixmap(ONImageFilePath), this); + mONPixmap->hide(); + mOFFPixmap = new QGraphicsPixmapItem(QPixmap(OFFImageFilePath), this); + mOFFPixmap->show(); + + mButtonEnabled = true; + mButtonData = 0; + + if(Label.isEmpty() == false) + { + QGraphicsTextItem *BtnLabel = new QGraphicsTextItem(this); + BtnLabel->setPlainText(Label); + BtnLabel->adjustSize(); + BtnLabel->setPos(-BtnLabel->boundingRect().width()-3,0); + } +} + + +void CToggleButtonWidget::SetData(unsigned int data) +{ + mButtonData = data; +} +unsigned int CToggleButtonWidget::GetData() +{ + return mButtonData; +} + +void CToggleButtonWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} + +void CToggleButtonWidget::mouseReleaseEvent( QGraphicsSceneMouseEvent * event) +{ + Q_UNUSED(event) + + if(mButtonEnabled == false) + return ; + + if(mButtonState == TOGGLE_BUTTON_ON) + mButtonState = TOGGLE_BUTTON_OFF; + else + mButtonState = TOGGLE_BUTTON_ON; + + UpdateButton(); + emit ButtonToggled(this); +} + +void CToggleButtonWidget::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + + + mONPixmap->setPixmap(mONPixmap->pixmap().scaled(boundingRect().width(),boundingRect().height())); + mOFFPixmap->setPixmap(mOFFPixmap->pixmap().scaled(boundingRect().width(),boundingRect().height())); +} + +unsigned int CToggleButtonWidget::GetButtonState() +{ + return mButtonState; +} + +unsigned int CToggleButtonWidget::SetButtonEnabled(bool Enabled) +{ + mButtonEnabled = Enabled; + return RET_OK; +} + +unsigned int CToggleButtonWidget::SetButtonState(unsigned int State) +{ + if(mButtonState != TOGGLE_BUTTON_OFF && mButtonState != TOGGLE_BUTTON_ON) + return RET_ERROR; + + mButtonState = State; + UpdateButton(); + + return RET_OK; +} + + +void CToggleButtonWidget::UpdateButton() +{ + if(mButtonState == TOGGLE_BUTTON_OFF) + { + mOFFPixmap->show(); + mONPixmap->hide(); + } + else + { + mOFFPixmap->hide(); + mONPixmap->show(); + } +} diff --git a/sources/GuiElements/ToggleButtonWidget.h b/sources/GuiElements/ToggleButtonWidget.h new file mode 100644 index 0000000..af6101e --- /dev/null +++ b/sources/GuiElements/ToggleButtonWidget.h @@ -0,0 +1,47 @@ +#ifndef TOGGLEBUTTONWIDGET_H +#define TOGGLEBUTTONWIDGET_H + + +#include "GlobalDefine.h" +#include +#include +#include + +#define TOGGLE_BUTTON_ON 1 +#define TOGGLE_BUTTON_OFF 0 + +class CToggleButtonWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CToggleButtonWidget(QString ONImageFilePath, QString OFFImageFilePath,QGraphicsItem *Parent,QString Label = QString()); + + + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + + QGraphicsPixmapItem *mONPixmap, *mOFFPixmap; + + unsigned int GetButtonState(); + unsigned int SetButtonState(unsigned int State); + unsigned int SetButtonEnabled(bool Enabled); + void SetData(unsigned int data); + unsigned int GetData(); + +private: + unsigned int mButtonState; + bool mButtonEnabled; + unsigned int mButtonData; + + void UpdateButton(); + + + + signals: + void ButtonToggled(CToggleButtonWidget*); + + +}; + +#endif // TOGGLEBUTTONWIDGET_H diff --git a/sources/GuiElements/ToggleButtonWidget.h.autosave b/sources/GuiElements/ToggleButtonWidget.h.autosave new file mode 100644 index 0000000..eed7f2d --- /dev/null +++ b/sources/GuiElements/ToggleButtonWidget.h.autosave @@ -0,0 +1,47 @@ +#ifndef TOGGLEBUTTONWIDGET_H +#define TOGGLEBUTTONWIDGET_H + + +#include "GlobalDefine.h" +#include +#include +#include + +#define TOGGLE_BUTTON_ON 1 +#define TOGGLE_BUTTON_OFF 0 + +class CToggleButtonWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CToggleButtonWidget(QString ONImageFilePath, QString OFFImageFilePath,QGraphicsItem *Parent,QString Label = QString()); + + + virtual void mousePressEvent ( QGraphicsSceneMouseEvent * event ); + virtual void mouseReleaseEvent( QGraphicsSceneMouseEvent * event); + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + + QGraphicsPixmapItem *mONPixmap, *mOFFPixmap; + + unsigned int GetButtonState(); + unsigned int SetButtonState(unsigned int State); + unsigned int SetButtonEnabled(bool Enabled); + void SetData(unsigned int data); + unsigned int GetData(); + +private: + unsigned int mButtonState; + bool mButtonEnabled; + unsigned int mButtonData; +l + void UpdateButton(); + + + + signals: + void ButtonToggled(CToggleButtonWidget*); + + +}; + +#endif // TOGGLEBUTTONWIDGET_H diff --git a/sources/GuiElements/ToggleTextButtonWidget.cpp b/sources/GuiElements/ToggleTextButtonWidget.cpp new file mode 100644 index 0000000..2fc3987 --- /dev/null +++ b/sources/GuiElements/ToggleTextButtonWidget.cpp @@ -0,0 +1,105 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + . + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130306 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "TextButtonWidget.h" +#include +#include + +CToggleTextButtonWidget::CToggleTextButtonWidget(QString ActivatedText, QString DeActivatedText, QPixmap ActivatedButtonImage, QPixmap DeActivatedButtonImage, int ButtonHeight,int ButtonWidth,int FontSize, int ToggleTextButtonData) +{ + mButtonState = false; + mActivatedBtnText = ActivatedText; + mDeActivatedButtonText = DeActivatedText; + mActivatedBtnImage = ActivatedButtonImage; + mDeActivatedBtnImage = DeActivatedButtonImage; + mButtonHeight = ButtonHeight; + mButtonData = ToggleTextButtonData; + + if(mDeActivatedBtnImage.isNull()) + mTextButton = new CTextButtonWidget(DeActivatedText,mButtonData,mButtonHeight,ButtonWidth,FontSize,0); + else + mTextButton = new CTextButtonWidget(DeActivatedText,mButtonData,mButtonHeight,ButtonWidth,FontSize,&mDeActivatedBtnImage); + connect(mTextButton, SIGNAL(TxtButtonClicked(CTextButtonWidget *)), this, SLOT(ChildTextButtonClicked(CTextButtonWidget *))); + + setGeometry(mTextButton->rect()); + mTextButton->setParentItem(this); +} +CToggleTextButtonWidget::~CToggleTextButtonWidget() +{ + delete mTextButton; +} + +void CToggleTextButtonWidget::ChildTextButtonClicked(CTextButtonWidget *TextButtonPtr) +{ + Q_UNUSED(TextButtonPtr) + + if(mButtonState) + { + if(!mDeActivatedBtnImage.isNull()) + mTextButton->SetButtonImage(&mDeActivatedBtnImage); + + mTextButton->SetButtonText(mDeActivatedButtonText); + mTextButton->SetBackgroundColor(QColor(245, 245, 255, 220)); + mButtonState = false; + emit ToggleBtnDeActivate(this); + } + else + { + if(!mActivatedBtnImage.isNull()) + mTextButton->SetButtonImage(&mActivatedBtnImage); + + mTextButton->SetButtonText(mActivatedBtnText); + mTextButton->SetBackgroundColor(Qt::green); + mButtonState = true; + emit ToggleBtnActivate(this); + } +} + +void CToggleTextButtonWidget::ForceActivation(bool Emit) +{ + if(!mActivatedBtnImage.isNull()) + mTextButton->SetButtonImage(&mActivatedBtnImage); + + mTextButton->SetButtonText(mActivatedBtnText); + mTextButton->SetBackgroundColor(Qt::green); + mButtonState = true; + + if(Emit == true) + emit ToggleBtnActivate(this); +} +void CToggleTextButtonWidget::ForceDeactivation(bool Emit) +{ + if(!mDeActivatedBtnImage.isNull()) + mTextButton->SetButtonImage(&mDeActivatedBtnImage); + + mTextButton->SetButtonText(mDeActivatedButtonText); + mTextButton->SetBackgroundColor(QColor(245, 245, 255, 220)); + mButtonState = false; + + if(Emit == true) + emit ToggleBtnDeActivate(this); +} diff --git a/sources/GuiElements/ToggleTextButtonWidget.h b/sources/GuiElements/ToggleTextButtonWidget.h new file mode 100644 index 0000000..c85f98a --- /dev/null +++ b/sources/GuiElements/ToggleTextButtonWidget.h @@ -0,0 +1,44 @@ +#ifndef TOGGLETEXTBUTTONWIDGET_H +#define TOGGLETEXTBUTTONWIDGET_H + +#include +#include +#include +#include "TextButtonWidget.h" + +#define TOGGLE_TEXT_BUTTON_WIDGET_WIDTH 280 +#define TOGGLE_TEXT_BUTTON_WIDGET_HEIGHT 25 + +class CToggleTextButtonWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CToggleTextButtonWidget(QString ActivatedText,QString DeActivatedText, + QPixmap ActivatedButtonImage,QPixmap DeActivatedButtonImage, + int ButtonHeight = TOGGLE_TEXT_BUTTON_WIDGET_HEIGHT,int ButtonWidth = 0,int FontSize = 0, int ToggleTextButtonData = 0); + virtual ~CToggleTextButtonWidget(); + + void ForceDeactivation(bool Emit = false); + void ForceActivation(bool Emit = false); + bool GetActivationState(){return mButtonState;} + + public slots: + void ChildTextButtonClicked(CTextButtonWidget *TextButtonPtr); +// void TxtButtonPressed(CTextButtonWidget *TextButtonPtr); +// void TxtButtonReleased(CTextButtonWidget *TextButtonPtr); + + signals: + void ToggleBtnActivate(CToggleTextButtonWidget* ButtonInstancePtr); + void ToggleBtnDeActivate(CToggleTextButtonWidget* ButtonInstancePtr); + +private: + CTextButtonWidget *mTextButton; + QString mActivatedBtnText,mDeActivatedButtonText; + QPixmap mActivatedBtnImage,mDeActivatedBtnImage; + unsigned int mButtonHeight,mButtonWidth; + int mButtonData; + bool mButtonState; //false = deactivated(up), true = activated (down) + +}; + +#endif // TOGGLETEXTBUTTONWIDGET_H diff --git a/sources/GuiElements/WelcomePage.cpp b/sources/GuiElements/WelcomePage.cpp new file mode 100644 index 0000000..e673a3d --- /dev/null +++ b/sources/GuiElements/WelcomePage.cpp @@ -0,0 +1,62 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page qui est affichée lors du démarrage de l'application. Elle affiche tout + simplement un message à l'utilisateur. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "WelcomePage.h" +#include +#include "GlobalDefine.h" +#include "QCoreApplication" + + + +CWelcomePage::CWelcomePage(QGraphicsWidget *Parent) +{ + Q_UNUSED(Parent) + setGeometry(0,0,SCREEN_RES_WIDTH,SCREEN_RES_HEIGHT); + + mTextBoxWidget.setParentItem(this); + + CEngLog::instance()->AddLogString("CWelcomePage::CWelcomePage. CWelcomePage créée avec succès",2); + +} + +void CWelcomePage::InsertTextBoxString(QString string) +{ + mTextBoxWidget.InsertString(string); + QCoreApplication::processEvents(); +} + +void CWelcomePage::ClearTextBoxWidget() +{ + mTextBoxWidget.ClearText(); +} + +void CWelcomePage::ShowTextboxWidget() +{ + mTextBoxWidget.ShowTextBox(); +} diff --git a/sources/GuiElements/WelcomePage.h b/sources/GuiElements/WelcomePage.h new file mode 100644 index 0000000..43a2d68 --- /dev/null +++ b/sources/GuiElements/WelcomePage.h @@ -0,0 +1,58 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef WELCOMEPAGE_H +#define WELCOMEPAGE_H + +#include +#include "Guipage.h" +#include +#include "SimpleTextBoxWidget.h" + + + +class CWelcomePage : public CGuiPage +{ +Q_OBJECT +public: + CWelcomePage(QGraphicsWidget *Parent = 0); + + + void ClearTextBoxWidget(void); + void InsertTextBoxString(QString string); + void ShowTextboxWidget(); + +private: + CSimpleTextBoxWidget mTextBoxWidget; + + + + +}; + +#endif // WELCOMEPAGE_H diff --git a/sources/GuiElements/ZT1EquipmentWidget.cpp b/sources/GuiElements/ZT1EquipmentWidget.cpp new file mode 100644 index 0000000..0fa6889 --- /dev/null +++ b/sources/GuiElements/ZT1EquipmentWidget.cpp @@ -0,0 +1,155 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Élément graphique qui affiche les équipements de la ZT1. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZT1EquipmentWidget.h" +#include + +CZT1EquipmentWidget::CZT1EquipmentWidget(QGraphicsItem *Parent) +{ + setParentItem(Parent); + setGeometry(0,0,320,180); + + QFont LabelFont; + LabelFont.setPointSize(20); + mZT1Label = new QGraphicsTextItem(this); + mZT1Label->setFont(LabelFont); + mZT1Label->setPlainText("ZT1 - Avant Gare"); + mZT1Label->setPos(boundingRect().x()+(boundingRect().width()/2 - mZT1Label->boundingRect().width()/2),boundingRect().bottom()+10); + + + mS1Activated = mS2Activated = mFNActivated = mPPEActivated = mPPIActivated = mPGEActivated = mPGIActivated = false; + mZT1Active = true; + + mFNRect1.setRect(0,50,boundingRect().width(),10); + mFNRect2.setRect(0,boundingRect().bottom()-50,boundingRect().width(),10); + + mPGERect.setRect(boundingRect().width()/2-10,10,20,20); + mPGIRect.setRect(boundingRect().width()/2-10,boundingRect().bottom()-20,20,20); + + mPPERect.setRect(boundingRect().width()-50,65,10,20); + mPPIRect.setRect(boundingRect().width()-50,boundingRect().bottom() - 75,10,20); + + mS1Rect.setRect(boundingRect().right()-30,boundingRect().bottom()-30,30,20); + mS2Rect.setRect(0,boundingRect().bottom()-30,30,20); + + + mRedBrush = new QBrush(Qt::red); + mGreenBrush = new QBrush(Qt::darkGreen); + mHashedBrush = new QBrush(Qt::darkGray/*,Qt::Dense2Pattern*/); +} + +void CZT1EquipmentWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) +// static int toto = 0; +// qDebug("CZT1EquipmentWidget::paint %d",toto++); + + if(mZT1Active == false) + { + painter->fillRect(mFNRect1,*mHashedBrush); + painter->fillRect(mFNRect2,*mHashedBrush); + painter->fillRect(mPGERect,*mHashedBrush); + painter->fillRect(mPGIRect,*mHashedBrush); + painter->fillRect(mS1Rect,*mHashedBrush); + painter->fillRect(mS2Rect,*mHashedBrush); + painter->fillRect(mPPERect,*mHashedBrush); + painter->fillRect(mPPIRect,*mHashedBrush); + } + else + { + QBrush *brush; + + if(mS1Activated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mS1Rect,*brush); + + if(mS2Activated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mS2Rect,*brush); + + if(mPGEActivated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mPGERect,*brush); + + if(mPGIActivated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mPGIRect,*brush); + + if(mPPEActivated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mPPERect,*brush); + + if(mPPIActivated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mPPIRect,*brush); + + if(mFNActivated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mFNRect1,*brush); + painter->fillRect(mFNRect2,*brush); + + + } +} + +unsigned int CZT1EquipmentWidget::SetState(bool S1, bool S2, bool FN, bool PI, bool PE, bool PPI, bool PPE) +{ + mS1Activated = S1; + mS2Activated = S2; + mFNActivated = FN; + mPGIActivated = PI; + mPGEActivated = PE; + mPPIActivated = PPI; + mPPEActivated = PPE; + + update(); + + return RET_OK; +} + +unsigned int CZT1EquipmentWidget::SetActivation(bool IsActive) +{ + mZT1Active = IsActive; + update(); + + return RET_OK; +} diff --git a/sources/GuiElements/ZT1EquipmentWidget.h b/sources/GuiElements/ZT1EquipmentWidget.h new file mode 100644 index 0000000..b47603a --- /dev/null +++ b/sources/GuiElements/ZT1EquipmentWidget.h @@ -0,0 +1,52 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZT1EQUIPMENTWIDGET_H +#define ZT1EQUIPMENTWIDGET_H +#include "GlobalDefine.h" +#include +#include + +class CZT1EquipmentWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CZT1EquipmentWidget(QGraphicsItem *parent = 0); + + void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + unsigned int SetState(bool S1, bool S2, bool FN, bool PI, bool PE,bool PPI,bool PPE); + unsigned int SetActivation(bool IsZT1Active); + QGraphicsTextItem *mZT1Label; + +private: + bool mS1Activated,mS2Activated,mFNActivated,mPGEActivated,mPGIActivated,mZT1Active,mPPIActivated,mPPEActivated; + + QRectF mS1Rect,mS2Rect,mFNRect1,mFNRect2,mPGERect,mPGIRect,mPPERect,mPPIRect; + QBrush *mGreenBrush, *mRedBrush, *mHashedBrush; +}; + +#endif // ZT1EQUIPMENTWIDGET_H diff --git a/sources/GuiElements/ZT1StatsZone.cpp b/sources/GuiElements/ZT1StatsZone.cpp new file mode 100644 index 0000000..5ddc997 --- /dev/null +++ b/sources/GuiElements/ZT1StatsZone.cpp @@ -0,0 +1,208 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Zone de texte qui affiche les statistiques de passage d'un train dans la ZT1 + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + + + + + +#include "ZT1StatsZone.h" + +CZT1StatsZone::CZT1StatsZone(QGraphicsItem *Parent) +{ + setParentItem(Parent); + + QFont font; + //font.setPixelSize(15); + font.setPointSize(15); + + mTrainSpeedText = new QGraphicsTextItem(this); + mTrainSpeedText->setPos(0,12); +// mTrainSpeedText->setPlainText("Vitesse du train: 0"); + mTrainSpeedText->setFont(font); + + mBogieCountText = new QGraphicsTextItem(this); + mBogieCountText->setPos(0,34); +// mBogieCountText->setPlainText("Compte Bogie: 0"); + mBogieCountText->setFont(font); + + mS1CountText = new QGraphicsTextItem(this); + mS1CountText->setPos(0,56); +// mS1CountText->setPlainText("Compte S1: 0"); + mS1CountText->setFont(font); + + mS2CountText = new QGraphicsTextItem(this); + mS2CountText->setPos(0,78); +// mS2CountText->setPlainText("Compte S2: 0"); + mS2CountText->setFont(font); + + mFNCountText = new QGraphicsTextItem(this); + mFNCountText->setPos(0,100); +// mFNCountText->setPlainText("Compte FN: 0"); + mFNCountText->setFont(font); + + mActualRankText = new QGraphicsTextItem(this); + mActualRankText->setPos(0,122); +// mActualRankText->setPlainText("Rang: 0"); + mActualRankText->setFont(font); + + mTrainTypeText = new QGraphicsTextItem(this); + mTrainTypeText->setPos(0,144); +// mTrainTypeText->setPlainText("Train Détecté: Aucun"); + mTrainTypeText->setFont(font); + + mPIValueText = new QGraphicsTextItem(this); + mPIValueText->setPos(0,166); +// mTrainTypeText->setPlainText("Train Détecté: Aucun"); + mPIValueText->setFont(font); + + mPEValueText = new QGraphicsTextItem(this); + mPEValueText->setPos(0,188); + // mTrainTypeText->setPlainText("Train Détecté: Aucun"); + mPEValueText->setFont(font); + + + mLastActivationDateTime = new QGraphicsTextItem(this); + mLastActivationDateTime->setPos(0,210); + mLastActivationDateTime->setFont(font); + mLastActivationDateTime->setPlainText("Dernier passage : "); + + Reset(); + +} + +unsigned int CZT1StatsZone::UpdateStats(CZT1ThreadData *DataPtr) +{ + QString temp; + + if(mBogieCount != DataPtr->mBogie) + { + mBogieCount = DataPtr->mBogie; + temp.clear(); + temp.sprintf("Compte Bogie: %d",mBogieCount); + mBogieCountText->setPlainText(temp); + } + + if(mS1Count != DataPtr->mS1Count) + { + mS1Count = DataPtr->mS1Count; + temp.clear(); + temp.sprintf("Compte S1: %d",mS1Count); + mS1CountText->setPlainText(temp); + } + + if(mS2Count != DataPtr->mS2Count) + { + mS2Count = DataPtr->mS2Count; + temp.clear(); + temp.sprintf("Compte S2: %d",mS2Count); + mS2CountText->setPlainText(temp); + } + + if(mFNCount != DataPtr->mFNCount) + { + mFNCount = DataPtr->mFNCount; + temp.clear(); + temp.sprintf("Compte FN: %d",mFNCount); + mFNCountText->setPlainText(temp); + } + + if(mActualRank != DataPtr->mRank) + { + mActualRank = DataPtr->mRank; + temp.clear(); + temp.sprintf("Rang: %d",mActualRank); + mActualRankText->setPlainText(temp); + } + + + if(mTrainSpeed != DataPtr->mTrainSpeed) + { + mTrainSpeed = DataPtr->mTrainSpeed; + temp.clear(); + temp.sprintf("Vitesse du train: %.2f Mph",mTrainSpeed); + mTrainSpeedText->setPlainText(temp); + } + + if(mTrainType != DataPtr->mTrainType) + { + mTrainType = DataPtr->mTrainType; + temp.clear(); + temp = "Train détecté: "; + temp += CZTData::GetTrainTypeString(mTrainType); + mTrainTypeText->setPlainText(temp); + } + if(mPIValue != DataPtr->mPGIntValue) + { + mPIValue = DataPtr->mPGIntValue; + temp.clear(); + temp = "Train détecté: "; + temp.sprintf("Pneu Guidage Int.: %i",mPIValue); + mPIValueText->setPlainText(temp); + } + if(mPEValue != DataPtr->mPGExtValue) + { + mPEValue = DataPtr->mPGExtValue; + temp.clear(); + temp = "Train détecté: "; + temp.sprintf("Pneu Guidage Ext.: %i",mPEValue); + mPEValueText->setPlainText(temp); + } + + + return RET_OK; + + +} + +unsigned int CZT1StatsZone::SetLastActivationDateTime() +{ + QString txt = "Dernier passage: "; + txt += QDateTime::currentDateTime().toString("yyyy/MM/dd - hh:mm:ss"); + mLastActivationDateTime->setPlainText(txt); + return RET_OK; +} + +unsigned int CZT1StatsZone::Reset() +{ + mBogieCount = mS1Count = mS2Count = mFNCount = mActualRank = mActualBogie = mTrainType = 0; + mTrainSpeed = 0.0; + mPEValue = 0; + mPIValue = 0; + + mTrainSpeedText->setPlainText("Vitesse du train: 0"); + mBogieCountText->setPlainText("Compte Bogie: 0"); + mS1CountText->setPlainText("Compte S1: 0"); + mS2CountText->setPlainText("Compte S2: 0"); + mFNCountText->setPlainText("Compte FN: 0"); + mActualRankText->setPlainText("Rang: 0"); + mTrainTypeText->setPlainText("Train Détecté: Aucun"); + mPIValueText->setPlainText("Pneu Guidage Int.: ?"); + mPEValueText->setPlainText("Pneu Guidage Ext.: ?"); + + return RET_OK; +} diff --git a/sources/GuiElements/ZT1StatsZone.h b/sources/GuiElements/ZT1StatsZone.h new file mode 100644 index 0000000..04769c3 --- /dev/null +++ b/sources/GuiElements/ZT1StatsZone.h @@ -0,0 +1,54 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZT1STATSZONE_H +#define ZT1STATSZONE_H +#include "GlobalDefine.h" +#include +#include +#include "ZTData.h" + +class CZT1StatsZone : public QGraphicsWidget +{ + Q_OBJECT +public: + CZT1StatsZone(QGraphicsItem *Parent); + +// unsigned int UpdateStats(unsigned int BogieCount, unsigned int S1Count, unsigned int S2Count, unsigned int FNCount, unsigned int Rank, unsigned int Bogie, unsigned int TrainType, float TrainSpeed); + unsigned int UpdateStats(CZT1ThreadData *DataPtr); + unsigned int Reset(); + unsigned int SetLastActivationDateTime(); + +private: + unsigned int mBogieCount,mS1Count,mS2Count,mFNCount,mActualRank,mActualBogie,mTrainType; + float mTrainSpeed; + int mPIValue, mPEValue; + + QGraphicsTextItem *mTrainSpeedText, *mBogieCountText, *mS1CountText, *mS2CountText, *mFNCountText, *mActualRankText, *mActualBogieText, *mTrainTypeText, *mPIValueText, *mPEValueText, *mLastActivationDateTime; +}; + +#endif // ZT1STATSZONE_H diff --git a/sources/GuiElements/ZT2EquipmentWidget.cpp b/sources/GuiElements/ZT2EquipmentWidget.cpp new file mode 100644 index 0000000..f48dd5b --- /dev/null +++ b/sources/GuiElements/ZT2EquipmentWidget.cpp @@ -0,0 +1,115 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Élément graphique qui affiche les équipements de la ZT2. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZT2EquipmentWidget.h" +#include + +CZT2EquipmentWidget::CZT2EquipmentWidget(QGraphicsItem *Parent) +{ + setParentItem(Parent); + setGeometry(0,0,200,180); + + QFont LabelFont; + LabelFont.setPointSize(20); + mZT2Label = new QGraphicsTextItem(this); + mZT2Label->setFont(LabelFont); + mZT2Label->setPlainText("ZT2 - Arrière Gare"); + mZT2Label->setPos(boundingRect().x()+(boundingRect().width()/2 - mZT2Label->boundingRect().width()/2),boundingRect().bottom()+10); + + mS1Activated = mPPEActivated = mPPIActivated = false; + mZT2Active = false; + + mRailRect1.setRect(0,50,boundingRect().width(),10); + mRailRect2.setRect(0,boundingRect().bottom()-50,boundingRect().width(),10); + mPPERect.setRect(60,65,10,20); + mPPIRect.setRect(60,boundingRect().bottom() - 75,10,20); + + mS1Rect.setRect(boundingRect().right()-60,boundingRect().bottom()-30,30,20); + + mRedBrush = new QBrush(Qt::red); + mGreenBrush = new QBrush(Qt::darkGreen); + mHashedBrush = new QBrush(Qt::darkGray/*,Qt::Dense2Pattern*/); +} + +void CZT2EquipmentWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option) + Q_UNUSED(widget) + + if(mZT2Active == false) + { + painter->fillRect(mS1Rect,*mHashedBrush); + painter->fillRect(mPPERect,*mHashedBrush); + painter->fillRect(mPPIRect,*mHashedBrush); + painter->fillRect(mRailRect1,*mHashedBrush); + painter->fillRect(mRailRect2,*mHashedBrush); + } + else + { + QBrush *brush; + + painter->fillRect(mRailRect1,*mGreenBrush); + painter->fillRect(mRailRect2,*mGreenBrush); + + if(mS1Activated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mS1Rect,*brush); + + if(mPPEActivated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mPPERect,*brush); + + if(mPPIActivated) + brush = mRedBrush; + else + brush = mGreenBrush; + painter->fillRect(mPPIRect,*brush); + + } +} + +unsigned int CZT2EquipmentWidget::SetState(bool S1,bool PPI, bool PPE) +{ + mS1Activated = S1; + mPPIActivated = PPI; + mPPEActivated = PPE; + + update(); + + return RET_OK; +} + +unsigned int CZT2EquipmentWidget::SetActivation(bool IsActive) +{ + mZT2Active = IsActive; + update(); + return RET_OK; +} diff --git a/sources/GuiElements/ZT2EquipmentWidget.h b/sources/GuiElements/ZT2EquipmentWidget.h new file mode 100644 index 0000000..a2a2a42 --- /dev/null +++ b/sources/GuiElements/ZT2EquipmentWidget.h @@ -0,0 +1,53 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131101 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZT2EQUIPMENTWIDGET_H +#define ZT2EQUIPMENTWIDGET_H +#include "GlobalDefine.h" +#include +#include + +class CZT2EquipmentWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + CZT2EquipmentWidget(QGraphicsItem *parent = 0); + + void paint( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); + unsigned int SetState(bool S1,bool PPI,bool PPE); + unsigned int SetActivation(bool IsZT2Active); + +private: + bool mS1Activated,mZT2Active,mPPIActivated,mPPEActivated; + + QGraphicsTextItem *mZT2Label; + + QRectF mS1Rect,mPPERect,mPPIRect,mRailRect1,mRailRect2; + QBrush *mGreenBrush, *mRedBrush, *mHashedBrush; +}; + +#endif // ZT2EQUIPMENTWIDGET_H diff --git a/sources/GuiElements/ZT2StatsZone.cpp b/sources/GuiElements/ZT2StatsZone.cpp new file mode 100644 index 0000000..ca1d48b --- /dev/null +++ b/sources/GuiElements/ZT2StatsZone.cpp @@ -0,0 +1,119 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Zone de texte qui affiche les statistiques de passage d'un train dans la ZT2. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131104 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + + + + + +#include "ZT2StatsZone.h" + +CZT2StatsZone::CZT2StatsZone(QGraphicsItem *Parent) +{ + setParentItem(Parent); + + QFont font; + //font.setPixelSize(15); + font.setPointSize(15); + + mBogieCountText = new QGraphicsTextItem(this); + mBogieCountText->setPos(0,12); +// mBogieCountText->setPlainText("Compte Bogie: 0"); + mBogieCountText->setFont(font); + + mS1CountText = new QGraphicsTextItem(this); + mS1CountText->setPos(0,34); +// mS1CountText->setPlainText("Compte S1: 0"); + mS1CountText->setFont(font); + + mActualRankText = new QGraphicsTextItem(this); + mActualRankText->setPos(0,56); +// mActualRankText->setPlainText("Rang: 0"); + mActualRankText->setFont(font); + + mLastActivationDateTime = new QGraphicsTextItem(this); + mLastActivationDateTime->setPos(0,78); + mLastActivationDateTime->setFont(font); + mLastActivationDateTime->setPlainText("Dernier passage : "); + + Reset(); + +} + +unsigned int CZT2StatsZone::SetLastActivationDateTime() +{ + QString txt = "Dernier passage: "; + txt += QDateTime::currentDateTime().toString("yyyy/MM/dd - hh:mm:ss"); + mLastActivationDateTime->setPlainText(txt); + return RET_OK; +} + +unsigned int CZT2StatsZone::UpdateStats(CZT2ThreadData *DataPtr) +{ + QString temp; + + if(mBogieCount != DataPtr->mBogie) + { + mBogieCount = DataPtr->mBogie; + temp.clear(); + temp.sprintf("Compte Bogie: %d",mBogieCount); + mBogieCountText->setPlainText(temp); + } + + if(mS1Count != DataPtr->mS1Count) + { + mS1Count = DataPtr->mS1Count; + temp.clear(); + temp.sprintf("Compte S1: %d",mS1Count); + mS1CountText->setPlainText(temp); + } + + if(mActualRank != DataPtr->mRank) + { + mActualRank = DataPtr->mRank; + temp.clear(); + temp.sprintf("Rang: %d",mActualRank); + mActualRankText->setPlainText(temp); + } + + + return RET_OK; + + +} + +unsigned int CZT2StatsZone::Reset() +{ + mBogieCount = mS1Count = mActualRank = 0; + + mBogieCountText->setPlainText("Compte Bogie: 0"); + mS1CountText->setPlainText("Compte S1: 0"); + mActualRankText->setPlainText("Rang: 0"); + + + return RET_OK; +} diff --git a/sources/GuiElements/ZT2StatsZone.h b/sources/GuiElements/ZT2StatsZone.h new file mode 100644 index 0000000..1e6dab7 --- /dev/null +++ b/sources/GuiElements/ZT2StatsZone.h @@ -0,0 +1,53 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131104 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZT2STATSZONE_H +#define ZT2STATSZONE_H +#include "GlobalDefine.h" +#include +#include +#include "ZTData.h" + +class CZT2StatsZone : public QGraphicsWidget +{ + Q_OBJECT +public: + CZT2StatsZone(QGraphicsItem *Parent); + +// unsigned int UpdateStats(unsigned int BogieCount, unsigned int S1Count, unsigned int S2Count, unsigned int FNCount, unsigned int Rank, unsigned int Bogie, unsigned int TrainType, float TrainSpeed); + unsigned int UpdateStats(CZT2ThreadData *DataPtr); + unsigned int Reset(); + unsigned int SetLastActivationDateTime(); + +private: + unsigned int mBogieCount,mS1Count,mActualRank; + int mPIValue, mPEValue; + + QGraphicsTextItem *mBogieCountText, *mS1CountText,*mActualRankText, *mLastActivationDateTime; +}; + +#endif // ZT2STATSZONE_H diff --git a/sources/GuiElements/ZTLogViewerPage.cpp b/sources/GuiElements/ZTLogViewerPage.cpp new file mode 100644 index 0000000..7f7fe80 --- /dev/null +++ b/sources/GuiElements/ZTLogViewerPage.cpp @@ -0,0 +1,138 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page permettant de visualiser le fichier ZTLog.txt + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131021 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "ZTLogViewerPage.h" +#include +#include "GlobalDefine.h" +#include +#include +#include "Zonetest.h" +#include +#include + +#include "ZTLog.h" + + + +CZTLogViewerPage::CZTLogViewerPage(QGraphicsWidget *Parent) +{ + Q_UNUSED(Parent) + + + mProgramHandle = 0; + + mBackgroundRect = new QGraphicsRectItem(boundingRect(), this); + QBrush BackgroundBrush(QColor(245, 245, 255)); + mBackgroundRect->setBrush(BackgroundBrush); + + QGraphicsTextItem *Title = new QGraphicsTextItem("Paramètres généraux",this); + QFont font; + font.setPointSize(18); + Title->setFont(font); + Title->setPos(40,10); + + Title = new QGraphicsTextItem("Ajuster date & heure",this); + Title->setFont(font); + Title->setPos(270,130); + + mCancelButton = new CTextButtonWidget("Fermer"); + mCancelButton->setParentItem(this); + mCancelButton->setPos(700,550); + connect(mCancelButton,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + + mDestroyZTLogBtn = new CTextButtonWidget("Détruire ZTLog"); + mDestroyZTLogBtn->setParentItem(this); + mDestroyZTLogBtn->setPos(400,550); + connect(mDestroyZTLogBtn,SIGNAL(TxtButtonClicked(CTextButtonWidget*)),this,SLOT(ButtonClicked(CTextButtonWidget*))); + + mDestroyZTLogBtn->hide(); + + + mZTLogTextZone = new QTextEdit(); + QGraphicsProxyWidget *Proxy = new QGraphicsProxyWidget(this); + Proxy->setWidget(mZTLogTextZone); + Proxy->setPos(10,10); + mZTLogTextZone->resize(780,500); + mZTLogTextZone->setReadOnly(true); + mZTLogTextZone->setWordWrapMode(QTextOption::NoWrap); + +} + +void CZTLogViewerPage::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_UNUSED(event) + + + mBackgroundRect->setRect(boundingRect()); +} + +void CZTLogViewerPage::ButtonClicked(CTextButtonWidget *BtnPtr) +{ + if(BtnPtr == mCancelButton) + { + mProgramHandle->HideZTLogViewerPage(); + hide(); + } + if(BtnPtr == mDestroyZTLogBtn) + { + CZTLog::instance()->DeleteLogFile(); + LoadAndDisplayZTLog(); + + } +} + +void CZTLogViewerPage::LoadAndDisplayZTLog() +{ + mZTLogTextZone->clear(); + + mZTLogTextZone->setPlainText(CZTLog::instance()->GetEntireLogFile()); + + QTextCursor Cursor = mZTLogTextZone->textCursor(); + Cursor.movePosition(QTextCursor::End); + mZTLogTextZone->setTextCursor(Cursor); + mZTLogTextZone->ensureCursorVisible(); +} + +void CZTLogViewerPage::showEvent(QShowEvent *event) +{ + LoadAndDisplayZTLog(); + return; + + Q_UNUSED(event) +} + +//Grab the mouse if the user clicks outside buttons +void CZTLogViewerPage::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} +void CZTLogViewerPage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event) +} diff --git a/sources/GuiElements/ZTLogViewerPage.h b/sources/GuiElements/ZTLogViewerPage.h new file mode 100644 index 0000000..61a71d5 --- /dev/null +++ b/sources/GuiElements/ZTLogViewerPage.h @@ -0,0 +1,68 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page permettant de visualiser le fichier ZTLog.txt + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20131122 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef ZTLOGVIEWERPAGE_H +#define ZTLOGVIEWERPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "TextButtonWidget.h" +#include + +class CZoneTest; + +class CZTLogViewerPage : public CGuiPage +{ +Q_OBJECT +public: + CZTLogViewerPage(QGraphicsWidget *Parent = 0); + + CZoneTest *mProgramHandle; + + virtual void resizeEvent(QGraphicsSceneResizeEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void showEvent ( QShowEvent * event ); + + +private: + QGraphicsRectItem *mBackgroundRect; + CTextButtonWidget *mCancelButton, *mDestroyZTLogBtn; + QTextEdit *mZTLogTextZone; + + void LoadAndDisplayZTLog(); + + +public slots: + void ButtonClicked(CTextButtonWidget *); + +}; + +#endif // ZTLOGVIEWERPAGE_H diff --git a/sources/GuiElements/ZTPage.cpp b/sources/GuiElements/ZTPage.cpp new file mode 100644 index 0000000..15d4351 --- /dev/null +++ b/sources/GuiElements/ZTPage.cpp @@ -0,0 +1,451 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Page principale de la ZT. C'est sur cette dernière que tout est affiché. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121221 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#include "ZTPage.h" +#include +#include "GlobalDefine.h" +#include +#include +#include "Zonetest.h" +#include +#include "ZTVersion.h" +#include "SwitchCDVItem.h" + + + +CZTPage::CZTPage(QGraphicsWidget *Parent) +{ +// Q_UNUSED(Parent) + setGeometry(0,0,SCREEN_RES_WIDTH,SCREEN_RES_HEIGHT); + + mProgramHandle = 0; + mZTSimulatorPtr = 0; + + QGraphicsTextItem *SoftVersion = new QGraphicsTextItem(this); + QFont TextFont; + TextFont.setPointSize(15); + TextFont.setBold(true); + SoftVersion->setFont(TextFont); + SoftVersion->setPlainText(QString().sprintf("Version: %s",ZT_SOFT_VERSION)); + SoftVersion->setZValue(1); + SoftVersion->adjustSize(); + SoftVersion->setPos(800,2); + + QGraphicsTextItem *ZTStartDateTime = new QGraphicsTextItem(this); + ZTStartDateTime->setFont(TextFont); + QString StartDateTime = "ZT démarrée le: "; + StartDateTime += QDateTime::currentDateTime().toString("yyyy/MM/dd - hh:mm"); + ZTStartDateTime->setPlainText(StartDateTime); + ZTStartDateTime->setZValue(1); + //ZTStartDateTime->adjustSize(); + ZTStartDateTime->setPos(200,675); + + mTimeDisplayText = new QGraphicsTextItem(this); + mTimeDisplayText->setPos(400,2); +// QFont TextFont; +// TextFont.setPointSize(15); +// TextFont.setBold(true); + mTimeDisplayText->setFont(TextFont); + mTimeDisplayText->setZValue(1); +// mTimeDisplayText->adjustSize(); + + mToolsPushButton = new CPushButton(this,"./Images/tools.png"); + mToolsPushButton->setPos(25,650); + mToolsPushButton->resize(50,50); + connect( mToolsPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT( SettingsButtonPressed() ) ); + + mZTLogPushButton = new CPushButton(this,"./Images/log.png"); + mZTLogPushButton->setPos(10,570); + mZTLogPushButton->resize(65,65); + connect( mZTLogPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT( ShowZTLogButtonPressed() ) ); + + CPushButton *LogsPushButton = new CPushButton(this,"./Images/Save-icon.png"); + LogsPushButton->setPos(10,490); + LogsPushButton->resize(65,65); + connect( LogsPushButton, SIGNAL( clicked(CPushButton*) ), this, SLOT(LogsButtonPressed()) ); + + mExitPasswordPrompt = new CPasswordPrompt(Parent); + mExitPasswordPrompt->setZValue(2); + mExitPasswordPrompt->hide(); + connect(mExitPasswordPrompt,SIGNAL(PasswordValid()),this,SLOT(ExitPasswordValid())); + connect(mExitPasswordPrompt,SIGNAL(Canceled()),this,SLOT(ExitPasswordInvalid())); + + mTimeDisplayTimer = new QTimer(); + connect(mTimeDisplayTimer,SIGNAL(timeout()),this,SLOT(UpdateTime())); + mTimeDisplayTimer->setSingleShot(false); + mTimeDisplayTimer->start(1000); + + mStatusBar = new CStatusBar(this); + mStatusBar->setPos(0,715); + + mEventsBar = new CEventsBar(this); + mEventsBar->setPos(0,715+mStatusBar->boundingRect().height()); + + mZT1EquipmentWidget = new CZT1EquipmentWidget(this); + mZT1EquipmentWidget->setPos(512,150); + + mZT2EquipmentWidget = new CZT2EquipmentWidget(this); + mZT2EquipmentWidget->setPos(150,150); + + mDeckRect = new QGraphicsRectItem(this); + mDeckRect->hide(); + mDeckRect->setBrush(QBrush(Qt::Dense4Pattern)); + mDeckRect->setPen(QPen(Qt::transparent)); + + mIsZT2Present = true; + + mZT1Stats = new CZT1StatsZone(this); + mZT1Stats->setPos(mZT1EquipmentWidget->pos().x() + 70 ,100+mZT1EquipmentWidget->boundingRect().height() + 80); + + mZT2Stats = new CZT2StatsZone(this); + mZT2Stats->setPos(mZT2EquipmentWidget->pos().x() + 30,100+mZT2EquipmentWidget->boundingRect().height()+80); + + mZT1DisplayTimer.start(); +} + +unsigned int CZTPage::SetZTSimulator(CZTSimulator *Ptr) +{ + if(Ptr == 0) + return RET_ERROR; + + mZTSimulatorPtr = Ptr; + mZTSimulatorPtr->setParentItem(this); + mZTSimulatorPtr->setFlag(QGraphicsItem::ItemIsSelectable); + mZTSimulatorPtr->setFlag(QGraphicsItem::ItemIsMovable); + mZTSimulatorPtr->setFlag(QGraphicsItem::ItemSendsGeometryChanges); + mZTSimulatorPtr->setGeometry(200,400,640,480); + mZTSimulatorPtr->Show(); + + return RET_OK; +} + +void CZTPage::SettingsButtonPressed() +{ + mProgramHandle->OptionsMenuPageSelected(); +} + +void CZTPage::ShowZTLogButtonPressed() +{ + mProgramHandle->ShowZTLogViewerPage(); +} + +unsigned int CZTPage::SetStationName(QString Name) +{ + QGraphicsTextItem *StationName = new QGraphicsTextItem(this); + QFont TextFont; + TextFont.setPointSize(18); + TextFont.setBold(true); + StationName->setFont(TextFont); + StationName->setPlainText(Name); + StationName->setZValue(1); + StationName->adjustSize(); + StationName->setPos(50,2); + return RET_OK; +} + +void CZTPage::UpdateTime() +{ + QDateTime time = QDateTime::currentDateTime(); + mTimeDisplayText->setPlainText(time.toString("yyyy/MM/dd hh:mm:ss")); + +} + +void CZTPage::LogsButtonPressed() +{ + mProgramHandle->LogsPageSelected(); +} + + +unsigned int CZTPage::SetCDVList(QList *CDVListPtr) +{ + if(CDVListPtr == 0) + return RET_ERROR; + + mCDVList = CDVListPtr; + if(mCDVList->size() == 0) + return RET_ERROR; + + mCDVItemsList.clear(); + + int DeckPositionY = -1, DeckPositionX = -1, DeckWidth = 0; + + //Create CDV graphical items list, + //adjust all their position on screen and + //set parameters +// unsigned int LastPos = 0; + for(int i = 0; i < mCDVList->size(); i++) + { + int x = 0, y = 70; + int WaysSpacing = 10; + CCDVItem *NewCDVGraphicalItem; +// CCDV *temp = mCDVList->at(i); + if(mCDVList->at(i)->GetCDVType() == CDV_NORMAL_TYPE) + { + NewCDVGraphicalItem = new CCDVItem(mCDVList->at(i),this); + } + else + { + NewCDVGraphicalItem = new CSwitchCDVItem(mCDVList->at(i),this); + + } + + NewCDVGraphicalItem->SetParameters(mCDVList->at(i)->GetLabel()); + mCDVItemsList.append(NewCDVGraphicalItem); + x = (mCDVList->at(i)->GetCDVGraphicalPos() * NewCDVGraphicalItem->geometry().width())+90; + if(mCDVList->at(i)->GetCDVWay() == 2) + y += WaysSpacing+NewCDVGraphicalItem->geometry().height(); +// NewCDVGraphicalItem->setPos(i*NewCDVGraphicalItem->geometry().width()+90,70); + NewCDVGraphicalItem->setPos(x,y); + NewCDVGraphicalItem->setZValue(3); + + if(mCDVList->at(i)->IsCDVDeck() == true) + { + if(DeckPositionX == -1) + { + DeckPositionX = x/* + (NewCDVGraphicalItem->geometry().width()/2)*/; + } + DeckWidth += NewCDVGraphicalItem->geometry().width(); + + if(mCDVList->at(i)->GetCDVWay() == 1) + { + DeckPositionY = y - 30; + } + else + { + DeckPositionY = y +NewCDVGraphicalItem->geometry().height() + 5; + } + } + } + + if(DeckPositionX != -1) + { + mDeckRect->setRect(0,0,DeckWidth,20); + mDeckRect->setPos(DeckPositionX,DeckPositionY); + mDeckRect->show(); + } + else + mDeckRect->hide(); + + return RET_OK; +} + + +unsigned int CZTPage::UpdateCDVDisplay(int CDVIndex) +{ + if(CDVIndex >= mCDVItemsList.size()) + return RET_ERROR; + + if(CDVIndex < 0 || CDVIndex >= mCDVItemsList.size()) + { + for(int i = 0; i < mCDVItemsList.size(); i++) + { + mCDVItemsList.at(i)->UpdateState(); + } + } + else + mCDVItemsList.at(CDVIndex)->UpdateState(); + + return RET_OK; +} + +unsigned int CZTPage::SetZTStatus(unsigned int NbPass, unsigned int NbTriggers, unsigned int ZT1Active, unsigned int ZT2Active) +{ + mStatusBar->SetNbPass(NbPass); + mStatusBar->SetNbTriggers(NbTriggers); +// if(ZT1Active == true) +// mStatusBar->SetZT1Status(SB_ZT_ACTIVE_STATUS); +// else +// mStatusBar->SetZT1Status(SB_ZT_INACTIVE_STATUS); + mStatusBar->SetZT1Status(ZT1Active); + + if(mIsZT2Present == true) + { +// if(ZT2Active == true) +// { +// mStatusBar->SetZT2Status(SB_ZT_ACTIVE_STATUS); +// } +// else +// { +// mStatusBar->SetZT2Status(SB_ZT_INACTIVE_STATUS); +// } + mStatusBar->SetZT2Status(ZT2Active); + } + else + { + mStatusBar->SetZT2Status(SB_ZT_NOT_PRESENT_STATUS); + } + + if(ZT1Active == SB_ZT_ACTIVE_STATUS) + { + mZT1EquipmentWidget->SetActivation(true); + } + else + { + mZT1EquipmentWidget->SetActivation(false); + } + + + if(ZT2Active == SB_ZT_ACTIVE_STATUS) + { + mZT2EquipmentWidget->SetActivation(true); + } + else + { + mZT2EquipmentWidget->SetActivation(false); + } + + return RET_OK; +} + +unsigned int CZTPage::SetZT1Data(CZT1ThreadData *Data, bool ForceDisplay) +{ + if(Data == 0) + return RET_ERROR; + + //Unless specified by the ForceDisplay flag, limit refresh rate to 24 fps (~42 milliseconds) + if(ForceDisplay == false && mZT1DisplayTimer.elapsed() < 42) + { + return RET_OK; + } + + mZT1EquipmentWidget->SetState((bool)Data->mS1,(bool)Data->mS2,(bool)Data->mFN,(bool)Data->mPG,(bool)Data->mPG,(bool)Data->mPInt,(bool)Data->mPExt); + mZT1Stats->UpdateStats(Data); + mZT1DisplayTimer.start(); + + return RET_OK; + +} + +unsigned int CZTPage::SetZT2Data(CZT2ThreadData *Data) +{ + if(Data == 0) + return RET_ERROR; + mZT2EquipmentWidget->SetState(Data->mS1,Data->mPPInt,Data->mPPExt); + mZT2Stats->UpdateStats(Data); + + return RET_OK; +} + +unsigned int CZTPage::SetZT1ActivationState(bool ZT1Activated) +{ + if(ZT1Activated) + { + // mZT1EquipmentWidget->SetActivation(true); + mZT1Stats->SetLastActivationDateTime(); + } + else + { + // mZT1EquipmentWidget->SetActivation(false); + } + + return RET_OK; +} +unsigned int CZTPage::SetZT2ActivationSTate(bool ZT2Activated) +{ + if(ZT2Activated) + { +// mZT2EquipmentWidget->SetActivation(true); + mZT2Stats->SetLastActivationDateTime(); + } + else + { +// mZT2EquipmentWidget->SetActivation(false); + } + return RET_OK; +} + +unsigned int CZTPage::ResetZT1Stats() +{ + mZT1Stats->Reset(); + return RET_OK; +} + +unsigned int CZTPage::ResetZT2Stats() +{ + mZT2Stats->Reset(); + return RET_OK; +} + +unsigned int CZTPage::SetEventListPtr(QList *ListPtr) +{ + mEventsBar->mEventsList = ListPtr; + return RET_OK; +} + +unsigned int CZTPage::UpdateEventsList() +{ + mEventsBar->UpdateEventsList(); + return RET_OK; +} +unsigned int CZTPage::RequestExitPassword() +{ + mExitPasswordPrompt->RequestPassword(); + return RET_OK; +} + +void CZTPage::ExitPasswordValid() +{ + mProgramHandle->ProgramExitRequest(); +} + +void CZTPage::ExitPasswordInvalid() +{ + mExitPasswordPrompt->hide(); +} + +unsigned int CZTPage::SetZT2Presence(bool IsPresent) +{ + if(IsPresent == true) //The page is already initialized with ZT2 present + return RET_OK; + + mZT2Stats->hide(); + mZT2EquipmentWidget->hide(); + mStatusBar->SetZT2Status(SB_ZT_NOT_PRESENT_STATUS); + mIsZT2Present = false; + return RET_OK; +} + +void CZTPage::ModbusCCConnected() +{ + mStatusBar->SetCCModbusState(SB_MODBUS_CONNECTED); +} + +void CZTPage::ModbusCCDisconnected() +{ + mStatusBar->SetCCModbusState(SB_MODBUS_DISCONNECTED); +} + +void CZTPage::ModbusSEIConnected() +{ + mStatusBar->SetSEIModbusState(SB_MODBUS_CONNECTED); +} + +void CZTPage::ModbusSEIDisconnected() +{ + mStatusBar->SetSEIModbusState(SB_MODBUS_DISCONNECTED); +} diff --git a/sources/GuiElements/ZTPage.h b/sources/GuiElements/ZTPage.h new file mode 100644 index 0000000..17bda8e --- /dev/null +++ b/sources/GuiElements/ZTPage.h @@ -0,0 +1,114 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121221 JFM + Verision d'origine. + +### YYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + + +#ifndef ZTPAGE_H +#define ZTPAGE_H + +#include "GlobalDefine.h" +#include +#include "Guipage.h" +#include +#include "PushButton.h" +#include "ZTSimulator.h" +#include "CDVItem.h" +#include "CDV.h" +#include "StatusBar.h" +#include "ZT1EquipmentWidget.h" +#include "ZT1StatsZone.h" +#include "EventsBar.h" +#include "ZT2EquipmentWidget.h" +#include "ZT2StatsZone.h" +#include "PasswordPrompt.h" + +class CZoneTest; +class CEvent; + +class CZTPage : public CGuiPage +{ +Q_OBJECT +public: + CZTPage(QGraphicsWidget *Parent = 0); + CPushButton *mToolsPushButton; + CPushButton *mZTLogPushButton; + + + CZoneTest *mProgramHandle; + CPasswordPrompt *mExitPasswordPrompt; + + unsigned int SetZTSimulator(CZTSimulator* Ptr); + unsigned int SetStationName(QString Name); + unsigned int SetCDVList(QList *CDVListPtr); + + unsigned int UpdateCDVDisplay(int CDVIndex = -1); + unsigned int SetZTStatus(unsigned int NbPass, unsigned int NbTriggers, unsigned int ZT1Active, unsigned int ZT2Active); + unsigned int SetZT1Data(CZT1ThreadData *Data, bool ForceDisplay = false); + unsigned int SetZT2Data(CZT2ThreadData *Data); + unsigned int SetZT1ActivationState(bool ZT1Activated); + unsigned int SetZT2ActivationSTate(bool ZT2Activated); + unsigned int ResetZT1Stats(); + unsigned int ResetZT2Stats(); + unsigned int SetEventListPtr(QList* ListPtr); + unsigned int UpdateEventsList(); + unsigned int RequestExitPassword(); + unsigned int SetZT2Presence(bool IsPresent); + + +private: + CZTSimulator *mZTSimulatorPtr; + QTimer *mTimeDisplayTimer; + QGraphicsTextItem *mTimeDisplayText; + QGraphicsRectItem *mDeckRect; + CStatusBar *mStatusBar; + CZT1EquipmentWidget *mZT1EquipmentWidget; + CZT2EquipmentWidget *mZT2EquipmentWidget; + CZT1StatsZone *mZT1Stats; + CZT2StatsZone *mZT2Stats; + CEventsBar *mEventsBar; + QElapsedTimer mZT1DisplayTimer; + bool mIsZT2Present; + + + QList *mCDVList; //pointer to the list of CDVs + QList mCDVItemsList; //Graphical representation items only + +public slots: + void SettingsButtonPressed(); + void LogsButtonPressed(); + void UpdateTime(); + void ExitPasswordValid(); + void ExitPasswordInvalid(); + void ShowZTLogButtonPressed(); + void ModbusCCConnected(); + void ModbusCCDisconnected(); + void ModbusSEIConnected(); + void ModbusSEIDisconnected(); + + +}; + +#endif // WELCOMEPAGE_H diff --git a/sources/GuiElements/splashitem.cpp b/sources/GuiElements/splashitem.cpp new file mode 100644 index 0000000..de4bf56 --- /dev/null +++ b/sources/GuiElements/splashitem.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "splashitem.h" + +#include + +//! [0] +SplashItem::SplashItem(QGraphicsItem *parent) + : QGraphicsObject(parent) +{ + text = tr("Welcome to the Pad Navigator Example. You can use the" + " keyboard arrows to navigate the icons, and press enter" + " to activate an item. Press any key to begin."); + setCacheMode(DeviceCoordinateCache); +} +//! [0] + +//! [1] +QRectF SplashItem::boundingRect() const +{ + return QRectF(0, 0, 400, 175); +} +//! [1] + +//! [2] +void SplashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setPen(QPen(Qt::black, 2)); + painter->setBrush(QColor(245, 245, 255, 220)); + painter->setClipRect(boundingRect()); + painter->drawRoundRect(3, -100 + 3, 400 - 6, 250 - 6); + + QRectF textRect = boundingRect().adjusted(10, 10, -10, -10); + int flags = Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap; + + QFont font; + font.setPixelSize(18); + painter->setPen(Qt::black); + painter->setFont(font); + painter->drawText(textRect, flags, text); +} +//! [2] diff --git a/sources/GuiElements/splashitem.h b/sources/GuiElements/splashitem.h new file mode 100644 index 0000000..bc0917e --- /dev/null +++ b/sources/GuiElements/splashitem.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SPLASHITEM_H +#define SPLASHITEM_H + +#include + +//! [0] +class SplashItem : public QGraphicsObject +{ + Q_OBJECT +public: + explicit SplashItem(QGraphicsItem *parent = 0); + + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); + +private: + QString text; +}; +//! [0] + +#endif // SPLASHITEM_H diff --git a/sources/IOManager.cpp b/sources/IOManager.cpp new file mode 100644 index 0000000..614d147 --- /dev/null +++ b/sources/IOManager.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme du gestionnaire des modules + d'entrées/sorties externes ethernet (SEAI/O) + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "IOManager.h" + +//CIOManager::CIOManager() +//{ +//} +CIOManager::~CIOManager() +{ +} diff --git a/sources/IOManager.h b/sources/IOManager.h new file mode 100644 index 0000000..13ad7fa --- /dev/null +++ b/sources/IOManager.h @@ -0,0 +1,64 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef IOMANAGER_H +#define IOMANAGER_H + +#include "IOModule.h" +#include "QList" + +typedef enum eIOModuleType +{ + IO_MODULE_INPUT_TYPE, + IO_MODULE_OUTPUT_TYPE, + IO_MODULE_MIXED_TYPE, + IO_MODULE_INVALID_TYPE +}eIOModuleType_t; + + +enum eIOMgrRetValues +{ + EXTIO_MGR_RET_OK, + EXTIO_MGR_RET_ERR_CANNOT_CONNECT, + EXTIO_MGR_RET_ERR_CANNOT_OPEN_MODULE, + EXTIO_MGR_RET_ERR_MOD_TYPE_MISMATCH, + EXTIO_MGR_RET_ERR_MOD_OFFLINE +}; + +class CIOManager +{ +public: + //CIOManager(); + + virtual unsigned int InitIO() = 0; + virtual CIOModule *GetModule(eIOModuleType_t type, unsigned int ModuleID) = 0; + //QList mModulesList; + virtual void DestroyModule() = 0; + virtual ~CIOManager(); +}; + +#endif // IOMANAGER_H diff --git a/sources/IOModule.cpp b/sources/IOModule.cpp new file mode 100644 index 0000000..815b61f --- /dev/null +++ b/sources/IOModule.cpp @@ -0,0 +1,38 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme des modules d'entrées/sorties externes + ethernet (SEAI/O). + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "IOModule.h" + +//CIOModule::CIOModule() +//{ +//} + +CIOModule::~CIOModule() +{ + +} diff --git a/sources/IOModule.h b/sources/IOModule.h new file mode 100644 index 0000000..58669f4 --- /dev/null +++ b/sources/IOModule.h @@ -0,0 +1,38 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef IOMODULE_H +#define IOMODULE_H + +class CIOModule +{ +public: +// CIOModule(); + virtual ~CIOModule(); +}; + +#endif // IOMODULE_H diff --git a/sources/InputModule.cpp b/sources/InputModule.cpp new file mode 100644 index 0000000..4e2016d --- /dev/null +++ b/sources/InputModule.cpp @@ -0,0 +1,32 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme des modules d'entrée externes. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "InputModule.h" +CInputModule::~CInputModule() +{ + +} diff --git a/sources/InputModule.h b/sources/InputModule.h new file mode 100644 index 0000000..b25db2c --- /dev/null +++ b/sources/InputModule.h @@ -0,0 +1,43 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef INPUTMODULE_H +#define INPUTMODULE_H +#include "IOModule.h" + +class CInputModule: public CIOModule +{ +public: + + virtual ~CInputModule(); + /*virtual unsigned int GetInputs(unsigned char *DataBuf) = 0;*/ + virtual unsigned int GetInputs() = 0; + virtual unsigned int GetInputBuf() = 0; + +}; + +#endif // INPUTMODULE_H diff --git a/sources/LazerProbe.cpp b/sources/LazerProbe.cpp new file mode 100644 index 0000000..26375e0 --- /dev/null +++ b/sources/LazerProbe.cpp @@ -0,0 +1,378 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Lecture et décodage des sondes Laser physiques dans la voie. La classe lit + le port série lorsque des données sont disponibles, décode les données et les + rend disponibles via la fonction GetLastData(). + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121221 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + 20141118 JFM + Reset the mProbeAlive flag to "true" when signal comes back. + */ + +/* ************************************************************************** */ + +#include "LazerProbe.h" +#include +#include "LazerProbesMgr.h" +#include +#include +#include +#include +#include "ZTLog.h" + +CLazerProbe::CLazerProbe(unsigned int ProbeID, unsigned int ProbeType): + mIsAcquisitioning(false), + mSerialPort(NULL) + +{ + mLazerProbeRxState = LP_WAIT_HEADER1_STATE; + mHeader1 = mDataNibble = mData1 = mData2 = mHeader2 = 0; + mProbeType = ProbeType; + mProbeID = ProbeID; + mLPCurData = 0; + mIsLazerProbeAlive = true; + mRunThread = true; + +} + +CLazerProbe::~CLazerProbe() +{ + close(fd); +} + +unsigned int CLazerProbe::OpenPort(QString PortName) +{ + //////////////////////////////////////////////////////////////////////////////////// + ///NOTE SUR CE GESTIONNAIRE DE PORT SÉRIE: + /// + ///Linux étant ce qu'il est, il est nécessaire de faire une petite passe-passe afin d'exploiter le port série efficacement. + ///Les sondes lazer envoient 3 bytes par message, afin d'avoir une bonne synchronisation entre le train et les données des + ///sondes, il est impératif d'analyser les nouvelles données au moment même où elles arrivent. + ///Le problème est que le chip UART 16550A possède une FIFO interne qui est automatiquement configurée à 8 bytes par le kernel + ///lorsqu'on ouvre le port. Ceci empèche le traîtement des données en temps réel car nous avons toujours au moins 2 échantillons + ///qui sont perdus pour chaque lecture du port série. Seule la désactivation de la FIFO permet de lire 1 byte à la fois par des + ///moyens "traditionnels" + ///Il n'y a aucun moyen de désactiver la FIFO interne autrement qu'en écrivant directement dans le registre de la carte avec + ///la fonction outb() (cette méthode est aussi implémentée, voir le #define USE_UART_HARDWARE_CTRL). Par contre, cette méthode + ///nécessite les privilèges ROOT (utilisation de la fonction setuid() ). Ceci rend le debugging impossible autrement qu'en passant + ///par un remote debugger... + /// + ///En regardant le code source du kernel driver, j'ai remarqué que si le "device" était un 16550 plutôt qu'un 16550A, la fifo était désactivée + ///lors du changement de baudrate, ceci pour des raisons historiques de compatibilité. On peut donc exploiter ce "bug" en forcant + ///le device à un 16550 avant d'ajuster le baudrate. Comme par magie, la FIFO est désactivée et tout fonctionne bien. + /// + ///J-F Martel. 2014/01/27 + ///////////////////////////////////////////////////////////////////////////////////// + + + QString PortPath = "/dev/"; + PortPath += PortName; + fd = open(PortPath.toLatin1().data(), O_RDONLY | O_NOCTTY | O_NDELAY | O_NONBLOCK); + if (fd < 0) + { + CEngLog::instance()->AddLogString(QString().sprintf("Erreur d'ouverture de la sonde EXT #%d sur le port %s : %s",mProbeID,PortName.toUtf8().constData(),strerror (errno))); + return RET_ERROR; + } + CEngLog::instance()->AddLogString(QString().sprintf("Ouverture de la sonde laser INT #%d réussie sur le port %s",mProbeID,PortName.toUtf8().constData()),1); + + //Faisons un peu de magie ! + //On accède directement au driver avec ioctl (privilèges ROOT non requis). + //On lit les paramètres du port série détectés au démarrage par le driver. + struct serial_struct serinfo; + if(ioctl(fd,TIOCGSERIAL,&serinfo) != 0) + { + CEngLog::instance()->AddLogString(QString().sprintf("Impossible d'accéder au driver du port série %s",PortName.toUtf8().constData()),1); + close(fd); + return RET_ERROR; + } + +#ifndef CUSTOM_KERNEL_INSTALLED + //C'est ici que l'on force le port à être un 16550 plutôt qu'un 16550A. + //Le port fonctionne de la même manière mais le driver force la désactivation du FIFO interne. + //Aussi, on active le flag LOW_LATENCY pour que le kernel remonte les données au fur et à + //mesure qu'elles arrivent du port. + //Il est important de faire cette opération avant de modifier le baudrate du port + + + serinfo.type = PORT_16550; +#endif + + serinfo.flags |= ASYNCB_LOW_LATENCY; + if(ioctl(fd,TIOCSSERIAL,&serinfo) != 0) + { + CEngLog::instance()->AddLogString(QString().sprintf("Impossible de fixer le type du port série %s",PortName.toUtf8().constData()),1); + close(fd); + return RET_ERROR; + } + + + //De retour à la configuration "traditionnelle" du port série. + struct termios tty; + memset (&tty, 0, sizeof tty); + if (tcgetattr (fd, &tty) != 0) + { + CEngLog::instance()->AddLogString(QString().sprintf("Impossible de configurer le port série %s",PortName.toUtf8().constData()),1); + close(fd); + return RET_ERROR; + } + + cfsetospeed (&tty, B38400); + cfsetispeed (&tty, B38400); + + tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars + tty.c_iflag &= ~IGNBRK; // ignore break signal + tty.c_lflag = 0; // no signaling chars, no echo, + tty.c_oflag = 0; // no remapping, no delays + tty.c_cc[VMIN] = 0; // read doesn't block + tty.c_cc[VTIME] = 0; // no read timeout + + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl + + tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, + // enable reading + tty.c_cflag &= ~(PARENB | PARODD); // shut off parity + tty.c_cflag |= CSTOPB; //2 STOP BITS JFM 20140210 + tty.c_cflag &= ~CRTSCTS; + + tcflush(fd,TCIOFLUSH); + + if (tcsetattr (fd, TCSANOW, &tty) != 0) + { + CEngLog::instance()->AddLogString(QString().sprintf("Impossible de configurer le port série %s",PortName.toUtf8().constData()),1); + close(fd); + return RET_ERROR; + } + + return RET_OK; + +} + +unsigned int CLazerProbe::SetUID() +{ + + return 0; +} + +unsigned int CLazerProbe::ResetUID() +{ + return 0; +} + +void CLazerProbe::ProbeDataAvailable() +{ + + qDebug("Probe thread started..."); + mDataIntervalTimer.start(); + + char buf[1024]; + int size; + + bool run = true; + + while(run) + { + size = read(fd,buf,1024); + if(size > 0) + { + for(int i = 0; i < size; i++) + LPRxStateMachine(buf[i]); + + mDataIntervalTimer.start(); + if(mIsLazerProbeAlive == false) + { + mRdWrLock.lockForWrite(); + mIsLazerProbeAlive = true; + mRdWrLock.unlock(); + CZTLog::instance()->AddLogString(QString().sprintf("Fin panne sonde lazer ID %d ",mProbeID),true); + } + } + + if(mDataIntervalTimer.elapsed() > 1000) //If we didn't receive anything for more than 1 second + { + if(mIsLazerProbeAlive == true) + { + mRdWrLock.lockForWrite(); + mIsLazerProbeAlive = false; + mRdWrLock.unlock(); + + CZTLog::instance()->AddLogString(QString().sprintf("Panne équipement sonde lazer ID %d",mProbeID),true); + } + } + mRdWrLock.lockForRead(); + run = mRunThread; + mRdWrLock.unlock(); + } + +// qDebug("Probe thread quit : %d",mProbeID); +} + +unsigned int CLazerProbe::LPRxStateMachine(unsigned char newbyte) +{ + QString mRxString; + static int datacount = 0; + + switch(mLazerProbeRxState) + { + case LP_IGNORE_DATA_STATE: + { + //The system is not acquisitioning so simply ignore and discard byte + break; + } + case LP_WAIT_HEADER1_STATE: + { + mHeader1 = newbyte & LAZER_PROBE_HEADER_MASK; + if(mHeader1 == 0x54 || mHeader1 == 0xA8) + { + mDataNibble = newbyte & LAZER_PROBE_DATA_NIBBLE_MASK; + mLazerProbeRxState = LP_GET_DATA1_STATE; + } + else + { + mHeader1 = 0; + qDebug("Bad header 0x%x",newbyte); + } + + break; + } + case LP_GET_DATA1_STATE: + { + mData1 = newbyte; + mLazerProbeRxState = LP_GET_DATA2_STATE; + break; + } + case LP_GET_DATA2_STATE: + { + mData2 = newbyte; + mLazerProbeRxState = LP_CHECK_HEADER2_STATE; + break; + } + case LP_CHECK_HEADER2_STATE: + { + mHeader2 = newbyte & LAZER_PROBE_HEADER_MASK; + + + //We do this verification to ensure that we are still in sync with the frame. + //If Header1 is not 1's complement of Header2, reset the state machine and + //wait for a new header... + if(mHeader1 == (~mHeader2 & 0xFC)) + { + unsigned int mTempData = 0; + + mTempData = mData2; + mTempData <<= 8; + + mTempData += (unsigned int)mData1; + + + mTempData <<= 2; + + + if(mTempData >= 100000 && mTempData <= 200000) //filter results out of the sensor's range + { + + mRdWrLock.lockForWrite(); + mLPCurData = mTempData; + mRdWrLock.unlock(); + } + + + + //This is used for the Engineering page only so we can display + //the value in semi-realtime each 500ms (1 sample / 500) + if(datacount++ >= 500) + { + emit NewProbeData(mTempData,mProbeType); + datacount = 0; + } + + //The Header2 is now the Header1 of the next frame. + //So we need to continue to LP_GET_DATA1_STATE + mHeader1 = mHeader2; + mDataNibble = newbyte & LAZER_PROBE_DATA_NIBBLE_MASK; + mLazerProbeRxState = LP_GET_DATA1_STATE; + } + else + { + //We are out of sync or there was a transmission error. Ignore this frame and reset. + mHeader1 = 0; + mDataNibble = 0; + mLazerProbeRxState = LP_WAIT_HEADER1_STATE; + qDebug("Bad header 0x%x",newbyte); + } + break; + } + } + return LAZER_PROBE_DATA_INVALID; +} + +unsigned int CLazerProbe::LPAnalyseNewData() +{ + return RET_OK; +} + +unsigned int CLazerProbe::StartAcquisition() +{ + mLazerProbeRxState = LP_WAIT_HEADER1_STATE; + mHeader1 = mDataNibble = mData1 = mData2 = mHeader2 = 0; + mIsAcquisitioning = true; + return RET_OK; +} +unsigned int CLazerProbe::StopAcquisition() +{ + mIsAcquisitioning = false; + mLazerProbeRxState = LP_IGNORE_DATA_STATE; + return RET_OK; +} + +unsigned int CLazerProbe::GetLastData() +{ + static unsigned int Last = 0; + + mRdWrLock.lockForRead(); + Last = mLPCurData; + mRdWrLock.unlock(); + + + return Last; +} + +unsigned int CLazerProbe::FlushProbeData() +{ + mSerialPort->flush(); + return RET_OK; +} + +bool CLazerProbe::IsProbeAlive() +{ + bool temp; + mRdWrLock.lockForRead(); + temp = mIsLazerProbeAlive; + mRdWrLock.unlock(); + + return temp; +} + +void CLazerProbe::QuitProbeThread() +{ + mRdWrLock.lockForWrite(); + mRunThread = false; + mRdWrLock.unlock(); +} diff --git a/sources/LazerProbe.h b/sources/LazerProbe.h new file mode 100644 index 0000000..c0fa833 --- /dev/null +++ b/sources/LazerProbe.h @@ -0,0 +1,131 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef LAZERPROBE_H +#define LAZERPROBE_H + + +//N'activer qu'une seule de ces deux options... USE_CUSTOM_SERIAL_DRIVER ou USE_UART_HARDWARE_CTRL +#define USE_CUSTOM_SERIAL_DRIVER +#ifndef USE_CUSTOM_SERIAL_DRIVER +//#define USE_UART_HARDWARE_CTRL +#endif + + +#include "GlobalDefine.h" +#include "qextserialport.h" +#include "AbstractLazerProbe.h" +#include +#include +#ifdef USE_CUSTOM_SERIAL_DRIVER + #include + #include + #include + #include + #include + #include + #include +#endif + + + +#define LAZER_PROBE_HEADER_MASK 0xFC +#define LAZER_PROBE_DATA_NIBBLE_MASK 0x03 + + +class CLazerProbe : public QObject, public CAbstractLazerProbe +{ + Q_OBJECT + + enum eLazerProbeRxStates + { + LP_WAIT_HEADER1_STATE, + LP_GET_DATA1_STATE, + LP_GET_DATA2_STATE, + LP_CHECK_HEADER2_STATE, + LP_IGNORE_DATA_STATE, + LP_MAX_STATE + }; + +public: + CLazerProbe(unsigned int ProbeID, unsigned int ProbeType); + ~CLazerProbe(); + unsigned int OpenPort(QString PortName); + unsigned int GetType(){return mProbeType;} + QString GetPortName(){return mSerialPortName;} + unsigned int GetID(){return mProbeID;} + unsigned int StartAcquisition(); + unsigned int StopAcquisition(); + unsigned int GetLastData(); + unsigned int FlushProbeData(); + bool IsProbeAlive(); + void QuitProbeThread(); + + +private: + unsigned char mHeader1,mDataNibble,mData1,mData2,mHeader2; + unsigned int mLPCurData; + unsigned int mLazerProbeRxState; + unsigned int mProbeType; + unsigned int mProbeID; + bool mRunThread; + + QString mSerialPortName; + bool mIsAcquisitioning; + + uid_t euid, ruid; + + QReadWriteLock mRdWrLock; + + + + QextSerialPort *mSerialPort; + QElapsedTimer mDataIntervalTimer; + bool mIsLazerProbeAlive; + + unsigned int LPRxStateMachine(unsigned char newbyte); + unsigned int LPAnalyseNewData(); + unsigned int SetUID(); + unsigned int ResetUID(); + +#ifdef USE_CUSTOM_SERIAL_DRIVER + int fd; + int mUartBaseAddress; +#endif + +public slots: + void ProbeDataAvailable(); + +signals: + void NewProbeData(unsigned int,unsigned int); + + + + +}; + +#endif // LAZERPROBE_H diff --git a/sources/LazerProbesMgr.cpp b/sources/LazerProbesMgr.cpp new file mode 100644 index 0000000..f45b239 --- /dev/null +++ b/sources/LazerProbesMgr.cpp @@ -0,0 +1,101 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe haut niveau de gestion des sondes lazer. Cette classe instancie les + objets CLazerProbe selon ce qui est défini dans le fichier de configuration + de la ZT. Ensuite, elle les ajoute dans une liste et les rend disponible via + la fonction GetLazerProbeHandle. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130130 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "LazerProbesMgr.h" +#include "ZTconfigmgr.h" +#include "EngLog.h" +#include "ZTLog.h" + +CLazerProbesMgr::CLazerProbesMgr(): + mNbOpenedProbes(0) +{ +} +CLazerProbesMgr::~CLazerProbesMgr() +{ + for(int i = 0; i < mLazerProbesList.size(); i++) + { + if(mLazerProbesList.at(i)) + { + mLazerProbesList.at(i)->QuitProbeThread(); + mLazerProbesThread.at(i)->quit(); + mLazerProbesThread.at(i)->wait(1000); + delete mLazerProbesThread.at(i); + delete mLazerProbesList.at(i); + } + } + + mLazerProbesList.clear(); +} + +unsigned int CLazerProbesMgr::InitLazerProbes() +{ + + //Open each module and make shure the configuration matches the slave address + + QList * ProbesList = 0; + int i; + + //Parse list extracted from config file and create modules instances. + ProbesList = CZTConfigMgr::instance()->GetLazerProbesConfigList(); + CLazerProbe *NewProbe; + for(i = 0; i < ProbesList->size(); i++) + { + NewProbe = new CLazerProbe(ProbesList->at(i).ProbeID, ProbesList->at(i).ProbeType); + + unsigned int Ret = NewProbe->OpenPort(ProbesList->at(i).SerialPort); + + if(Ret != RET_OK) + { + CEngLog::instance()->AddLogString(QString().sprintf("Impossible d'ouvrir la sonde lazer. ID:%d, Type:%d, Port:%s",ProbesList->at(i).ProbeID,ProbesList->at(i).ProbeType,ProbesList->at(i).SerialPort.toUtf8().data()),1); + delete NewProbe; + return LAZERPROBES_MGR_RET_PROBE_OPEN_ERROR; + } + + mLazerProbesList.append(NewProbe); + + QThread *ProbeThread = new QThread; + NewProbe->moveToThread(ProbeThread); + connect(ProbeThread,SIGNAL(started()),NewProbe,SLOT(ProbeDataAvailable())); + mLazerProbesThread.append(ProbeThread); + + ProbeThread->start(QThread::HighPriority); //JFM 20150421 higher priority to avoid buffer overruns... + } + + return LAZERPROBES_MGR_RET_OK; +} + +CAbstractLazerProbe * CLazerProbesMgr::GetLazerProbeHandle(eLazerProbeType_t LazerProbeType, unsigned int LazerProbeID) +{ + for(int i = 0; i < mLazerProbesList.size(); i++) + { + if((int)mLazerProbesList.at(i)->GetType() == LazerProbeType && mLazerProbesList.at(i)->GetID() == LazerProbeID) + return mLazerProbesList.at(i); + } + return NULL; +} diff --git a/sources/LazerProbesMgr.h b/sources/LazerProbesMgr.h new file mode 100644 index 0000000..6a704f8 --- /dev/null +++ b/sources/LazerProbesMgr.h @@ -0,0 +1,72 @@ +#ifndef LAZERPROBESMGR_H +#define LAZERPROBESMGR_H + +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130130 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#include "LazerProbe.h" +#include "QList" +#include "AbstractLazerProbeMgr.h" +#include + +//enum eLazerProbesMgrRetValues +//{ +// LAZERPROBES_MGR_RET_OK, +// LAZERPROBES_MGR_RET_PROBE_OPEN_ERROR, +// LAZERPROBES_MGR_RET_INVALID_PROBE_ID +//}; + +//typedef enum eLazerProbeType +//{ +// LAZER_PROBE_TYPE_EXTERNAL, //Internal lazer probe installation +// LAZER_PROBE_TYPE_INTERNAL, //External lazer probe installation +// LAZER_PROBE_TYPE_INVALID +//}eLazerProbeType_t; + +class CLazerProbesMgr : public QObject, public CAbstractLazerProbeMgr +{ + Q_OBJECT +public: + + + CLazerProbesMgr(); + ~CLazerProbesMgr(); + + unsigned int InitLazerProbes(void); + // unsigned int OpenExternalModules(void); + CAbstractLazerProbe *GetLazerProbeHandle(eLazerProbeType_t LazerProbeType, unsigned int LazerProbeID); + + +private: + QList mLazerProbesList; + QList mLazerProbesThread; + unsigned int mNbOpenedProbes; + +}; + +#endif // LAZERPROBESMGR_H diff --git a/sources/LogMgr.cpp b/sources/LogMgr.cpp new file mode 100644 index 0000000..9f3717d --- /dev/null +++ b/sources/LogMgr.cpp @@ -0,0 +1,644 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est responsable de la création d'une liste d'objets CLogElement + à partir des données de passage des trains contenues dans les fichiers log. + Cette classe est principalement utilisée par l'interface graphique pour la + visualisation des passages. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121024 JFM + + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "LogMgr.h" + +#include "TrainLogFileMgr.h" +#include "ZTLog.h" + +CLogMgr::CLogMgr() +{ + mMaxFileCount = MAX_LOG_FILE_COUNT; + mKeepMPM10Logs = false; +} + +CLogMgr::~CLogMgr() +{ + DestroyLogList(); +} + +unsigned int CLogMgr::DestroyLogList() +{ + for(int i = 0; i < mPassagesList.size(); i++) + { + delete mPassagesList.at(i); + } + + mPassagesList.clear(); + + return RET_OK; +} + +int CLogMgr::KeepAllMPM10Logs(bool keep) +{ + mKeepMPM10Logs = keep; + return RET_OK; +} + +int CLogMgr::KeepAllZT1Logs(bool keep) +{ + mKeepZT1Logs = keep; + return RET_OK; +} + +int CLogMgr::KeepAllZT2Logs(bool keep) +{ + mKeepZT2Logs = keep; + return RET_OK; +} + +int CLogMgr::SetMaxLogFilesCount(int count) +{ + mMaxFileCount = count; + return RET_OK; +} + +//Parse all the logs at once. This may freeze the program and the GUI depending +//on the number of log files. +//The KeepData parameter determines if the raw data should be kept in RAM (Not recommended). +//It is recommended to load it when needed via LoadLogData(). +unsigned int CLogMgr::ParseLogs(bool KeepData) +{ + DestroyLogList(); + +// QStringList LogFilters; +// LogFilters << "*.bin"; +// QDir LogDir("./Trains/"); + +// LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); +// LogDir.setNameFilters(LogFilters); +// LogDir.setSorting(QDir::Name); + + QFileInfoList list = GetLogsFilenameList();//LogDir.entryInfoList(); + + if(list.size() == 0) + return RET_OK; + + //Extract data for each passage + for(int i = 0; i < list.size(); i++) + { + ParseNewLog(list.at(i).filePath(),KeepData,false); + } + + return RET_OK; +} + +QFileInfoList CLogMgr::GetLogsFilenameList() +{ + QStringList LogFilters; + LogFilters << "*.bin"; + QDir LogDir("./Trains/"); + + LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + LogDir.setNameFilters(LogFilters); + LogDir.setSorting(QDir::Name); + + QFileInfoList list = LogDir.entryInfoList(); + + return list; +} + +////This function checks the number of log files on the disk and +////makes shure there are not too many. The number of files can be +////limited by MaxNbLog for the max file count or MaxSize for the maximum +////number of bytes on the disk. +//unsigned int CLogMgr::CleanLogsOnDisk(qint32 MaxNbLogs, qint64 MaxSize) +//{ +// int RemovedFiles = 0; +// QStringList LogFilters; +// LogFilters << "*.bin"; +// QDir *LogDir = new QDir("./Trains/"); + +// LogDir->setFilter(QDir::Files | QDir::NoDotAndDotDot); +// LogDir->setNameFilters(LogFilters); +// LogDir->setSorting(QDir::Name); + +// QFileInfoList list = LogDir->entryInfoList(); + +// if(list.size() == 0) +// { +// delete LogDir; +// return RET_OK; +// } + +// //First, delete the older files if there are too many. +// if(list.size() > MaxNbLogs) +// { +// for(qint32 i = 0; i < (list.size() - MaxNbLogs); i++) +// { +// if(LogDir->remove(list.at(i).absoluteFilePath()) == false) +// { +// CZTLog::instance()->AddLogString(QString().sprintf("Impossible d'effacer le log %s",list.at(i).absoluteFilePath().toUtf8().data()),true); +// } +// else +// { +// RemovedFiles++; +// } +// } + +// //refresh list +// delete LogDir; +// QDir *LogDir = new QDir("./Trains/"); + +// LogDir->setFilter(QDir::Files | QDir::NoDotAndDotDot); +// LogDir->setNameFilters(LogFilters); +// LogDir->setSorting(QDir::Name); + +// list = LogDir->entryInfoList(); +// } + +// delete LogDir; + +// qint64 DirSize = 0; +// for(qint32 i = 0; i < list.size(); i++) +// { +// DirSize += list.at(i).size(); +// } + +// if(DirSize > MaxSize) +// { +// int i = 0; +// while(DirSize > MaxSize) +// { +// if(LogDir->remove(list.at(i).absoluteFilePath()) == true) +// { +// DirSize -= list.at(i).size(); +// RemovedFiles++; +// } +// else +// { +// CZTLog::instance()->AddLogString(QString().sprintf("Impossible d'effacer le log %s",list.at(i).absoluteFilePath().toUtf8().data()),true); +// } +// i++; +// } +// } + +// if(RemovedFiles > 0) +// { +// CZTLog::instance()->AddLogString(QString().sprintf("%d fichiers de passage on été effacés",RemovedFiles),true); +// } + +// return RET_OK; +//} + +//This function loads the raw data from a log element for which +//the data has not yet been loaded. Data will be loaded directly in the +//passed element pointer. +//Returns a pointer to the new log Element +CLogElement* CLogMgr::LoadLogData(CLogElement *Element) +{ + if(Element->mZTLogType == ZT1_LOG_TYPE) + { + CZT1LogElement *TargetElement = (CZT1LogElement*)Element; + QString FilePath = TargetElement->mLogFileName; + unsigned int ret; + + //Make shure that the lists are empty in the target element + for(int i = 0; i < TargetElement->mZTLogData.size(); i++) + { + delete TargetElement->mZTLogData.at(i); + } + for(int i = 0; i < TargetElement->mZTDetections.size(); i++) + { + delete TargetElement->mZTDetections.at(i); + } + + TargetElement->mZTLogData.clear(); + TargetElement->mZTDetections.clear(); + + //Passing the TargetElement to the OpenTrainLog function will fill it with data + CTrainLogFileMgr::instance()->OpenTrainLog(FilePath,ret,TargetElement,true); + + return (CLogElement*)TargetElement; + } + else if(Element->mZTLogType == ZT2_LOG_TYPE) + { + CZT2LogElement *TargetElement = (CZT2LogElement*)Element; + QString FilePath = TargetElement->mLogFileName; + unsigned int ret; + + //Make shure that the lists are empty in the target element + for(int i = 0; i < TargetElement->mZTLogData.size(); i++) + { + delete TargetElement->mZTLogData.at(i); + } + for(int i = 0; i < TargetElement->mZTDetections.size(); i++) + { + delete TargetElement->mZTDetections.at(i); + } + + TargetElement->mZTLogData.clear(); + TargetElement->mZTDetections.clear(); + + //Passing TargetElement to the OpenTrainLog function will fill it with data + CTrainLogFileMgr::instance()->OpenTrainLog(FilePath,ret,TargetElement,true); + + return (CLogElement*)TargetElement; + } + + return 0; + +} + +unsigned int CLogMgr::FreeLogData(CLogElement *Element) +{ + if(Element->mZTLogType == ZT1_LOG_TYPE) + { + CZT1LogElement *temp = (CZT1LogElement*)Element; + for(int i = 0; i < temp->mZTLogData.size(); i++) + delete temp->mZTLogData.at(i); + temp->mZTLogData.clear(); + } + if(Element->mZTLogType == ZT2_LOG_TYPE) + { + CZT2LogElement *temp = (CZT2LogElement*)Element; + for(int i = 0; i < temp->mZTLogData.size(); i++) + delete temp->mZTLogData.at(i); + temp->mZTLogData.clear(); + } + + return RET_OK; + +} + +//Resets the logs list and checks for log files. +//Thereafter, ParseNextLog() shall be called periodically for all of files in the list +//returns the number of detected files +unsigned int CLogMgr::InitSteppedLogParsing() +{ + DestroyLogList(); + mLogsFileIndex = 0; + + QStringList LogFilters; + LogFilters << "*.bin"; + QDir LogDir("./Trains/"); + + LogDir.setFilter(QDir::Files | QDir::NoDotAndDotDot); + LogDir.setNameFilters(LogFilters); + LogDir.setSorting(QDir::Name); + + mLogsFilelist.clear(); + + mLogsFilelist = LogDir.entryInfoList(); + + return mLogsFilelist.size(); + +} + +//returns true if the parsed log is valid. +//otherwise returns false +bool CLogMgr::ParseNextLog() +{ + if((int)mLogsFileIndex >= mLogsFilelist.size()) + return false; + + //Extract data + + if(ParseNewLog(mLogsFilelist.at(mLogsFileIndex).filePath()) == RET_ERROR) + return false; + + mLogsFileIndex++; + + return true; +} + +unsigned int CLogMgr::ParseNewLog(QString FileName, bool KeepData,bool CleanupLogs) +{ + Q_UNUSED(KeepData) + + unsigned int ret; + CLogElement *NewLog = CTrainLogFileMgr::instance()->OpenTrainLog(FileName,ret); + + if(ret == RET_ERROR) + { + return RET_ERROR; + } + + mPassagesList.append(NewLog); + + if(CleanupLogs == true) + { + CleanUpLogs(); + } + + return RET_OK; +} + + +//This function makes shure that we keep only a certain cout of standard passage files +//but we keep all the passage files that contains detections. +unsigned int CLogMgr::CleanUpLogs() +{ + int NbZT1Logs = 0, NbZT2Logs = 0; + //First, check if we have more logs than supposed... + for(int i = 0; i < mPassagesList.size(); i++) + { + CLogElement *Log = mPassagesList.at(i); + + if(Log->mZTLogType == ZT1_LOG_TYPE) + { + CZT1LogElement *ZT1Log = (CZT1LogElement*)Log; + if(ZT1Log->mZTDetections.size() == 0 && ZT1Log->mFlags.mIsProblematicPassage == 0) + { + NbZT1Logs++; + } + } + else + { + CZT2LogElement *ZT2Log = (CZT2LogElement*)Log; + if(ZT2Log->mZTDetections.size() == 0 && ZT2Log->mFlags.mIsProblematicPassage == 0) + { + NbZT2Logs++; + } + } + } + + //Now check if we need to delete some logs + bool CleanZT1Logs = false; + if(mKeepZT1Logs == false) + { + CleanZT1Logs = (NbZT1Logs > mMaxFileCount); + } + + bool CleanZT2Logs = false; + if(mKeepZT2Logs == false) + { + CleanZT2Logs = (NbZT2Logs > mMaxFileCount); + } + + //Logs are sorted in ascending order, we want to delete the older + //logs so start from the top of the list. + int i = 0; + while(CleanZT1Logs == true || CleanZT2Logs == true) + { + CLogElement *Log = mPassagesList.at(i); + + if(Log->mZTLogType == ZT1_LOG_TYPE) + { + if(CleanZT1Logs == true) + { + CZT1LogElement *ZT1Log = (CZT1LogElement*)Log; + if(ZT1Log->mZTDetections.size() == 0 && + !(ZT1Log->mTrainType == TRAIN_TYPE_MPM10 && mKeepMPM10Logs == true) && + ZT1Log->mFlags.mIsProblematicPassage == 0) + { + //Remove this log. + QDir().remove(ZT1Log->mLogFileName); + delete mPassagesList.at(i); + mPassagesList.removeAt(i); + + NbZT1Logs--; + if(NbZT1Logs <= mMaxFileCount) + { + CleanZT1Logs = false; + } + + } + else + { + i++; + } + } + else + { + i++; + } + } + else + { + if(CleanZT2Logs == true) + { + CZT2LogElement *ZT2Log = (CZT2LogElement*)Log; + if(ZT2Log->mZTDetections.size() == 0 && + ZT2Log->mFlags.mIsProblematicPassage == 0) + { + QDir().remove(ZT2Log->mLogFileName); + delete mPassagesList.at(i); + mPassagesList.removeAt(i); + + NbZT2Logs--; + + if(NbZT2Logs <= mMaxFileCount) + { + CleanZT2Logs = false; + } + + } + else + { + i++; + } + } + else + { + i++; + } + } + } + + + return RET_OK; +} + + +unsigned int CLogMgr::GetLogsCount() +{ + return mPassagesList.size(); +} + +QList * CLogMgr::GetLogsList() +{ + return &mPassagesList; +} + +int CLogMgr::DeleteErrorLogs(bool ZT1, bool ZT2) +{ + int count = 0; + int i=0; + + while(i < mPassagesList.size()) + { + CLogElement *Log = mPassagesList.at(i); + + if(Log->mZTLogType == ZT1_LOG_TYPE) + { + if(ZT1 == true) + { + CZT1LogElement *ZT1Log = (CZT1LogElement*)Log; + if(ZT1Log->mZTDetections.size() != 0 || + ZT1Log->mFlags.mIsProblematicPassage == 1) + { + QDir().remove(ZT1Log->mLogFileName); + count++; + delete mPassagesList.at(i); + mPassagesList.removeAt(i); + } + else + { + i++; + } + } + } + else + { + if(ZT2 == true) + { + CZT2LogElement *ZT2Log = (CZT2LogElement*)Log; + if(ZT2Log->mZTDetections.size() != 0 || + ZT2Log->mFlags.mIsProblematicPassage == 1) + { + QDir().remove(ZT2Log->mLogFileName); + count++; + delete mPassagesList.at(i); + mPassagesList.removeAt(i); + } + else + { + i++; + } + } + } + } + + CEngLog::instance()->AddLogString(QString().sprintf("%d fichiers d'erreurs effacés",count)); + return count; +} + +//QDataStream &operator<<(QDataStream &out, const CLogElement &source) +//{ +// return out; +//} + +//QDataStream &operator>>(QDataStream &in, CLogElement &dest) +//{ +// return in; +//} +CLogElement::~CLogElement() +{ +} + +CZT1LogElement::~CZT1LogElement() +{ +// for(int i = 0; i < mZTLogData.size(); i++) +// delete mZTLogData.at(i); + qDeleteAll(mZTLogData); + mZTLogData.clear(); + +// for(int i = 0; i < mZTDetections.size(); i++) +// delete mZTDetections.at(i); + qDeleteAll(mZTDetections); + mZTDetections.clear(); +} + +//QDataStream &operator<<(QDataStream &out, const CZT1LogElement &source) +//{ +// quint32 NbLogEntry = source.mZTLogData.size(); +// quint32 NbDetections = source.mZTDetections.size(); +// quint32 LogType = source.mZTLogType; + +// out << LogType << NbLogEntry << NbDetections; + +// for(unsigned int i = 0; i < NbLogEntry; i++) +// { +// out << *source.mZTLogData.at(i); +// } + +// //write detections +// for(unsigned int i =0; i < NbDetections; i++) +// { +// out << *source.mZTDetections.at(i); +// } + +// return out; +//} + +//QDataStream &operator>>(QDataStream &in, CZT1LogElement &dest) +//{ +// return in; +//} + +CZT2LogElement::~CZT2LogElement() +{ + for(int i = 0; i < mZTLogData.size(); i++) + delete mZTLogData.at(i); + mZTLogData.clear(); + + for(int i = 0; i < mZTDetections.size(); i++) + delete mZTDetections.at(i); + mZTDetections.clear(); + +} + + + + + +//QDataStream &operator<<(QDataStream &out, const CZT2LogElement &source) +//{ +// quint32 NbLogEntry = source.mZTLogData.size(); +// quint32 NbDetections = source.mZTDetections.size(); +// quint32 LogType = source.mZTLogType; + +// out << LogType << NbLogEntry << NbDetections; + +// for(unsigned int i = 0; i < NbLogEntry; i++) +// { +// out << *source.mZTLogData.at(i); +// } + +// //write detections +// for(unsigned int i =0; i < NbDetections; i++) +// { +// out << *source.mZTDetections.at(i); +// } + +// return out; +//} + +////QDataStream &operator>>(QDataStream &in, CZT2LogElement &dest) +////{ +////// quint32 NbLogEntry = source.mZTLogData.size(); +////// quint32 NbDetections = source.mZTDetections.size(); +////// quint32 LogType = source.mZTLogType; + +////// dest >> MagicNbr >> LogType >> NbLogEntry >> NbDetections; + +////// for(unsigned int i = 0; i < NbLogEntry; i++) +////// { +////// out << *source.mZTLogData->at(i); +////// } + +////// //write detections +////// for(unsigned int i =0; i < NbDetections; i++) +////// { +////// out << *source.mZTDetections->at(i); +////// } +//// return in; +////} diff --git a/sources/LogMgr.h b/sources/LogMgr.h new file mode 100644 index 0000000..8667b46 --- /dev/null +++ b/sources/LogMgr.h @@ -0,0 +1,121 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef LOGMGR_H +#define LOGMGR_H + +#include "ZTData.h" +#include "GlobalDefine.h" +#include +#include + +class CLogElement +{ +public: + unsigned int mZTLogType; + virtual ~CLogElement(); +}; +//QDataStream &operator<<(QDataStream &out, const CLogElement &source); +//QDataStream &operator>>(QDataStream &in, CLogElement &dest); + +class CZT1LogElement : public CLogElement +{ +public: + CZT1LogElement(){mZTLogType=ZT1_LOG_TYPE;} + ~CZT1LogElement(); + QDateTime mPassageDateTime; + QVector mZTLogData; + QVector mZTDetections; + quint32 mTrainType; + quint32 mNbElements; + quint64 mThreadDataStartTime, mThreadDataEndTime; + QString mLogFileName; + qreal mMeanSpeed; + CZT1FlagsData mFlags; + QString mStationName; +}; +//QDataStream &operator<<(QDataStream &out, const CZT1LogElement &source); +//QDataStream &operator>>(QDataStream &in, CZT1LogElement &dest); + +class CZT2LogElement : public CLogElement +{ +public: + CZT2LogElement(){mZTLogType = ZT2_LOG_TYPE;} + ~CZT2LogElement(); + QDateTime mPassageDateTime; + QVector mZTLogData; + QVector mZTDetections; + QString mLogFileName; + quint32 mNbElements; + CZT2FlagsData mFlags; + QString mStationName; +}; + +//QDataStream &operator<<(QDataStream &out, const CZT2LogElement &source); +//QDataStream &operator>>(QDataStream &in, CZT2LogElement &dest); + +class CLogMgr +{ +public: + CLogMgr(); + ~CLogMgr(); + unsigned int GetLogsCount(); + QList *GetLogsList(); + QFileInfoList GetLogsFilenameList(); + +// unsigned int CleanLogsOnDisk(qint32 MaxNbLogs, qint64 MaxSize); + unsigned int CleanUpLogs(); + unsigned int ParseLogs(bool KeepData = false); + unsigned int ParseNewLog(QString FileName, bool KeepData = false,bool CleanupLogs = true); + CLogElement* LoadLogData(CLogElement * Element); + unsigned int FreeLogData(CLogElement * Element); + unsigned int InitSteppedLogParsing(); + bool ParseNextLog(); + int DeleteErrorLogs(bool ZT1 = true, bool ZT2 = true); + int SetMaxLogFilesCount(int count); + int KeepAllMPM10Logs(bool keep); + int KeepAllZT1Logs(bool keep); + int KeepAllZT2Logs(bool keep); + + +private: + QList mPassagesList; + unsigned int DestroyLogList(); + + + QFileInfoList mLogsFilelist; + unsigned int mLogsFileIndex; + + bool mKeepMPM10Logs, mKeepZT1Logs, mKeepZT2Logs; + int mMaxFileCount; + +}; + + + +#endif // LOGMGR_H + diff --git a/sources/MainPanel.cpp b/sources/MainPanel.cpp new file mode 100644 index 0000000..a5811b8 --- /dev/null +++ b/sources/MainPanel.cpp @@ -0,0 +1,194 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe qui crée la scène ainsi que les instances des différents objets + nécessaires à l'affichage. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "MainPanel.h" +#include +#include +#include + +#include +#include +#include +#include "Zonetest.h" + +#include "ZTconfigmgr.h" + + +//#include +//#ifndef Q_OS_WIN32 +//Q_IMPORT_PLUGIN(qjpeg) +//#endif + +Panel::~Panel() +{ + //if(scene) + //delete scene; +// delete mWelcomePage; +// delete mZTMainPage; + +} + +Panel::Panel() +{ + + scene = 0; + mProgramHandle = 0; + + //No Scrollbar + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + + //Speed-up display + setCacheMode(CacheBackground); + setRenderHints(/*QPainter::Antialiasing | */QPainter::SmoothPixmapTransform/* | QPainter::TextAntialiasing*/); + setViewportUpdateMode(QGraphicsView::SmartViewportUpdate/*QGraphicsView::FullViewportUpdate*/); + +// QPixmap background; +// background.load("./Images/GuiBackground.jpg"); +// background = background.scaled(SCREEN_RES_WIDTH,SCREEN_RES_HEIGHT); + + + QLinearGradient BackgroundGradient(QPointF(rect().width()/2,0),QPointF(rect().width()/2,rect().height())); + BackgroundGradient.setColorAt(0.5,QColor(128,158,222)); + BackgroundGradient.setColorAt(1,Qt::white); + QBrush BkBrush(BackgroundGradient); + setBackgroundBrush(BkBrush); + + // QRectF bounds(0,0, QApplication::desktop()->geometry().width(),QApplication::desktop()->geometry().height()); + QRectF bounds(0,0, SCREEN_RES_WIDTH,SCREEN_RES_HEIGHT); + scene = new QGraphicsScene(bounds, this); + setScene(scene); + + //resize(QApplication::desktop()->geometry().width(),QApplication::desktop()->geometry().height()); + + resize(SCREEN_RES_WIDTH,SCREEN_RES_HEIGHT); + //////////////////////// + + setMouseTracking(true); + + mWelcomePage = new CWelcomePage(); + mZTMainPage = new CZTPage(); + mOptionsPage = new COptionsPage(); + mFunctionSelectPage = new CFunctionSelectionPage(); + mLogsListPage = new CLogsListPage(); + mLogViewPage = new CLogViewPage(); + mEngineeringPage = new CEngineeringPage(); + mMaintenancePage = new CMaintenancePage(); + mGeneralSettingsPage = new CGeneralSettingsPage(); + mZTLogViewerPage = new CZTLogViewerPage(); + + scene->addItem(mWelcomePage); + scene->addItem(mZTMainPage); + scene->addItem(mOptionsPage); + scene->addItem(mFunctionSelectPage); + scene->addItem(mLogsListPage); + scene->addItem(mLogViewPage); + scene->addItem(mEngineeringPage); + scene->addItem(mMaintenancePage); + scene->addItem(mGeneralSettingsPage); + scene->addItem(mZTLogViewerPage); + + mZTMainPage->setPos(0,0); + mZTMainPage->hide(); + mZTMainPage->setZValue(0); + scene->addItem(mZTMainPage->mExitPasswordPrompt); + + mWelcomePage->setPos(0,0); + mWelcomePage->show(); + mWelcomePage->setZValue(1); + + mOptionsPage->setPos(312,100); + mOptionsPage->hide(); + mOptionsPage->resize(400,400); + mOptionsPage->setZValue(1); + + mFunctionSelectPage->setPos(212,184); + mFunctionSelectPage->hide(); + mFunctionSelectPage->resize(600,400); + mFunctionSelectPage->setZValue(1); + + mLogsListPage->setPos(62,84); + mLogsListPage->hide(); + mLogsListPage->resize(900,600); + mLogsListPage->setZValue(1); + + mLogViewPage->setPos(0,0); + mLogViewPage->resize(1024,768); + mLogViewPage->setZValue(1); + mLogViewPage->hide(); + + mEngineeringPage->setPos(10,10); + mEngineeringPage->resize(SCREEN_RES_WIDTH-20,SCREEN_RES_HEIGHT-20); + mEngineeringPage->setZValue(1); + mEngineeringPage->hide(); + scene->addItem(mEngineeringPage->mPasswordPrompt); + + mMaintenancePage->setPos(112,84); + mMaintenancePage->hide(); + mMaintenancePage->resize(800,600); + mMaintenancePage->setZValue(1); + + mGeneralSettingsPage->setPos(112,84); + mGeneralSettingsPage->hide(); + mGeneralSettingsPage->resize(800,600); + mGeneralSettingsPage->setZValue(1); + + mZTLogViewerPage->setPos(112,84); + mZTLogViewerPage->hide(); + mZTLogViewerPage->resize(800,600); + mZTLogViewerPage->setZValue(1); + + installEventFilter(mLogViewPage); + +} + +void Panel::HideWelcomePage() +{ + mWelcomePage->hide(); +} + +void Panel::ShowMainPage() +{ + mZTMainPage->show(); +} + +void Panel::HideMainPAge() +{ + mZTMainPage->hide(); +} + +//void Panel::mousePressEvent(QGraphicsSceneMouseEvent *event) +//{ +//} + +void Panel::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event) + mProgramHandle->ApplicationQuit(); +} + diff --git a/sources/MainPanel.h b/sources/MainPanel.h new file mode 100644 index 0000000..29cc52e --- /dev/null +++ b/sources/MainPanel.h @@ -0,0 +1,89 @@ +#ifndef PANEL_H +#define PANEL_H + +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#include +#include +#include + +#include "Guipage.h" +#include "WelcomePage.h" +#include "ZTPage.h" +#include "OptionsPage.h" +#include "FunctionSelectionPage.h" +#include "LogsListPage.h" +#include "LogViewPage.h" +#include "EngineeringPage.h" +#include "MaintenancePage.h" +#include "GeneralSettingsPage.h" +#include "ZTLogViewerPage.h" + +class CZoneTest; + +class Panel : public QGraphicsView +{ + Q_OBJECT + //QFile Ledfd; + +public: + Panel(); + ~Panel(); + // virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + + void HideWelcomePage(void); + + void ShowMainPage(void); + void HideMainPAge(void); + virtual void closeEvent(QCloseEvent *); + CZoneTest *mProgramHandle; + + +public slots: +// void AudioPageButtonClicked(); +// void mMailMsgButtonPressed(); +// void BusScheduleButtonPressed(); +// void DayScheduleButtonPressed(); + +public: + + QGraphicsScene *scene; + CWelcomePage *mWelcomePage; + CZTPage *mZTMainPage; + COptionsPage *mOptionsPage; + CFunctionSelectionPage *mFunctionSelectPage; + CLogsListPage *mLogsListPage; + CLogViewPage *mLogViewPage; + CEngineeringPage *mEngineeringPage; + CMaintenancePage *mMaintenancePage; + CGeneralSettingsPage *mGeneralSettingsPage; + CZTLogViewerPage *mZTLogViewerPage; +}; + +#endif // PANEL_H diff --git a/sources/MixedModule.cpp b/sources/MixedModule.cpp new file mode 100644 index 0000000..ed6308f --- /dev/null +++ b/sources/MixedModule.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme des modules d'entrées/sorties externes + mixtes (SEAI/0 470). + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "MixedModule.h" + +CMixedModule::~CMixedModule() +{ + +} diff --git a/sources/MixedModule.h b/sources/MixedModule.h new file mode 100644 index 0000000..805181e --- /dev/null +++ b/sources/MixedModule.h @@ -0,0 +1,43 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef MIXEDMODULE_H +#define MIXEDMODULE_H + +#include "IOModule.h" + + +class CMixedModule: public CIOModule +{ +public: + + virtual ~CMixedModule(); + virtual unsigned int GetAnalogInput(int Channel, int *Data) = 0; + +}; + +#endif // MIXEDMODULE_H diff --git a/sources/Modbus/ModbusBackend.cpp b/sources/Modbus/ModbusBackend.cpp new file mode 100644 index 0000000..ccd5b95 --- /dev/null +++ b/sources/Modbus/ModbusBackend.cpp @@ -0,0 +1,687 @@ +#include "ModbusBackend.h" +#include "QBuffer" +#include "EngLog.h" +#include "ZTLog.h" + +CModbusBackend::CModbusBackend(CModbusRepository *Repo) +{ + mModbusTCPSocketHandle = 0; + mDataLinkValid = false; + mModbusRepo = Repo; + mModbusMode = MODBUS_INVALID_MODE; + mTransactionIDCounter = 0; + mDeviceID = 9;//0xFF; + + mModbusMaxRetry = MODBUS_RETRY_MAX_COUNT; + mModbusRequestTimeout = MODBUS_RETRY_DELAY; +} + +CModbusBackend::~CModbusBackend() +{ + +} + +void CModbusBackend::ModbusDataReady() +{ + + CModbusTransaction Transaction; + QByteArray InData = mModbusTCPSocketHandle->readAll(); + + QBuffer FileBuffer(&InData); + FileBuffer.open(QIODevice::ReadOnly); + FileBuffer.seek(0); + QDataStream *TransactionDataStrm = new QDataStream(&FileBuffer); + *TransactionDataStrm >> Transaction.mHeader; + *TransactionDataStrm >> Transaction.mPDU.mFunctionCode; + Transaction.mPDU.mData = InData.right(Transaction.mHeader.mMessageLength - 2); //-2 to remove Device ID and Function Code. + + qDebug("modbus data received %s",InData.toHex().data()); + qDebug("Transaction ID 0x%X",Transaction.mHeader.mTransactionID); + qDebug("Message Length %d",Transaction.mHeader.mMessageLength); + qDebug("Protocol ID 0x%X",Transaction.mHeader.mProtocolID); + qDebug("Unit ID 0x%X",Transaction.mHeader.mUnitID); + + qDebug("Function Code 0x%X",Transaction.mPDU.mFunctionCode); + qDebug("Data %s",Transaction.mPDU.mData.toHex().data()); + + if(mModbusMode == MODBUS_MASTER_MODE) + { + AnalyzeModbusResponse(Transaction); + } + else if( mModbusMode == MODBUS_SLAVE_MODE) + { + AnalyzeModbusRequest(Transaction); + } + else + { + CEngLog::instance()->AddLogString("Erreur Modbus: "); + } +} + +void CModbusBackend::ModbusLinkDisconnected() +{ +// qDebug("Modbus link disconnected"); + mDataLinkValid = false; +} + + +//In client mode. This is the request from the master. +int CModbusBackend::AnalyzeModbusRequest(CModbusTransaction Transaction) +{ + if(Transaction.mHeader.mProtocolID != 0) + { + //Invalid protocol... what can we do? + return 0; + } + + switch(Transaction.mPDU.mFunctionCode) + { + case MODBUS_FCT_READ_HOLDING_REGISTERS: + { + bool ok = true; + unsigned short StartAdress = 0; + StartAdress = Transaction.mPDU.mData[0]&0xFF; + StartAdress <<= 8; + StartAdress += Transaction.mPDU.mData[1]&0xFF; + unsigned short NbRegisters = 0; + NbRegisters = Transaction.mPDU.mData[2]&0xFF; + NbRegisters <<= 8; + NbRegisters += Transaction.mPDU.mData[3]&0xFF; + + //Validate nb of registers + if(NbRegisters < 1 || NbRegisters > MODBUS_MAX_NB_REGISTERS) + { + SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE); + ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS); + return 0; + } + + //Validate data range + if(!mModbusRepo->IsHRValid(StartAdress,NbRegisters)) + { + qDebug("Reg invalid"); + //Send negative response + SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS); + ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_READ_HOLDING_REGISTERS); + return 0; + } + + QByteArray data = mModbusRepo->GetHRData(StartAdress,NbRegisters,&ok); + + qDebug("Slave Rx Read Holding Registers. Address: %d, Nb Reg: %d",StartAdress, NbRegisters); + qDebug("Data: %s",data.toHex().data()); + + //The response to a HR reading needs the byte count before the data. + quint8 ByteCount = data.size(); + data.prepend(ByteCount); + SendModbusResponse(Transaction, data); + + //All OK + + break; + } + case MODBUS_WRITE_SINGLE_REGISTER: + { + unsigned short StartAdress = 0; + + StartAdress = Transaction.mPDU.mData[0]&0xFF; + StartAdress <<= 8; + StartAdress += Transaction.mPDU.mData[1]&0xFF; + + //Validate data range + if(!mModbusRepo->IsHRValid(StartAdress,1)) + { + qDebug("Reg invalid"); + //Send negative response + SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS); + ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_WRITE_SINGLE_REGISTER); + return 0; + } + + //Extract data. + QByteArray data = Transaction.mPDU.mData.right(2); + + //Write register data + mModbusRepo->WriteHRData(StartAdress,1,data); + + qDebug("Slave Rx Write Single Register. Address: %d, Value: 0x%s",StartAdress, data.toHex().data()); + qDebug("Data: %s",data.toHex().data()); + + data = Transaction.mPDU.mData.left(4); //The response corresponds to the Reg. Address & the value. Which is the first 4 bytes of the initial request. + SendModbusResponse(Transaction, data); + RegistersDatabaseUpdated(StartAdress,1); + + break; + } + case MODBUS_FCT_WRITE_MULTIPLE_REGISTERS: + { + unsigned short StartAdress = 0; + StartAdress = Transaction.mPDU.mData[0]&0xFF; + StartAdress <<= 8; + StartAdress += Transaction.mPDU.mData[1]&0xFF; + + unsigned short NbRegisters = 0; + NbRegisters = Transaction.mPDU.mData[2]&0xFF; + NbRegisters <<= 8; + NbRegisters += Transaction.mPDU.mData[3]&0xFF; + + quint8 ByteCount = Transaction.mPDU.mData[4]; + + //Validate nb of registers + if(NbRegisters < 1 || NbRegisters > 0x7D || ByteCount != (NbRegisters*2)) + { + qDebug("Invalid register number or byte count "); + SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE); + ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS); + return 0; + } + + //Validate data range + if(!mModbusRepo->IsHRValid(StartAdress,NbRegisters)) + { + qDebug("Reg invalid"); + //Send negative response + SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS); + ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS); + return 0; + } + + //Extract data. + QByteArray data = Transaction.mPDU.mData.right(ByteCount); + + //Write register data + mModbusRepo->WriteHRData(StartAdress,NbRegisters,data); + + qDebug("Slave Rx Write Multiple Registers. Address: %d, Nb Reg: %d",StartAdress, NbRegisters); + qDebug("Data: %s",data.toHex().data()); + + data = Transaction.mPDU.mData.left(4); //The response corresponds to the Start Adress and Nb of Regs. Which is the first 4 bytes of the initial request. + SendModbusResponse(Transaction, data); + + RegistersDatabaseUpdated(StartAdress,NbRegisters); + + break; + } + default: + { + //Received "Illegal function code". Send the exception code to master + //TODO: Log this. + qDebug("Slave received illegal function code from master: 0x%x",Transaction.mPDU.mFunctionCode); + SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_FCT); + ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_FCT,Transaction.mPDU.mFunctionCode); + break; + } + } + + + return 1; +} + +int CModbusBackend::SendModbusResponse(CModbusTransaction RequestTransaction, QByteArray Data) +{ + QByteArray ModbusPacket; + + QBuffer Buffer(&ModbusPacket); + Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered); + Buffer.seek(0); + QDataStream *PacketDataStrm = new QDataStream(&Buffer); + + //For a response, the header will be the same as the original request, except for the msg. length. + //Set the appropriate msg length. + RequestTransaction.mHeader.mMessageLength = Data.size() + 2; //+2 to add function code & Unit ID. + RequestTransaction.mPDU.mData = Data; + + *PacketDataStrm << RequestTransaction.mHeader; + *PacketDataStrm << RequestTransaction.mPDU.mFunctionCode; + Buffer.close(); + ModbusPacket.append(Data); + + + qDebug("Response packet: %s",ModbusPacket.toHex().data()); + + mModbusTCPSocketHandle->write(ModbusPacket); + + delete PacketDataStrm; + + return RET_OK; +} + +//In Master mode. This is the response from slave to a previously sent request. +int CModbusBackend::AnalyzeModbusResponse(CModbusTransaction Transaction) +{ + if(Transaction.mHeader.mProtocolID != 0) + { + //Invalid protocol... what can we do? + return RET_ERROR; + } + + //Find matching request and remove it from the queue... + CModbusRequest *Request; + bool Found = false; + for(int i = 0; i < mRequestsList.size(); i++) + { + if(mRequestsList.at(i)->mHeader.mTransactionID == Transaction.mHeader.mTransactionID) + { + Request = mRequestsList.takeAt(i); //Remove from queue and keep a copy + Request->mRequestTimer->stop(); //Stop the resend timer + Found = true; + } + } + + if(Found == false) + { + //Invalid request number. This should happen only if a very long delay exists in the comm. + //TODO: Log this... + qDebug("Master received response to a non existent request!!!"); + return RET_ERROR; + } + + //check if we have an exception response + if((Transaction.mPDU.mFunctionCode & MODBUS_EXCEPTION_FCT_MASK) != 0) + { + //we have an exception response... something went wrong. + quint8 ExceptionCode = Transaction.mPDU.mData[0]; + + //TODO: Manage this! + qDebug("Master Rx exception code %d to request %d",ExceptionCode,Request->mPDU.mFunctionCode); + emit ModbusResponseException(ExceptionCode,Request->mPDU.mFunctionCode); + delete Request; + return RET_ERROR; + } + + switch(Transaction.mPDU.mFunctionCode) + { + case MODBUS_FCT_READ_HOLDING_REGISTERS: + { + quint8 ByteCount = 0; + ByteCount = Transaction.mPDU.mData.at(0); + + if((Request->mNbRegisters*2) != ByteCount) + { + //Inconsistency between the data range and the data count. + //TODO: Log the error. + qDebug("Master eceived a wrong data size in response for a MODBUS_FCT_READ_HOLDING_REGISTERS request"); + emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS); + delete Request; + return RET_ERROR; + } + + QByteArray RegisterValues = Transaction.mPDU.mData.right(ByteCount); + + + qDebug("Master Rx Read Holding Registers Response."); + qDebug("Data: %s",RegisterValues.toHex().data()); + + mModbusRepo->WriteHRData(Request->mStartAddress,Request->mNbRegisters,RegisterValues); + RegistersDatabaseUpdated(Request->mStartAddress, Request->mNbRegisters); + + break; + } + case MODBUS_WRITE_SINGLE_REGISTER: + { + quint16 RegAddress = 0; + RegAddress = Transaction.mPDU.mData[0]&0xFF; + RegAddress <<= 8; + RegAddress += Transaction.mPDU.mData[1]&0xFF; + + if(Request->mStartAddress != RegAddress) + { + //Inconsistency between the request Adress and response Adress. + //TODO: Log the error. + qDebug("Master received a wrong Register Adress in response for a MODBUS_WRITE_SINGLE_REGISTER request"); + emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_WRITE_SINGLE_REGISTER); + delete Request; + return RET_ERROR; + } + qDebug("Master Rx Write Single Register response. Address: %d,",RegAddress); + qDebug("Data: %s",Transaction.mPDU.mData.toHex().data()); + + //Everything seems good. + + break; + } + case MODBUS_FCT_WRITE_MULTIPLE_REGISTERS: + { + unsigned short StartAdress = 0; + StartAdress = Transaction.mPDU.mData[0]&0xFF; + StartAdress <<= 8; + StartAdress += Transaction.mPDU.mData[1]&0xFF; + + unsigned short NbRegisters = 0; + NbRegisters = Transaction.mPDU.mData[2]&0xFF; + NbRegisters <<= 8; + NbRegisters += Transaction.mPDU.mData[3]&0xFF; + + if(StartAdress != Request->mStartAddress || NbRegisters != Request->mNbRegisters) + { + //Inconsistency between the request Adress or NbRegisters and response. + //TODO: Log the error. + qDebug("Master Received a wrong Register Adress or NbRegisters in response for a MODBUS_FCT_WRITE_MULTIPLE_REGISTERS request"); + emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS); + delete Request; + return RET_ERROR; + } + + qDebug("Master Rx Write Multiple Registers response. Address: %d, Nb Reg: %d",StartAdress, NbRegisters); + qDebug("Data: %s",Transaction.mPDU.mData.toHex().data()); + + //All is good. + + break; + } + default: + { + //Received "Illegal function code" response + //TODO: Log this. + qDebug("Master received illegal function code 0x%x",Transaction.mPDU.mFunctionCode); + emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_FCT,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS); + break; + } + } + + + delete Request; + return 1; +} + +int CModbusBackend::SendModbusRequest(CModbusRequest *Request) +{ + QByteArray ModbusPacket; + + QBuffer Buffer(&ModbusPacket); + Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered); + Buffer.seek(0); + QDataStream *PacketDataStrm = new QDataStream(&Buffer); + + *PacketDataStrm << Request->mHeader; + *PacketDataStrm << Request->mPDU.mFunctionCode; + Buffer.close(); + ModbusPacket.append(Request->mPDU.mData); + + qDebug("Request packet: %s",ModbusPacket.toHex().data()); + + mModbusTCPSocketHandle->write(ModbusPacket); + return RET_OK; +} + +int CModbusBackend::SendErrorResponse(CModbusTransaction RequestTransaction, quint8 ErrorCode) +{ + QByteArray ModbusPacket; + + QBuffer Buffer(&ModbusPacket); + Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered); + Buffer.seek(0); + QDataStream *PacketDataStrm = new QDataStream(&Buffer); + + //For a response, the header will be the same as the original request, except for the msg. length. + //Set the appropriate msg length. + RequestTransaction.mHeader.mMessageLength = 3; //Unit ID, function code & Exception code. + + *PacketDataStrm << RequestTransaction.mHeader; + Buffer.close(); + ModbusPacket.append(RequestTransaction.mPDU.mFunctionCode + 0x80); + ModbusPacket.append(ErrorCode); + + + CEngLog::instance()->AddLogString(QString("Modbus: Envoi d'un code d'un code d'erreur. Error Code %1, Error Packet: %2").arg(ErrorCode).arg(ModbusPacket.toHex().data())); + // qDebug("Sending error code %d. Error packet: %s",ErrorCode,ModbusPacket.toHex().data()); + + mModbusTCPSocketHandle->write(ModbusPacket); + + delete PacketDataStrm; + + return RET_OK; +} + + +int CModbusBackend::SendReadHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount) +{ + //First, validate that the reading range is within our repo + if(mModbusRepo->IsHRValid(StartAddress,RegisterCount) == false) + { + CEngLog::instance()->AddLogString("Trying to send a read HR in an invalid range"); + return RET_ERROR; + } + + //Create a request. + CModbusRequest *NewRequest = new CModbusRequest; + NewRequest->mStartAddress = StartAddress; + NewRequest->mNbRegisters = RegisterCount; + connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired())); + + NewRequest->mPDU.mData.clear(); + NewRequest->mPDU.mFunctionCode = MODBUS_FCT_READ_HOLDING_REGISTERS; + + quint8 HighByte, LowByte; + LowByte = StartAddress & 0x00FF; + HighByte = (StartAddress >> 8) & 0x00FF; + NewRequest->mPDU.mData.append(HighByte); + NewRequest->mPDU.mData.append(LowByte); + + LowByte = RegisterCount & 0x00FF; + HighByte = (RegisterCount >> 8) & 0x00FF; + NewRequest->mPDU.mData.append(HighByte); + NewRequest->mPDU.mData.append(LowByte); + + NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2; + NewRequest->mHeader.mProtocolID = 0; + NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID(); + NewRequest->mHeader.mUnitID = mDeviceID; + + mRequestsList.append(NewRequest); + + SendModbusRequest(NewRequest); + + NewRequest->mRequestTimer->start(mModbusRequestTimeout); + + + return RET_OK; + +} + +int CModbusBackend::SendWriteHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount) +{ + //First, validate that the reading range is within our repo + if(mModbusRepo->IsHRValid(StartAddress,RegisterCount) == false) + { + CEngLog::instance()->AddLogString("Trying to send a Write HR in an invalid range SendWriteHoldingRegistersRequest()"); + return RET_ERROR; + } + + if(RegisterCount > MODBUS_MAX_NB_REGISTERS) + { + return RET_ERROR; + } + + //Get data. + bool OK; + QByteArray RegData = mModbusRepo->GetHRData(StartAddress,RegisterCount,&OK); + if(OK == false) + { + return RET_ERROR; + } + + //Create a request. + CModbusRequest *NewRequest = new CModbusRequest; + NewRequest->mStartAddress = StartAddress; + NewRequest->mNbRegisters = RegisterCount; + connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired())); + + NewRequest->mPDU.mData.clear(); + NewRequest->mPDU.mFunctionCode = MODBUS_FCT_WRITE_MULTIPLE_REGISTERS; + + quint8 HighByte, LowByte; + LowByte = StartAddress & 0x00FF; + HighByte = (StartAddress >> 8) & 0x00FF; + NewRequest->mPDU.mData.append(HighByte); + NewRequest->mPDU.mData.append(LowByte); + + LowByte = RegisterCount & 0x00FF; + HighByte = (RegisterCount >> 8) & 0x00FF; + NewRequest->mPDU.mData.append(HighByte); + NewRequest->mPDU.mData.append(LowByte); + + NewRequest->mPDU.mData.append(RegData); + + NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2; + NewRequest->mHeader.mProtocolID = 0; + NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID(); + NewRequest->mHeader.mUnitID = mDeviceID; + + mRequestsList.append(NewRequest); + + SendModbusRequest(NewRequest); + + NewRequest->mRequestTimer->start(mModbusRequestTimeout); + + + return RET_OK; +} + +int CModbusBackend::SendWriteSingleRegisterRequest(quint16 Address) +{ + //First, validate that the reading range is within our repo + if(mModbusRepo->IsHRValid(Address,1) == false) + { + CEngLog::instance()->AddLogString("Trying to send a Write HR in an invalid range SendWriteSingleRegisterRequest()"); + return RET_ERROR; + } + + //Get data. + bool OK; + QByteArray RegData = mModbusRepo->GetHRData(Address,1,&OK); + if(OK == false) + { + return RET_ERROR; + } + + //Create a request. + CModbusRequest *NewRequest = new CModbusRequest; + NewRequest->mStartAddress = Address; + NewRequest->mNbRegisters = 1; + connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired())); + + NewRequest->mPDU.mData.clear(); + NewRequest->mPDU.mFunctionCode = MODBUS_WRITE_SINGLE_REGISTER; + + quint8 HighByte, LowByte; + LowByte = Address & 0x00FF; + HighByte = (Address >> 8) & 0x00FF; + NewRequest->mPDU.mData.append(HighByte); + NewRequest->mPDU.mData.append(LowByte); + + NewRequest->mPDU.mData.append(RegData); + + NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2; + NewRequest->mHeader.mProtocolID = 0; + NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID(); + NewRequest->mHeader.mUnitID = mDeviceID; + + mRequestsList.append(NewRequest); + + SendModbusRequest(NewRequest); + + NewRequest->mRequestTimer->start(mModbusRequestTimeout); + + + return RET_OK; +} + +void CModbusBackend::RequestTimerExpired() +{ + //find the expired request + for(int i = 0; i < mRequestsList.size(); i++) + { + if(mRequestsList.at(i)->mRequestTimer->isActive() == false) + { + if(mRequestsList.at(i)->mRetries >= mModbusMaxRetry) + { + //The max number of retry has been reached. The device is probably offline. + + CZTLog::instance()->AddLogString("Modbus Maître: Nombre maximal de tentatives sans réponse atteint avec le partenaire",true); + + + delete mRequestsList[i]; + mRequestsList.removeAt(i); + + + //TODO: Manage this situation (log?) + + return; + } + else + { + SendModbusRequest(mRequestsList[i]); + mRequestsList.at(i)->mRequestTimer->start(mModbusRequestTimeout); + mRequestsList[i]->mRetries++; + } + } + } +} + +quint16 CModbusBackend::GetNewTransactionID() +{ + quint16 ID = mTransactionIDCounter++; + + if(mTransactionIDCounter == 0xFFFF - 10) + { + mTransactionIDCounter = 0; + } + + return ID; +} + + + +CModbusRequest::CModbusRequest(): + mRetries(0) +{ + mRequestTimer = new QTimer; + mRequestTimer->setSingleShot(true); +} +CModbusRequest::~CModbusRequest() +{ + delete mRequestTimer; +} + + + + + +QDataStream &operator<<(QDataStream &out, const CModbusHeader &source) +{ + out << source.mTransactionID + << source.mProtocolID + << source.mMessageLength + << source.mUnitID + ; + + return out; +} + +QDataStream &operator>>(QDataStream &in, CModbusHeader &dest) +{ + in >> dest.mTransactionID + >> dest.mProtocolID + >> dest.mMessageLength + >> dest.mUnitID + ; + + return in; +} + +//Virtual function that should not even get called... +void CModbusBackend::ModbusResponseException(quint8 ExceptionCode, quint8 FctCode) +{ + Q_UNUSED(ExceptionCode) + Q_UNUSED(FctCode) + CEngLog::instance()->AddLogString("ModbusResponseException called from within slave object... weird stuff!"); +} + +//Virtual function that should not even get called... +void CModbusBackend::ModbusRequestException(quint8 ExceptionCode, quint8 FctCode) +{ + Q_UNUSED(ExceptionCode) + Q_UNUSED(FctCode) + CEngLog::instance()->AddLogString("ModbusResponseException called from within master object... weird stuff!"); +} diff --git a/sources/Modbus/ModbusBackend.h b/sources/Modbus/ModbusBackend.h new file mode 100644 index 0000000..99f0578 --- /dev/null +++ b/sources/Modbus/ModbusBackend.h @@ -0,0 +1,170 @@ +#ifndef CMODBUSBACKEND_H +#define CMODBUSBACKEND_H +#include +#include +#include "ModbusRepository.h" +#include + + +#define MODBUS_EXCEPTION_FCT_MASK 0x80 +#define MODBUS_RETRY_DELAY 2000 //millisecs +#define MODBUS_RETRY_MAX_COUNT 2 //resend an unanswered request this many times +#define MODBUS_MAX_NB_REGISTERS 0x7D + +enum eModbusFunctions +{ + MODBUS_FCT_READ_HOLDING_REGISTERS = 3, + MODBUS_WRITE_SINGLE_REGISTER = 6, + MODBUS_FCT_WRITE_MULTIPLE_REGISTERS = 16 +}; + +enum eModbusExceptionCodes +{ + MODBUS_EXCEPTION_ILLEGAL_FCT = 1, + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS = 2, + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE = 3, + MODBUS_EXCEPTION_SERVER_DEVICE_FAILURE = 4, + MODBUS_EXCEPTION_ACKNOWLEDGE = 5, + MODBUS_EXCEPTION_SERVER_DEVICE_BUSY = 6, + MODBUS_EXCEPTION_MEMORY_PARITY_ERROR = 8, + MODBUS_EXCEPTION_GATEWAY_PATH_UNAVAILABLE = 10, + MODBUS_EXCEPTION_GATEWAY_TARGET_DEV_NOT_RESPONDING = 11 +}; + +enum eModbusModes +{ + MODBUS_MASTER_MODE, + MODBUS_SLAVE_MODE, + MODBUS_INVALID_MODE +}; + +class CModbusException +{ +public: + +}; + +class CModbusPDU +{ +public: + qint8 mFunctionCode; + QByteArray mData; +}; + +class CModbusHeader +{ +public: + qint16 mTransactionID; + qint16 mProtocolID; + qint16 mMessageLength; + qint8 mUnitID; +}; + +class CModbusTransaction +{ +public: + CModbusHeader mHeader; + CModbusPDU mPDU; +}; + +class CModbusRequest : public CModbusTransaction +{ +public: + CModbusRequest(); + ~CModbusRequest(); + int mRetries; + QTimer *mRequestTimer; + quint16 mStartAddress, mNbRegisters; //For convinience... +}; + +class CModbusBackend : public QObject +{ + Q_OBJECT + + + +private: +enum eModbusMasterSMStates +{ + MODBUS_SM_WAIT_FOR__STATE +}; + +enum eModbusSlaveSMStates +{ + +}; + +public: + CModbusBackend(CModbusRepository *Repo); + virtual ~CModbusBackend(); + QTcpSocket *mModbusTCPSocketHandle; + CModbusRepository *mModbusRepo; + + bool mDataLinkValid; + int mModbusMode; + qint8 mDeviceID; + void ModbusLinkDisconnected(); + void SetDeviceID(qint8 ID){mDeviceID = ID;} + + //Master (client) + int SendReadHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); + int SendWriteHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); + int SendWriteSingleRegisterRequest(quint16 Address); + + + + + virtual void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length) = 0; + + //Master Exception + virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode); + + //Slave Exception + virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode); + + +private: + + + + //Slave (server) + int AnalyzeModbusRequest(CModbusTransaction Transaction); + int ModbusStateMachine(int Event, QByteArray Data); + int SendModbusResponse(CModbusTransaction RequestTransaction, QByteArray Data); + int SendErrorResponse(CModbusTransaction RequestTransaction, quint8 ErrorCode); + + //Master (client) + QList mRequestsList; + int SendModbusRequest(CModbusRequest *Request); + quint16 GetNewTransactionID(); + int AnalyzeModbusResponse(CModbusTransaction Transaction); + + quint16 mTransactionIDCounter; + int mModbusRequestTimeout; + int mModbusMaxRetry; + +signals: + +// void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length); + +// //Master signals +// void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode); + +//// //Slave signals +// void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode); + + + +public slots: + void ModbusDataReady(); + + void RequestTimerExpired(); + + +}; + + +QDataStream &operator<<(QDataStream &out, const CModbusHeader &source); +QDataStream &operator>>(QDataStream &in, CModbusHeader &dest); + +#endif // CMODBUSBACKEND_H diff --git a/sources/Modbus/ModbusCCDefs.h b/sources/Modbus/ModbusCCDefs.h new file mode 100644 index 0000000..e0e04d5 --- /dev/null +++ b/sources/Modbus/ModbusCCDefs.h @@ -0,0 +1,105 @@ +#ifndef PROTOCOLDEFS_H +#define PROTOCOLDEFS_H + + + +//ZT - CC modbus table masks + + +//Flags definitions for HR2000 +#define ZT1_PP_INT_FLAG_MASK_1 0x0001 +#define ZT1_PP_INT_FLAG_MASK_2 0x0002 +#define ZT1_PP_INT_FLAG_MASK_3 0x0004 +#define ZT1_PP_INT_FLAG_MASK_4 0x0008 +#define ZT1_PP_EXT_FLAG_MASK_1 0x0010 +#define ZT1_PP_EXT_FLAG_MASK_2 0x0020 +#define ZT1_PP_EXT_FLAG_MASK_3 0x0040 +#define ZT1_PP_EXT_FLAG_MASK_4 0x0080 +#define ZT1_PG_FLAG_MASK_1 0x0100 +#define ZT1_PG_FLAG_MASK_2 0x0200 +#define ZT1_PG_FLAG_MASK_3 0x0400 +#define ZT1_PG_FLAG_MASK_4 0x0800 +#define ZT1_FN_FLAG_MASK_1 0x1000 +#define ZT1_FN_FLAG_MASK_2 0x2000 +#define ZT1_FN_FLAG_MASK_3 0x4000 +#define ZT1_FN_FLAG_MASK_4 0x8000 + +//Flags definitions for HR2017 +#define ZT2_PP_INT_FLAG_MASK_1 0x0001 +#define ZT2_PP_INT_FLAG_MASK_2 0x0002 +#define ZT2_PP_INT_FLAG_MASK_3 0x0004 +#define ZT2_PP_INT_FLAG_MASK_4 0x0008 +#define ZT2_PP_EXT_FLAG_MASK_1 0x0010 +#define ZT2_PP_EXT_FLAG_MASK_2 0x0020 +#define ZT2_PP_EXT_FLAG_MASK_3 0x0040 +#define ZT2_PP_EXT_FLAG_MASK_4 0x0080 + +//Flags definitions for HR2026 +#define ZT1_V00_ALARM_FLAG_MASK 0x0001 +#define ZT1_PEQ1_ALARM_FLAG_MASK 0x0002 +#define ZT1_ALARM_ITI_FLAG_MASK 0x8000 +#define ZT2_V02_ALARM_FLAG_MASK 0x0004 +#define ZT2_PEQ2_ALARM_FLAG_MASK 0x0008 + + + +//Register addressing +//Outgoing +#define MODBUS_ZT_DATA_BASE_REG 2000 +#define MODBUS_ZT_TABLE_DATA_SIZE 28 //Taille de la table = 28 registres + +#define MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD 2000 +#define MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD 2017 +#define MODBUS_MISC_DATA_BASE_REG_ADD 2026 +#define MODBUS_ZT_WATCHDOG_REG_ADD 2027 + +#define MODBUS_ZT1_ALARM_RANKS_BASE_ADD 2001 +#define MODBUS_ZT1_RANK_PP_INT_1_REG_ADD 2001 +#define MODBUS_ZT1_RANK_PP_INT_2_REG_ADD 2002 +#define MODBUS_ZT1_RANK_PP_INT_3_REG_ADD 2003 +#define MODBUS_ZT1_RANK_PP_INT_4_REG_ADD 2004 +#define MODBUS_ZT1_RANK_PP_EXT_1_REG_ADD 2005 +#define MODBUS_ZT1_RANK_PP_EXT_2_REG_ADD 2006 +#define MODBUS_ZT1_RANK_PP_EXT_3_REG_ADD 2007 +#define MODBUS_ZT1_RANK_PP_EXT_4_REG_ADD 2008 +#define MODBUS_ZT1_RANK_PG_1_REG_ADD 2009 +#define MODBUS_ZT1_RANK_PG_2_REG_ADD 2010 +#define MODBUS_ZT1_RANK_PG_3_REG_ADD 2011 +#define MODBUS_ZT1_RANK_PG_4_REG_ADD 2012 +#define MODBUS_ZT1_RANK_FN_1_REG_ADD 2013 +#define MODBUS_ZT1_RANK_FN_2_REG_ADD 2014 +#define MODBUS_ZT1_RANK_FN_3_REG_ADD 2015 +#define MODBUS_ZT1_RANK_FN_4_REG_ADD 2016 + +#define MODBUS_ZT2_ALARM_RANKS_BASE_ADD 2018 +#define MODBUS_ZT2_RANK_PP_INT_1_REG_ADD 2018 +#define MODBUS_ZT2_RANK_PP_INT_2_REG_ADD 2019 +#define MODBUS_ZT2_RANK_PP_INT_3_REG_ADD 2020 +#define MODBUS_ZT2_RANK_PP_INT_4_REG_ADD 2021 +#define MODBUS_ZT2_RANK_PP_EXT_1_REG_ADD 2022 +#define MODBUS_ZT2_RANK_PP_EXT_2_REG_ADD 2023 +#define MODBUS_ZT2_RANK_PP_EXT_3_REG_ADD 2024 +#define MODBUS_ZT2_RANK_PP_EXT_4_REG_ADD 2025 + + + +//Incoming +#define MODBUS_CC_ZTC_ZT1_FLAG_MASK 0x0001 +#define MODBUS_CC_ZTC_ZT2_FLAG_MASK 0x0002 +#define MODBUS_CC_FCYCLE_ZT1_FLAG_MASK 0x0004 +#define MODBUS_CC_FCYCLE_ZT2_FLAG_MASK 0x0008 + +#define MODBUS_CC_DATA_BASE_REG_ADD 2028 +#define MODBUS_CC_TABLE_DATA_SIZE 13 //Taille de la table = 28 registres + + +#define MODBUS_CC_WATCHDOG_BASE_REG_ADD 2028 +#define MODBUS_CC_AN_BASE_REG_ADD 2029 +#define MODBUS_CC_CLK_UPDATE_BASE_REG_ADD 2036 +#define MODUBS_CC_CLK_SEC_BASE_REG_ADD 2037 +#define MODUBS_CC_CLK_HR_MIN_BASE_REG_ADD 2038 +#define MODUBS_CC_CLK_MNT_DAY_BASE_REG_ADD 2039 +#define MODUBS_CC_CLK_YEAR_BASE_REG_ADD 2040 + + +#endif // PROTOCOLDEFS_H diff --git a/sources/Modbus/ModbusCCMgr.cpp b/sources/Modbus/ModbusCCMgr.cpp new file mode 100644 index 0000000..802844a --- /dev/null +++ b/sources/Modbus/ModbusCCMgr.cpp @@ -0,0 +1,67 @@ +#include "ModbusCCMgr.h" +#include "ZTLog.h" +#include "EngLog.h" + + +CModbusCCMgr::CModbusCCMgr(CModbusRepository *Repo, int ModbusPort, int DevID) : + CModbusBackend(Repo) +{ + mModbusServer = new QTcpServer(); + mDeviceID = DevID; + mModbusPort = ModbusPort; + + connect(mModbusServer,SIGNAL(newConnection()),this,SLOT(NewModbusConnection())); + mModbusMode = MODBUS_SLAVE_MODE; +} + +CModbusCCMgr::~CModbusCCMgr() +{ + delete mModbusServer; +} + +int CModbusCCMgr::StartModbusCCServer() +{ + mModbusServer->listen(QHostAddress::Any,mModbusPort); + CZTLog::instance()->AddLogString(QString("Serveur Modbus Commande Centralisée démarré sur le port %1").arg(mModbusPort),true); + return 1; +} + +void CModbusCCMgr::NewModbusConnection() +{ + mModbusTCPSocketHandle = mModbusServer->nextPendingConnection(); + if(mModbusTCPSocketHandle != 0) + { + mDataLinkValid = true; + connect(mModbusTCPSocketHandle,SIGNAL(readyRead()),this,SLOT(ModbusDataReady())); + connect(mModbusTCPSocketHandle,SIGNAL(disconnected()),this,SLOT(ConnectionLost())); + //qDebug("ModbusCC: Connection with CC established"); + CZTLog::instance()->AddLogString(QString("Connection Modbus avec la CC établie. IP[%1]").arg(mModbusTCPSocketHandle->peerAddress().toString()),true); + + emit ModbusCCConnected(); + } +} + +void CModbusCCMgr::ConnectionLost() +{ + ModbusLinkDisconnected(); + emit ModbusCCDisconnected(); + CZTLog::instance()->AddLogString(QString("Connection Modbus avec la CC rompue."),true); +} + +bool CModbusCCMgr::IsModbusConnected() +{ + return mDataLinkValid; +} + +void CModbusCCMgr::RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length) +{ + Q_UNUSED(StartAddress) + Q_UNUSED(Length) + emit RepoHasChanged(); +} + +void CModbusCCMgr::ModbusRequestException(quint8 ExceptionCode, quint8 FctCode) +{ + //qDebug("Modbus CC: Request exception occured. ExceptCode: [%d], FctCode: [%d]",ExceptionCode,FctCode); + CEngLog::instance()->AddLogString(QString("Modbus CC: Exception de requête. ExceptionCode[%1], FctCode[%2]").arg(ExceptionCode).arg(FctCode)); +} diff --git a/sources/Modbus/ModbusCCMgr.h b/sources/Modbus/ModbusCCMgr.h new file mode 100644 index 0000000..14170b5 --- /dev/null +++ b/sources/Modbus/ModbusCCMgr.h @@ -0,0 +1,38 @@ +#ifndef CMODBUSSLAVE_H +#define CMODBUSSLAVE_H + +#include +#include "ModbusBackend.h" +#include +#include "ModbusRepository.h" + +class CModbusCCMgr : public CModbusBackend +{ + Q_OBJECT +public: + explicit CModbusCCMgr(CModbusRepository *Repo, int ModbusPort, int DevID); + virtual ~CModbusCCMgr(); + + int StartModbusCCServer(); + bool IsModbusConnected(); + + + + virtual void RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length); + virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode); + +private: + QTcpServer *mModbusServer; + int mModbusPort; + +signals: + void RepoHasChanged(); + void ModbusCCConnected(); + void ModbusCCDisconnected(); + +public slots: + void NewModbusConnection(); + void ConnectionLost(); +}; + +#endif // CMODBUSSLAVE_H diff --git a/sources/Modbus/ModbusMaster.cpp b/sources/Modbus/ModbusMaster.cpp new file mode 100644 index 0000000..3b436cf --- /dev/null +++ b/sources/Modbus/ModbusMaster.cpp @@ -0,0 +1,94 @@ +#include "ModbusMaster.h" +#include +#include "ModbusCCDefs.h" + +CModbusMaster::CModbusMaster(CModbusRepository *Repo, int ModbusPort, int DevID): + CModbusBackend(Repo) +{ + // connect(mModbusTCPSocketHandle,SIGNAL(readyRead()),this,SLOT(ModbusDataReady())); + mModbusMode = MODBUS_MASTER_MODE; + mModbusPort = ModbusPort; + mDeviceID = DevID; + + mModbusTCPSocketHandle = new QTcpSocket(); + connect(mModbusTCPSocketHandle,SIGNAL(readyRead()),this,SLOT(ModbusDataReady())); + connect(mModbusTCPSocketHandle,SIGNAL(disconnected()),this,SLOT(SocketDisconnected())); + connect(mModbusTCPSocketHandle,SIGNAL(connected()),this,SLOT(SocketConnected())); +} + +CModbusMaster::~CModbusMaster() +{ + if(mModbusTCPSocketHandle->state() != QAbstractSocket::UnconnectedState) + { + mModbusTCPSocketHandle->disconnectFromHost(); + mModbusTCPSocketHandle->waitForDisconnected(1000); + } + delete mModbusTCPSocketHandle; +} + +int CModbusMaster::ConnectToSlave(QString SlaveIP, int SlavePort) +{ + if(mModbusTCPSocketHandle->state() != QAbstractSocket::UnconnectedState) + { + return RET_ERROR; + } + + mModbusTCPSocketHandle->connectToHost(SlaveIP,SlavePort); + + return RET_OK; +} + +int CModbusMaster::DisconnectFromSlave() +{ + if(mModbusTCPSocketHandle->state() != QAbstractSocket::ConnectedState) + { + qDebug("Trying to disconnect a non connected socket"); + mModbusTCPSocketHandle->disconnectFromHost(); + return 0; + } + + qDebug("Requesting Disconnection..."); + mModbusTCPSocketHandle->disconnectFromHost(); + return 1; +} + +void CModbusMaster::SocketConnected() +{ + emit ModbusMasterConnected(this); + qDebug("Master: Connection established with slave"); +} + +void CModbusMaster::SocketDisconnected() +{ + ModbusLinkDisconnected(); + emit ModbusMasterDisconnected(this); +} + +int CModbusMaster::ReadModbusRegisters() +{ + //return SendReadHoldingRegistersRequest(ZT_DATA_BASE_REGISTER_ADDRESS,4); //Read all 3 registers from ZT (2000 - 2003) +} + + +void CModbusMaster::RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length) +{ + emit ModbusMasterRepositoryUpdated(); + qDebug("Database updated with ZT data..."); +} + +void CModbusMaster::ModbusResponseException(quint8 ExceptionCode, quint8 FctCode) +{ + qDebug("Modbus MASTER exception: code:%d Fct:%d",ExceptionCode,FctCode); +} + +int CModbusMaster::SendAN1ToZT() +{ + //return SendWriteHoldingRegistersRequest(CC_AN1_REGISTER_ADDRESS,1); + //return SendWriteSingleRegisterRequest(CC_AN1_REGISTER_ADDRESS); +} + +int CModbusMaster::SendAN2ToZT() +{ + //return SendWriteHoldingRegistersRequest(CC_AN2_REGISTER_ADDRESS,1); + //return SendWriteSingleRegisterRequest(CC_AN2_REGISTER_ADDRESS); +} diff --git a/sources/Modbus/ModbusMaster.h b/sources/Modbus/ModbusMaster.h new file mode 100644 index 0000000..9db5564 --- /dev/null +++ b/sources/Modbus/ModbusMaster.h @@ -0,0 +1,39 @@ +#ifndef CMODBUSMASTER_H +#define CMODBUSMASTER_H + +#include +#include "ModbusBackend.h" + + + + +class CModbusMaster : public CModbusBackend +{ + Q_OBJECT +public: + explicit CModbusMaster(CModbusRepository *Repo, int ModbusPort, int DevID); + ~CModbusMaster(); + + int ConnectToSlave(QString SlaveIP, int SlavePort); + int DisconnectFromSlave(); + int ReadModbusRegisters(); + int SendAN1ToZT(); + int SendAN2ToZT(); + + virtual void RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length); + virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode); + +private: + int mModbusPort; + +signals: + void ModbusMasterConnected(CModbusMaster *); + void ModbusMasterDisconnected(CModbusMaster *); + void ModbusMasterRepositoryUpdated(); + +public slots: + void SocketConnected(); + void SocketDisconnected(); +}; + +#endif // CMODBUSMASTER_H diff --git a/sources/Modbus/ModbusRepository.cpp b/sources/Modbus/ModbusRepository.cpp new file mode 100644 index 0000000..cb1c3d8 --- /dev/null +++ b/sources/Modbus/ModbusRepository.cpp @@ -0,0 +1,211 @@ +#include "ModbusRepository.h" +#include +#include +#include +#include "EngLog.h" + +CModbusRepository::CModbusRepository() +{ +} + +int CModbusRepository::AddHRDataMap(quint16 StartAddress, quint16 Length) +{ + mMutex.lockForWrite(); + for(int i= 0; i < mHoldingRegisters.size(); i++) + { + if((StartAddress >= mHoldingRegisters.at(i).mStartAddress && StartAddress <= mHoldingRegisters.at(i).mEndAddress) || + (StartAddress + Length - 1 >= mHoldingRegisters.at(i).mStartAddress && StartAddress + Length - 1 <= mHoldingRegisters.at(i).mEndAddress)) + { + mMutex.unlock(); + return RET_ERROR; //The data map overlaps an existing map. + } + } + + CHRDataMap NewHRMap(StartAddress,Length); + + mHoldingRegisters.append(NewHRMap); + mMutex.unlock(); + + CEngLog::instance()->AddLogString(QString("Création d'une zone registre modbus à l'adresse: %1 de taille %2").arg(StartAddress).arg(Length)); + + return RET_OK; +} + +bool CModbusRepository::IsHRValid(quint16 StartAddress, quint16 Length, int *index) +{ + mMutex.lockForRead(); + for(int i= 0; i < mHoldingRegisters.size(); i++) + { + if((StartAddress >= mHoldingRegisters.at(i).mStartAddress && StartAddress + Length - 1 <= mHoldingRegisters.at(i).mEndAddress)) + { + if(index != 0) + { + *index = i; + } + mMutex.unlock(); + return true; + } + } + mMutex.unlock(); + + return false; +} + +QByteArray CModbusRepository::GetHRData(quint16 StartAddress, quint16 Length, bool *OK) +{ + QByteArray Data; + int RegisterIndex = 0; + + if(IsHRValid(StartAddress,Length, &RegisterIndex) == false) + { + if(OK != 0) + { + *OK = false; + } + } + else + { + mMutex.lockForRead(); + int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress; + for(int i = 0; i < Length; i++) + { + quint16 CurReg = mHoldingRegisters.at(RegisterIndex).mRegistersData.at(DataIndex++); + quint8 HighByte, LowByte; + + LowByte = CurReg & 0x00FF; + HighByte = (CurReg >> 8) & 0x00FF; + Data.append(HighByte); + Data.append(LowByte); + } + mMutex.unlock(); + + if(OK != 0) + *OK = true; + } + + return Data; +} + +int CModbusRepository::WriteHRData(quint16 StartAddress, quint16 Length, QByteArray Data) +{ + int RegisterIndex; + + if(IsHRValid(StartAddress,Length, &RegisterIndex) == false) + { + return RET_ERROR; + } + + if(Length*2 != Data.size()) + { + return RET_ERROR; + } + + mMutex.lockForWrite(); + int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress; + + for(int i = 0; i < Length; i++) + { + quint8 HighByte = Data.at(i*2); + quint8 LowByte = Data.at(i*2 + 1); + qint16 Word = HighByte; + Word <<= 8; + Word += LowByte; + Word = Word &0xFFFF; + + mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex++] = Word; + } + mMutex.unlock(); + + return RET_OK; +} + +int CModbusRepository::WriteSingleReg(quint16 Address, quint16 Value) +{ + int RegisterIndex; + + if(IsHRValid(Address,1, &RegisterIndex) == false) + { + return RET_ERROR; + } + + mMutex.lockForWrite(); + int DataIndex = Address - mHoldingRegisters.at(RegisterIndex).mStartAddress; + mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex] = Value; + mMutex.unlock(); + + return RET_OK; +} + +int CModbusRepository::WriteMultipleRegs(quint16 StartAddress, QList Data) +{ + int RegisterIndex; + + if(IsHRValid(StartAddress,Data.size(), &RegisterIndex) == false) + { + return RET_ERROR; + } + + mMutex.lockForWrite(); + int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress; + for(int i = 0; i < Data.size(); i++) + { + mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex++] = Data.at(i); + } + mMutex.unlock(); + return RET_OK; +} + +QList CModbusRepository::GetRegs(quint16 StartAddress, quint16 Length, bool *OK) +{ + int RegisterIndex; + + if(IsHRValid(StartAddress,Length, &RegisterIndex) == false) + { + if(OK != 0) + { + *OK = false; + } + return QList(); + } + + if(OK != 0) + { + *OK = true; + } + + int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress; + return mHoldingRegisters[RegisterIndex].mRegistersData.mid(DataIndex,Length); +} +quint16 CModbusRepository::GetSingleReg(quint16 Address, bool *OK) +{ + int RegisterIndex; + + if(IsHRValid(Address,1, &RegisterIndex) == false) + { + if(OK != 0) + *OK = false; + return 0; + } + + if(OK != 0) + *OK = true; + + mMutex.lockForRead(); + int DataIndex = Address - mHoldingRegisters.at(RegisterIndex).mStartAddress; + quint16 Data = mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex]; + mMutex.unlock(); + + return Data; +} + +CHRDataMap::CHRDataMap(quint16 StartAddress, quint16 Length) +{ + mStartAddress = StartAddress; + mLength = Length; + for(int i = 0; i < Length; i++) + { + mRegistersData.append(0); + } + mEndAddress = StartAddress + Length - 1; +} + diff --git a/sources/Modbus/ModbusRepository.h b/sources/Modbus/ModbusRepository.h new file mode 100644 index 0000000..3c7acf9 --- /dev/null +++ b/sources/Modbus/ModbusRepository.h @@ -0,0 +1,38 @@ +#ifndef MODBUSREPOSITORY_H +#define MODBUSREPOSITORY_H +#include "GlobalDefine.h" +#include +#include + +class CHRDataMap ///Holding Register data map. +{ +public: + CHRDataMap(quint16 StartAddress, quint16 Length); + quint16 mStartAddress,mEndAddress; + quint16 mLength; + QList mRegistersData; + +}; + +class CModbusRepository +{ +public: + CModbusRepository(); + + //Holding Registers + int AddHRDataMap(quint16 StartAddress, quint16 Length); + bool IsHRValid(quint16 StartAddress, quint16 Length, int *index = 0); + QByteArray GetHRData(quint16 StartAddress, quint16 Length, bool *OK = 0); + quint16 GetSingleReg(quint16 Address, bool *OK = 0); + QList GetRegs(quint16 StartAddress, quint16 Length, bool *OK = 0); + int WriteHRData(quint16 StartAddress, quint16 Length, QByteArray Data); + int WriteSingleReg(quint16 Address, quint16 Value); + int WriteMultipleRegs(quint16 StartAddress, QList Data); + +private: + QList mHoldingRegisters; + QReadWriteLock mMutex; + +}; + +#endif // MODBUSREPOSITORY_H diff --git a/sources/Modbus/ModbusTKTransport.cpp b/sources/Modbus/ModbusTKTransport.cpp new file mode 100644 index 0000000..382da55 --- /dev/null +++ b/sources/Modbus/ModbusTKTransport.cpp @@ -0,0 +1,655 @@ +#include "ModbusTKTransport.h" +#include "ZTData.h" +#include "ZTLog.h" +#include "EngLog.h" + + +CModbusTKTransport::CModbusTKTransport(CModbusRepository *Repo) +{ + mModbusRepo = Repo; + mZT1CDVState = mZT2CDVState = false; + mMaintenanceMode = mForceZT1Clear = mForceZT2Clear = false; + mZT1TKDataList.clear(); + mZT2TKDataList.clear(); + + mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE; + mModbusTKZT2SMState = MODBUS_ZT2_TK_STANDBY_STATE; + + mZT1TKStateMachineTimer = new QTimer(); + mZT1TKStateMachineTimer->setSingleShot(false); + mZT1TKStateMachineTimer->setInterval(0); + connect(mZT1TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT1SM())); + + mZT2TKStateMachineTimer = new QTimer(); + mZT2TKStateMachineTimer->setSingleShot(false); + mZT2TKStateMachineTimer->setInterval(0); + connect(mZT2TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT2SM())); +} + +CModbusTKTransport::~CModbusTKTransport() +{ + delete mZT1TKStateMachineTimer; + delete mZT2TKStateMachineTimer; +} + +int CModbusTKTransport::ClearTK(int ZT) +{ + + if(ZT == ZT1_TYPE_ID) + { + //Fill ZT1 alarm regs with 0. + QList Data; + for(int i = 0; i <= 16; i++) //17 registers (1 flags reg + 16 ranks regs) + { + Data.append(0); + } + + //Clear pannes & itineraire flags + bool OK = false; + quint16 PannesReg = mModbusRepo->GetSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,&OK); + + if(OK == false) + { + return RET_ERROR; + } + + PannesReg ^= ZT1_V00_ALARM_FLAG_MASK; + PannesReg ^= ZT1_PEQ1_ALARM_FLAG_MASK; + PannesReg ^= ZT1_ALARM_ITI_FLAG_MASK; + + //Clear repo now... + mModbusRepo->WriteMultipleRegs(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD,Data); + mModbusRepo->WriteSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,PannesReg); + + + } + else if(ZT == ZT2_TYPE_ID) + { + //Fill ZT2 alarm regs with 0. + QList Data; + for(int i = 0; i <= 8; i++) //9 registers (1 flags reg + 8 ranks regs) + { + Data.append(0); + } + + //Clear pannes + bool OK = false; + quint16 PannesReg = mModbusRepo->GetSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,&OK); + + if(OK == false) + { + return RET_ERROR; + } + + PannesReg ^= ZT2_V02_ALARM_FLAG_MASK; + PannesReg ^= ZT2_PEQ2_ALARM_FLAG_MASK; + + //Clear repo now... + mModbusRepo->WriteMultipleRegs(MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD,Data); + mModbusRepo->WriteSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,PannesReg); + } + else + { + return RET_ERROR; + } + + return RET_OK; +} + +int CModbusTKTransport::SendTKToCC(int ZT) +{ + if(ZT == ZT1_TYPE_ID) + { + int PPIntIndex = 0, PPExtIndex = 0, FNIndex = 0, PGIndex = 0; + qint16 FlagsReg = 0; + qint16 PannesReg; + + QList DataBuf; + + //Get a local buffer of the repo... + bool OK; + DataBuf = mModbusRepo->GetRegs(MODBUS_ZT_DATA_BASE_REG,MODBUS_ZT_TABLE_DATA_SIZE,&OK); + if(OK == false) + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() ZT1 -> Lecture repository invalide."); + } + + PannesReg = DataBuf.at(RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD)); + + for(int i = 0; i < mZT1TKDataList.size(); i++) + { + CZTDetectionData TKData = mZT1TKDataList.at(i); + + switch(TKData.mDetectionID) + { + case DETECTION_MAGNETIC_SENSOR_COUNT: + { + PannesReg |= ZT1_V00_ALARM_FLAG_MASK; + break; + } + case DETECTION_FN_DETECTION: + { + if(FNIndex == 0) + { + FlagsReg |= ZT1_FN_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_1_REG_ADD)] = (qint16)TKData.mRank; + } + else if(FNIndex == 1) + { + FlagsReg |= ZT1_FN_FLAG_MASK_2; + DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_2_REG_ADD)] = (qint16)TKData.mRank; + } + else if(FNIndex == 2) + { + FlagsReg |= ZT1_FN_FLAG_MASK_3; + DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_3_REG_ADD)] = (qint16)TKData.mRank; + } + else if(FNIndex == 3) + { + FlagsReg |= ZT1_FN_FLAG_MASK_4; + DataBuf[RegOffset(MODBUS_ZT1_RANK_FN_4_REG_ADD)] = (qint16)TKData.mRank; + } + else + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() -> FNIndex > 3"); + } + FNIndex++; + break; + } + case DETECTION_PG_DETECTION: + { + if(PGIndex == 0) + { + FlagsReg |= ZT1_PG_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_1_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PGIndex == 1) + { + FlagsReg |= ZT1_PG_FLAG_MASK_2; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_2_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PGIndex == 2) + { + FlagsReg |= ZT1_PG_FLAG_MASK_3; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_3_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PGIndex == 3) + { + FlagsReg |= ZT1_PG_FLAG_MASK_4; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PG_4_REG_ADD)] = (qint16)TKData.mRank; + } + else + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() -> PGIndex > 3"); + } + PGIndex++; + break; + } + case DETECTION_PPI_DETECTION: + { + if(PPIntIndex == 0) + { + FlagsReg |= ZT1_PP_INT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_1_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPIntIndex == 1) + { + FlagsReg |= ZT1_PP_INT_FLAG_MASK_2; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_2_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPIntIndex == 2) + { + FlagsReg |= ZT1_PP_INT_FLAG_MASK_3; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_3_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPIntIndex == 3) + { + FlagsReg |= ZT1_PP_INT_FLAG_MASK_4; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_INT_4_REG_ADD)] = (qint16)TKData.mRank; + } + else + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() -> PPIntIndex ZT1 > 3"); + } + PPIntIndex++; + break; + } + case DETECTION_PPE_DETECTION: + { + if(PPExtIndex == 0) + { + FlagsReg |= ZT1_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_1_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPExtIndex == 1) + { + FlagsReg |= ZT1_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_2_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPExtIndex == 2) + { + FlagsReg |= ZT1_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_3_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPExtIndex == 3) + { + FlagsReg |= ZT1_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT1_RANK_PP_EXT_4_REG_ADD)] = (qint16)TKData.mRank; + } + else + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() -> PPExtIndex ZT1 > 3"); + } + PPExtIndex++; + break; + } + case DETECTION_PEQ1_DETECTION: + { + PannesReg |= ZT1_PEQ1_ALARM_FLAG_MASK; + break; + } + } + } + + //Update the modbus repo to send the alarms... + DataBuf[RegOffset(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD)] = FlagsReg; + DataBuf[RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD)] = PannesReg; + mModbusRepo->WriteMultipleRegs(MODBUS_ZT_DATA_BASE_REG,DataBuf); + + } + else if(ZT == ZT2_TYPE_ID) + { + int PPIntIndex = 0, PPExtIndex = 0; + qint16 FlagsReg = 0; + qint16 PannesReg; + + QList DataBuf; + + //Get a local buffer of the repo... + bool OK; + DataBuf = mModbusRepo->GetRegs(MODBUS_ZT_DATA_BASE_REG,MODBUS_ZT_TABLE_DATA_SIZE,&OK); + if(OK == false) + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() ZT2 -> Lecture repository invalide."); + } + + PannesReg = DataBuf.at(RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD)); + + for(int i = 0; i < mZT1TKDataList.size(); i++) + { + CZTDetectionData TKData = mZT1TKDataList.at(i); + + switch(TKData.mDetectionID) + { + + case DETECTION_PEQ2_DETECTION: + { + PannesReg |= ZT2_PEQ2_ALARM_FLAG_MASK; + break; + } + case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT: + { + PannesReg |= ZT2_V02_ALARM_FLAG_MASK; + break; + } + case DETECTION_ZT2_PPI_DETECTION: + { + if(PPIntIndex == 0) + { + FlagsReg |= ZT2_PP_INT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_1_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPIntIndex == 1) + { + FlagsReg |= ZT2_PP_INT_FLAG_MASK_2; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_2_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPIntIndex == 2) + { + FlagsReg |= ZT2_PP_INT_FLAG_MASK_3; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_3_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPIntIndex == 3) + { + FlagsReg |= ZT2_PP_INT_FLAG_MASK_4; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_INT_4_REG_ADD)] = (qint16)TKData.mRank; + } + else + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() -> PPIntIndex ZT2 > 3"); + } + PPIntIndex++; + break; + } + case DETECTION_ZT2_PPE_DETECTION: + { + if(PPExtIndex == 0) + { + FlagsReg |= ZT2_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_1_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPExtIndex == 1) + { + FlagsReg |= ZT2_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_2_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPExtIndex == 2) + { + FlagsReg |= ZT2_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_3_REG_ADD)] = (qint16)TKData.mRank; + } + else if(PPExtIndex == 3) + { + FlagsReg |= ZT2_PP_EXT_FLAG_MASK_1; + DataBuf[RegOffset(MODBUS_ZT2_RANK_PP_EXT_4_REG_ADD)] = (qint16)TKData.mRank; + } + else + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() -> PPExtIndex ZT2 > 3"); + } + PPExtIndex++; + break; + } + } + } + + //Update the modbus repo to send the alarms... + DataBuf[RegOffset(MODBUS_ZT2_ALARM_RANKS_BASE_ADD)] = FlagsReg; + DataBuf[RegOffset(MODBUS_MISC_DATA_BASE_REG_ADD)] = PannesReg; + mModbusRepo->WriteMultipleRegs(MODBUS_ZT_DATA_BASE_REG,DataBuf); + + } + else + { + CEngLog::instance()->AddLogString("Erreur de logique. ModbusTkTransport::SendTKToCC() -> Index de ZT invalide!!!"); + return RET_ERROR; + } + + return RET_OK; +} + + + + +bool CModbusTKTransport::IsZT2TKProcessing() +{ + if(mModbusTKZT2SMState != MODBUS_ZT2_TK_STANDBY_STATE) + { + return true; + } + return false; +} + +bool CModbusTKTransport::IsZT1TKProcessing() +{ + if(mModbusTKZT1SMState != MODBUS_ZT1_TK_STANDBY_STATE) + { + return true; + } + return false; +} +bool CModbusTKTransport::IsTKProcessing() +{ + if(IsZT1TKProcessing() || IsZT2TKProcessing()) + return true; + + return false; +} + +int CModbusTKTransport::AddNewZT1Detection(CZTDetectionData Detection) +{ + mZT1TKDataList.append(Detection); + return RET_OK; +} +int CModbusTKTransport::AddNewZT2Detection(CZTDetectionData Detection) +{ + mZT2TKDataList.append(Detection); + return RET_OK; +} +unsigned int CModbusTKTransport::BeginTKEmission() +{ + + if(mZT1TKDataList.size() > 0) + { + if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive == false) + { + mZT1TKDataList.clear(); + } + else if(mModbusTKZT1SMState == MODBUS_ZT1_TK_STANDBY_STATE) + { + mModbusTKZT1SMState = MODBUS_ZT1_TK_SHOW_STATE; + mZT1TKStateMachineTimer->start(0); + } + } + + + if(mZT2TKDataList.size() > 0) + { + if(GetDetectionConfig()->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive == false) + { + mZT2TKDataList.clear(); + } + else if(mModbusTKZT2SMState == MODBUS_ZT2_TK_STANDBY_STATE) + { + mModbusTKZT2SMState = MODBUS_ZT2_TK_SHOW_STATE; + mZT2TKStateMachineTimer->start(0); + } + } + + + return RET_OK; +} +unsigned int CModbusTKTransport::SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState) +{ + Q_UNUSED(AN2State) + Q_UNUSED(AN1State) + + mZT1CDVState = ZT1CDVState; + mZT2CDVState = ZT2CDVState; + return RET_OK; +} + +unsigned int CModbusTKTransport::CancelAllTK() +{ + return RET_OK; +} + +unsigned int CModbusTKTransport::CancelMaintenanceCurrentTK() +{ + return RET_OK; +} + +unsigned int CModbusTKTransport::ExitMaintenance() +{ + mMaintenanceMode = false; + mForceZT1Clear = false; + mForceZT2Clear = false; + CancelAllTK(); + + return RET_OK; +} + +unsigned int CModbusTKTransport::EnterMaintenance() +{ + if(IsTKProcessing()) + { + return RET_ERROR; + } + + CancelAllTK(); + mMaintenanceMode = true; + mForceZT1Clear = false; + mForceZT2Clear = false; + + return RET_OK; +} + +void CModbusTKTransport::ExecZT1SM() +{ + switch(mModbusTKZT1SMState) + { + case MODBUS_ZT1_TK_SHOW_STATE: + { + + SendTKToCC(ZT1_TYPE_ID); //Mise à jour de la table Modbus avec les données des alarmes actives. + + mModbusTKZT1SMState = MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE; + + CZTLog::instance()->AddLogString("Émission des alarmes PCC",true); + for(int i = 0; i < mZT1TKDataList.size(); i++) + { + LogTK(mZT1TKDataList.at(i)); + } + + if(mMaintenanceMode) + { + emit TKOutputStatesChanged(true,false); + } + + break; + } + case MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE: + { + if(mZT1Clear == true || (mMaintenanceMode == true && mForceZT1Clear == true)) + { + ClearTK(ZT1_TYPE_ID); //Remise à zéro des données d'alarmes dans la table modbus. + + mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE; + + if(mMaintenanceMode == true) + { + if(mForceZT1Clear == true) + { + mForceZT1Clear = false; + CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT1",true); + } + else + { + CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true); + } + + emit TKOutputStatesChanged(false,false); + + } + else + { + CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true); + } + } + else if(mZT1CDVState == false && mMaintenanceMode == false) + { + //The train has left... clear the alarms... + CZTLog::instance()->AddLogString("Libération du CDV de quai ZT1. Acquitement automatique des alarmes ZT1 au PCC",true); + ClearTK(ZT1_TYPE_ID); + mModbusTKZT1SMState = MODBUS_ZT1_TK_STANDBY_STATE; + } + + break; + } + case MODBUS_ZT1_TK_STANDBY_STATE: + { + mZT1TKDataList.clear(); + mZT1TKStateMachineTimer->stop(); + + //In maintenance mode, it is possible to have ZT2 events at the same time + //than ZT1. So if any ZT2 events are waiting in the qeue, send them... + if(mMaintenanceMode) + { + if(mZT2TKDataList.size() > 0) + { + BeginTKEmission(); + } + } + + break; + } + } +} + +void CModbusTKTransport::ExecZT2SM() +{ + switch(mModbusTKZT2SMState) + { + case MODBUS_ZT2_TK_SHOW_STATE: + { + + SendTKToCC(ZT2_TYPE_ID); //Mise à jour de la table Modbus avec les données des alarmes actives. + + mModbusTKZT1SMState = MODBUS_ZT2_TK_WAIT_FOR_CLEAR_STATE; + + CZTLog::instance()->AddLogString("Émission des alarmes PCC",true); + for(int i = 0; i < mZT2TKDataList.size(); i++) + { + LogTK(mZT2TKDataList.at(i)); + } + + if(mMaintenanceMode) + { + emit TKOutputStatesChanged(false,true); + } + break; + } + case MODBUS_ZT2_TK_WAIT_FOR_CLEAR_STATE: + { + if(mZT2Clear == true || (mMaintenanceMode == true && mForceZT2Clear == true)) + { + ClearTK(ZT2_TYPE_ID); //Remise à zéro des données d'alarmes dans la table modbus. + + mModbusTKZT2SMState = MODBUS_ZT2_TK_STANDBY_STATE; + + if(mMaintenanceMode == true) + { + if(mForceZT2Clear == true) + { + mForceZT2Clear = false; + CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT2",true); + } + else + { + CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true); + } + + emit TKOutputStatesChanged(false,false); + + } + else + { + CZTLog::instance()->AddLogString("Acquitement ZTC ou FCYCLE détectée",true); + } + } + else if(mZT2CDVState == false && mMaintenanceMode == false) + { + //The train has left... clear the alarms... + CZTLog::instance()->AddLogString("Libération du CDV de quai ZT2. Acquitement automatique des alarmes ZT2 au PCC",true); + ClearTK(ZT2_TYPE_ID); + mModbusTKZT1SMState = MODBUS_ZT2_TK_STANDBY_STATE; + } + + break; + } + case MODBUS_ZT2_TK_STANDBY_STATE: + { + mZT2TKDataList.clear(); + mZT2TKStateMachineTimer->stop(); + + //In maintenance mode, it is possible to have ZT1 events at the same time + //than ZT2. So if any ZT1 events are waiting in the qeue, send them... + if(mMaintenanceMode) + { + if(mZT1TKDataList.size() > 0) + { + BeginTKEmission(); + } + } + + break; + } + } +} + +void CModbusTKTransport::ModbusCCUpdated() +{ + qint16 ClearReg = mModbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD); + mZT1Clear = (ClearReg & (MODBUS_CC_FCYCLE_ZT1_FLAG_MASK | MODBUS_CC_ZTC_ZT1_FLAG_MASK)) != 0; + mZT2Clear = (ClearReg & (MODBUS_CC_FCYCLE_ZT2_FLAG_MASK | MODBUS_CC_ZTC_ZT2_FLAG_MASK)) != 0; +} diff --git a/sources/Modbus/ModbusTKTransport.h b/sources/Modbus/ModbusTKTransport.h new file mode 100644 index 0000000..8b349d0 --- /dev/null +++ b/sources/Modbus/ModbusTKTransport.h @@ -0,0 +1,63 @@ +#ifndef MODBUSTKTRANSPORT_H +#define MODBUSTKTRANSPORT_H + +#include "TKTransportInterface.h" +#include "ModbusRepository.h" +#include +#include "ModbusCCDefs.h" + + +class CModbusTKTransport : public CTKTransportInterface +{ +public: + enum eModbusTKSMStates + { + MODBUS_ZT1_TK_STANDBY_STATE, + MODBUS_ZT1_TK_SHOW_STATE, + MODBUS_ZT1_TK_WAIT_FOR_CLEAR_STATE, + + MODBUS_ZT2_TK_STANDBY_STATE, + MODBUS_ZT2_TK_SHOW_STATE, + MODBUS_ZT2_TK_WAIT_FOR_CLEAR_STATE + }; + + + + CModbusTKTransport(CModbusRepository *Repo); + ~CModbusTKTransport(); + + + int SendTKToCC(int ZT); + int ClearTK(int ZT); + + virtual bool IsZT2TKProcessing(); + virtual bool IsZT1TKProcessing(); + virtual bool IsTKProcessing(); + virtual int AddNewZT1Detection(CZTDetectionData Detection); + virtual int AddNewZT2Detection(CZTDetectionData Detection); + virtual unsigned int BeginTKEmission(); + virtual unsigned int SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState); + + virtual unsigned int CancelAllTK(); + virtual unsigned int CancelMaintenanceCurrentTK(); + virtual unsigned int ExitMaintenance(); + virtual unsigned int EnterMaintenance(); + +private: + CModbusRepository *mModbusRepo; + QList mZT1TKDataList,mZT2TKDataList; + bool mZT1CDVState, mZT2CDVState; + bool mMaintenanceMode, mForceZT1Clear, mForceZT2Clear; + int mModbusTKZT1SMState,mModbusTKZT2SMState; + QTimer *mZT1TKStateMachineTimer, *mZT2TKStateMachineTimer; + bool mZT1Clear, mZT2Clear; + + int RegOffset(qint16 Reg){return (int)Reg-MODBUS_ZT_DATA_BASE_REG;} + +public slots: + void ExecZT1SM(); + void ExecZT2SM(); + void ModbusCCUpdated(); +}; + +#endif // MODBUSTKTRANSPORT_H diff --git a/sources/NetworkManager.cpp b/sources/NetworkManager.cpp new file mode 100644 index 0000000..03df9b8 --- /dev/null +++ b/sources/NetworkManager.cpp @@ -0,0 +1,247 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2015 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe qui gère la communication IP entre la Zone Test et l'outil d'analyse. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "NetworkManager.h" +#include +#include +#include +#include + + +CNetworkManager CNetworkManager::mSingleton; + +CNetworkManager::CNetworkManager(QObject *parent) : + QObject(parent) +{ + mProgramHandle = 0; + mTCPSocket = 0; + mCurTrainLogsListIndex = 0; + mTrainLogsFileInfoList.clear(); + + + connect(&mTCPServer,SIGNAL(newConnection()),this,SLOT(NewTCPConnection())); +} + +CNetworkManager::~CNetworkManager() +{ + mTCPSocket->disconnectFromHost(); + mTCPServer.close(); +} + +void CNetworkManager::BindPointers(CZoneTest *ProgramHandle) +{ + mProgramHandle = ProgramHandle; +} + +unsigned int CNetworkManager::StartServer() +{ + if(mTCPServer.listen(QHostAddress::Any,TCP_SERVER_PORT) == false) + { + CZTLog::instance()->AddLogString("Impossible de démarrer le serveur TCP",true); + return RET_ERROR; + } + + CZTLog::instance()->AddLogString(QString().sprintf("Serveur TCP démarré sur le port %d",TCP_SERVER_PORT),true); + return RET_OK; + +} + +void CNetworkManager::NewTCPConnection() +{ + mTCPSocket = mTCPServer.nextPendingConnection(); + + if(mTCPSocket == 0) + { + CEngLog::instance()->AddLogString("Invalid socket from TCP server"); + return; + } + + // mTCPSocket->setSocketOption(QAbstractSocket::LowDelayOption,1); + + connect(mTCPSocket,SIGNAL(readyRead()),this,SLOT(TCPDataReady())); + connect(mTCPSocket,SIGNAL(disconnected()),this,SLOT(TCPSockedDisconnected())); + + QString str = "Client connecté : "; + str += mTCPSocket->peerAddress().toString(); + CZTLog::instance()->AddLogString(str,true); +} + +void CNetworkManager::TCPDataReady() +{ + qint64 datasize = mTCPSocket->bytesAvailable(); + //QByteArray data= mTCPSocket->read(datasize); + + qDebug() << "TCP data received" << datasize;// << "bytes: " << data.toHex(); + + AnalyzeNewData(mTCPSocket->readAll()); + +} + +void CNetworkManager::TCPSockedDisconnected() +{ + CZTLog::instance()->AddLogString("Client TCP déconnecté",true); + //StartServer(); +} + +void CNetworkManager::TCPTxRequest(QByteArray request) +{ + qDebug() << "Tx request in Network Manager : " << request.size() << " bytes : " << request.toHex(); + + mTCPSocket->write(request); +} + +void CNetworkManager::TCPHeartbeatRequest() +{ + qDebug("TCP: Received heartbeat request..."); + mTCPSocket->write(GetHeartbeatPacket()); +} + +void CNetworkManager::TCPStationNameRequest() +{ + qDebug("TCP: Received station name request..."); + mTCPSocket->write(GetStationNamePacket(mProgramHandle->GetStationTextualName())); +} + +void CNetworkManager::TCPStatusRequest() +{ + qDebug("TCP: Received ZT status request"); + CTCPZTStatus *status = mProgramHandle->GetTCPStatusRequest(); + mTCPSocket->write(GetZTStatusPacket(status)); + delete status; +// mTCPSocket->write(SendZTStatus()); +} + +void CNetworkManager::TCPZTLogDownloadRequest() +{ + qDebug("TCP: Received ZTLog Download request"); + QString *ZTLogText = mProgramHandle->GetZTLogTextRequest(); + mTCPSocket->write(GetZTLogPacket(ZTLogText)); + delete ZTLogText; +} + +void CNetworkManager::TCPTrainLogsDownloadRequest() +{ + mTrainLogsFileInfoList.clear(); + mTrainLogsFileInfoList = mProgramHandle->GetTrainLogsFileListRequest(); + mCurTrainLogsListIndex = 0; + + //Add LogZT.txt to the list of files to transfer... + mTrainLogsFileInfoList.append(QFileInfo("./LOG/LogZT.txt")); + + mTCPSocket->write(GetTrainLogsDownloadAckPacket((qint32)mTrainLogsFileInfoList.size())); + +} + +void CNetworkManager::TCPTrainLogFileDataAck(eTCPProtocolAcknowledge Acknowledge) +{ + if(mCurTrainLogsListIndex >= mTrainLogsFileInfoList.size()) + { + mTCPSocket->write(GetTrainLogsDownloadFinishedPacket()); + return; + } + + if(Acknowledge != TCP_PROTOCOL_ACK) + { + //TODO: Manage NACK codes... + return; + } + + //Send next file + + QByteArray FileData; + QDataStream strm(&FileData,QIODevice::WriteOnly); + strm.device()->seek(0); + + QFile* BinaryLogFile = new QFile(mTrainLogsFileInfoList.at(mCurTrainLogsListIndex).absoluteFilePath()); + if(BinaryLogFile) + { + if(BinaryLogFile->open(QIODevice::ReadOnly | QIODevice::Unbuffered) == false) + { + delete BinaryLogFile; + return; + } + + } + else + { + return; + } + + strm << mTrainLogsFileInfoList.at(mCurTrainLogsListIndex).fileName(); + + FileData.append(BinaryLogFile->readAll()); + BinaryLogFile->flush(); + BinaryLogFile->close(); + delete BinaryLogFile; + + QByteArray *Packet = GetTrainLogDataPacket(FileData); + + qDebug() << "Sending: " << mTrainLogsFileInfoList.at(mCurTrainLogsListIndex).absoluteFilePath(); + mTCPSocket->write(*Packet); + + delete Packet; + mCurTrainLogsListIndex++; +} + +void CNetworkManager::TCPDeleteZTLogRequest() +{ + qDebug("TCP: Received ZTLog Delete request"); + if(mProgramHandle->DeleteZTLogRequest() == RET_OK) + { + mTCPSocket->write(GetDeleteZTLogsAckPacket((qint32)TCP_PROTOCOL_ACK)); + } + else + { + mTCPSocket->write(GetDeleteZTLogsAckPacket((qint32)TCP_PROTOCOL_NACK)); + } +} + +void CNetworkManager::TCPSetZTFunctionsConfigRequest(QByteArray &Data) +{ + qDebug("TCP: Received Set ZT functions config request"); + + CTCPZTFunctionsStatus FunctionsConfig; + QDataStream strm(&Data,QIODevice::ReadOnly); + strm.device()->seek(0); + + strm >> FunctionsConfig; + + if(mProgramHandle->SetZTFunctionsConfig(FunctionsConfig) == RET_OK) + { + mTCPSocket->write(GetSetZTFunctionsConfigAckPacket((qint32)TCP_PROTOCOL_ACK)); + } + else + { + mTCPSocket->write(GetSetZTFunctionsConfigAckPacket((qint32)TCP_PROTOCOL_NACK)); + } +} + + + + + + diff --git a/sources/NetworkManager.h b/sources/NetworkManager.h new file mode 100644 index 0000000..6bd0b32 --- /dev/null +++ b/sources/NetworkManager.h @@ -0,0 +1,54 @@ +#ifndef NETWORKMANAGER_H +#define NETWORKMANAGER_H + +#include +#include +#include +#include +#include +#include + +class CZoneTest; + +class CNetworkManager : public QObject, public CTCPProtocol +{ + Q_OBJECT +public: + static CNetworkManager* instance(){return &mSingleton;} + static CNetworkManager mSingleton; + + explicit CNetworkManager(QObject *parent = 0); + ~CNetworkManager(); + + void BindPointers(CZoneTest *ProgramHandle); + unsigned int StartServer(); + + virtual void TCPTxRequest(QByteArray request); + virtual void TCPHeartbeatRequest(); + virtual void TCPStationNameRequest(); + virtual void TCPStatusRequest(); + virtual void TCPZTLogDownloadRequest(); + virtual void TCPTrainLogsDownloadRequest(); + virtual void TCPTrainLogFileDataAck(eTCPProtocolAcknowledge Acknowledge); + virtual void TCPDeleteZTLogRequest(); + virtual void TCPSetZTFunctionsConfigRequest(QByteArray &Data); + +private: + QTcpServer mTCPServer; + QTcpSocket *mTCPSocket; + CZoneTest *mProgramHandle; + + QFileInfoList mTrainLogsFileInfoList; + int mCurTrainLogsListIndex; + +signals: + + +public slots: + + void NewTCPConnection(); + void TCPDataReady(); + void TCPSockedDisconnected(); +}; + +#endif // NETWORKMANAGER_H diff --git a/sources/OutputModule.cpp b/sources/OutputModule.cpp new file mode 100644 index 0000000..0e3c891 --- /dev/null +++ b/sources/OutputModule.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme des modules d'entrées/sorties externes + mixtes (SEAI/0 440). + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "OutputModule.h" + +COutputModule::~COutputModule() +{ + +} diff --git a/sources/OutputModule.h b/sources/OutputModule.h new file mode 100644 index 0000000..ae52727 --- /dev/null +++ b/sources/OutputModule.h @@ -0,0 +1,46 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef OUTPUTMODULE_H +#define OUTPUTMODULE_H + +#include "GlobalDefine.h" +#include "IOModule.h" + +class COutputModule: public CIOModule +{ +public: + + virtual ~COutputModule(); + virtual unsigned int SetOutput(unsigned char* buffer) = 0; + virtual unsigned int SetOutput(quint32 buffer) = 0; + virtual unsigned int SetOutputFlags(quint32 Flags) = 0; + virtual unsigned int ClearOutputFlags(quint32 Flags) = 0; + virtual unsigned int ToggleOutputFlags(quint32 Flags) = 0; +}; + +#endif // OUTPUTMODULE_H diff --git a/sources/PCIIO/Comedilibinterface.cpp b/sources/PCIIO/Comedilibinterface.cpp new file mode 100644 index 0000000..377a97f --- /dev/null +++ b/sources/PCIIO/Comedilibinterface.cpp @@ -0,0 +1,125 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe d'interface avec le pilote Linux COMEDILib pour la carte d'I/O PCI. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Comedilibinterface.h" +#include + +CComediLibInterface::CComediLibInterface(): + mOpened(false) +{ + mInputBuf = 0; +} + +CComediLibInterface::~CComediLibInterface() +{ +#ifndef NO_PCI_CARD_INSTALLED + comedi_close(mComediDevice); +#endif +} + + +unsigned int CComediLibInterface::OpenPCIInterface() +{ + + if(mOpened) + return PCIIO_DEVICE_ALREADY_OPENED; + + QString comediFilename = "/dev/comedi0"; + + + CEngLog::instance()->AddLogString(QString("Ouverture de la carte PCI :") + comediFilename,3); + mComediDevice = comedi_open(comediFilename.toAscii().data()); + if(!mComediDevice) + { + + CEngLog::instance()->AddLogString("L'ouverture de la carte PCI a échouée",1); + return PCIIO_CANNOT_OPEN_DEVICE; + } + else + { + QString boardname; + boardname = comedi_get_board_name(mComediDevice); + + //Check that we have the good board installed. + if(boardname != PCI_DEVICE_NAME) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur. Incohérence du type de carte; Voulu: %s, Réel: %s",PCI_DEVICE_NAME,boardname.toAscii().data()),1); + return PCIIO_DEVICE_MISMATCH; + } + else + { + CEngLog::instance()->AddLogString(QString("Carte PCI initialisée :") + boardname,3); + } + +// int NbSubDevices = comedi_get_n_subdevices(mComediDevice); +// qDebug("Nb Subdevices: %d",NbSubDevices); + + //Check that the inputs and outputs subdevices are correct. + int SubDeviceType = comedi_get_subdevice_type(mComediDevice,PCI_OUTPUTS_SUBDEVICE_ID); + if(SubDeviceType != COMEDI_SUBD_DO) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur. Incohérence du type de Output Subdevice; Voulu: %d, Réel: %d",SubDeviceType,PCI_OUTPUTS_SUBDEVICE_ID),1); + return PCIIO_OUTPUTS_SUBDEVICE_MISMATCH; + } + + SubDeviceType = comedi_get_subdevice_type(mComediDevice,PCI_INPUTS_SUBDEVICE_ID); + if(SubDeviceType != COMEDI_SUBD_DI) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur. Incohérence du type de Output Subdevice; Voulu: %d, Réel: %d",SubDeviceType,PCI_INPUTS_SUBDEVICE_ID),1); + return PCIIO_INPUTS_SUBDEVICE_MISMATCH; + } + //qDebug("type"); + } + + CEngLog::instance()->AddLogString("Carte PCI ouverte avec succès",3); + mOpened = true; + return PCIIO_OK; +} + +unsigned int CComediLibInterface::GetInputs() +{ + unsigned int Buf; + mMutex.lock(); + comedi_dio_bitfield2(mComediDevice,0,0xFFFFFFFF,&Buf,0); +// Buf = mInputBuf; + mMutex.unlock(); + + return Buf; +} + +comedi_t *CComediLibInterface::GetPCIDevice() +{ + if(mOpened == false) + return NULL; + + return mComediDevice; +} + + + + + diff --git a/sources/PCIIO/Comedilibinterface.h b/sources/PCIIO/Comedilibinterface.h new file mode 100644 index 0000000..3879070 --- /dev/null +++ b/sources/PCIIO/Comedilibinterface.h @@ -0,0 +1,58 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef COMEDILIBINTERFACE_H +#define COMEDILIBINTERFACE_H + +#include "GlobalDefine.h" +#include "PCI1756Definitions.h" +#include +#include "PCIIOMgr.h" +#include + + + +class CComediLibInterface : public CPCIIOMgr +{ +public: + CComediLibInterface(); + ~CComediLibInterface(); + + virtual unsigned int OpenPCIInterface(void); + virtual unsigned int GetInputs(void); + + comedi_t *GetPCIDevice(void); + +private: + comedi_t *mComediDevice; + bool mOpened; + QMutex mMutex; + unsigned int mInputBuf; + +}; + +#endif // COMEDILIBINTERFACE_H diff --git a/sources/PCIIO/PCI1756Definitions.h b/sources/PCIIO/PCI1756Definitions.h new file mode 100644 index 0000000..3ab6c06 --- /dev/null +++ b/sources/PCIIO/PCI1756Definitions.h @@ -0,0 +1,38 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef PCI1756DEFINITIONS_H +#define PCI1756DEFINITIONS_H + +// Subdevice parameters for the Advantech PCI1756 +#define PCI_INPUTS_SUBDEVICE_ID 2 +#define PCI_OUTPUTS_SUBDEVICE_ID 1 + +#define PCI_DEVICE_NAME "pci1756" +#define PCI_DAQNAVI_NAME "PCI-1756" + +#endif // PCI1756DEFINITIONS_H diff --git a/sources/PCIIO/PCI1756Interface.cpp b/sources/PCIIO/PCI1756Interface.cpp new file mode 100644 index 0000000..a0f2c12 --- /dev/null +++ b/sources/PCIIO/PCI1756Interface.cpp @@ -0,0 +1,121 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe d'interface avec la carte d'I/O PCI1756. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "PCI1756Interface.h" +#include "PCI1756Definitions.h" +#include +#include + +CPCI1756Interface::CPCI1756Interface(): + mOpened(false) +{ + mInputBuf = 0; +} + +CPCI1756Interface::~CPCI1756Interface() +{ +#ifndef NO_PCI_CARD_INSTALLED + if(mOpened) + mInputCtrl->Dispose(); +#endif +} + + +unsigned int CPCI1756Interface::OpenPCIInterface() +{ + + if(mOpened) + return PCIIO_DEVICE_ALREADY_OPENED; + + + + CEngLog::instance()->AddLogString(QString("Ouverture de la carte PCI :"),3); + + mInputCtrl = AdxInstantDiCtrlCreate(); + ICollection *supportedDevices = mInputCtrl->getSupportedDevices(); + if(supportedDevices->getCount() == 0) + { + CEngLog::instance()->AddLogString("L'ouverture de la carte PCI a échouée (Aucune carte n'est installée)",1); + return PCIIO_CANNOT_OPEN_DEVICE; + } + + bool found = false; + for (int i = 0; i < supportedDevices->getCount(); i++) + { + DeviceTreeNode const &node = supportedDevices->getItem(i); + QString DeviceDescription(QString::fromWCharArray(node.Description)); + qDebug() << "Device Nbr: " << node.DeviceNumber << " : "<< DeviceDescription; + + if(QString::fromWCharArray(node.Description).contains(PCI_DAQNAVI_NAME)) + { + if(mInputCtrl->setSelectedDevice(DeviceInformation(node.Description)) != Success) + { + CEngLog::instance()->AddLogString("L'ouverture de la carte PCI a échouée (Carte occupée)",1); + supportedDevices->Dispose(); + mInputCtrl->Dispose(); + return PCIIO_CANNOT_OPEN_DEVICE; + } + CEngLog::instance()->AddLogString(QString("Carte PCI initialisée :") + QString::fromWCharArray(node.Description),3); + found = true; + break; + } + } + if(found == false) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Erreur. Incohérence du type de carte"),1); + return PCIIO_DEVICE_MISMATCH; + } + + supportedDevices->Dispose(); + CEngLog::instance()->AddLogString("Carte PCI ouverte avec succès",3); + mOpened = true; + return PCIIO_OK; + +} + +unsigned int CPCI1756Interface::GetInputs() +{ + unsigned int Buf = 0; + unsigned char data[4]; + memset(data,0,4); + mMutex.lock(); + ErrorCode errorCode = Success; + errorCode = mInputCtrl->Read(0,4,(unsigned char *)&Buf); + if(errorCode != Success) + { + qDebug("PCI read Error"); + } + + mMutex.unlock(); + + + return Buf; +} + + + + diff --git a/sources/PCIIO/PCI1756Interface.h b/sources/PCIIO/PCI1756Interface.h new file mode 100644 index 0000000..6ad651e --- /dev/null +++ b/sources/PCIIO/PCI1756Interface.h @@ -0,0 +1,60 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20140828 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef PCI1756INTERFACE_H +#define PCI1756INTERFACE_H + +#include +#include "GlobalDefine.h" +#include "PCIIOMgr.h" +#include + +using namespace Automation::BDaq; + +class CPCI1756Interface : public CPCIIOMgr +{ +public: + + + + CPCI1756Interface(); + ~CPCI1756Interface(); + + virtual unsigned int OpenPCIInterface(void); + virtual unsigned int GetInputs(void); + + +private: + + InstantDiCtrl *mInputCtrl; + bool mOpened; + QMutex mMutex; + unsigned int mInputBuf; + +}; + +#endif // DAQNAVIINTERFACE_H diff --git a/sources/PCIIO/PCIThread.cpp b/sources/PCIIO/PCIThread.cpp new file mode 100644 index 0000000..f177937 --- /dev/null +++ b/sources/PCIIO/PCIThread.cpp @@ -0,0 +1,277 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#include "ZT2AnalysisThread.h" +#include "PCIIOMgr.h" +#include "AbstractLazerProbe.h" +#include +#include "ZTconfigmgr.h" + +//const char * ErrorString[25] = {"Erreur de comptage S1-S2", +// "Déclenchement frotteur négatif", +// "Déclenchement pneu de guidage intérieur", +// "Déclenchement pneu de guidage extérieur", +// "Déclenchement pneu porteur intérieur", +// "Déclenchement pneu porteur extérieur", +// "Pré-détection frotteur négatif"}; + +CZT2AnalysisThread::CZT2AnalysisThread() +{ + mLastInputs = 0; + mZT2TrainState = ZT2_PRE_DETECTION_STATE; + + mPCIInputsHandle = 0; + mExitLoop = false; + mZT2Analyzing = false; +} + +unsigned int CZT2AnalysisThread::Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks,QElapsedTimer *RefTimer) +{ + mPCIInputsHandle = PCIIOHandle; + mInputMasksPtr = InputMasks; + mReferenceTimer = RefTimer; + + return RET_OK; +} + +void CZT2AnalysisThread::AnalyzeZT2Train() +{ + + qDebug("ZT2 Thread started!"); + mExitLoop = false; + mZT2Analyzing = true; + + + mZT2TrainState = ZT2_PRE_DETECTION_STATE; + unsigned int PCIInputs = 0; + bool Run = true; + + //inputs + unsigned int S1 = 0, Pint = 0, Pext = 0; + + //Train analysis variables + unsigned int Bogie = 0; + unsigned int Rank = 0; + unsigned int CountS1 = 0; + + + bool PPIDetected = false; + bool PPEDetected = false; + + + while(Run == true) + { + PCIInputs = mPCIInputsHandle->GetInputs(); + + if(PCIInputs != mLastInputs) + { + //Extract useful flags + + S1 = ((PCIInputs & mInputMasksPtr->InputZT2S1Mask) != 0); + Pint = ((PCIInputs & mInputMasksPtr->InputZT2PIMask) != 0); + Pext = ((PCIInputs & mInputMasksPtr->InputZT2PEMask) != 0); + + if(mZT2TrainState == ZT2_PRE_DETECTION_STATE) + { + if(/*S1 != 0 || */Pint != 0 || Pext != 0) + { + RegisterDetection(DETECTION_ZT1_FN_PRE_DETECTION,0,mReferenceTimer->nsecsElapsed()); + } + mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; + } + + switch(mZT2TrainState) + { + case ZT2_PRE_DETECTION_STATE: + { + qDebug("ZT2AnalysisThread::Logic error, in ZT2 Pre detection state and should not..."); + mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; + break; + } + case ZT2_WAIT_FOR_S1_STATE: + { + if(Pint != 0) + { + if(PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_ZT2_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + if(Pext != 0) + { + if(PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_ZT2_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + + if(S1 == 1) + { + Rank++; + CountS1++; + if(Rank %2 == 1) + Bogie++; + + PPIDetected = false; + PPEDetected = false; + + mZT2TrainState = ZT2_S1_ACTIVE_STATE; + } + break; + } + case ZT2_S1_ACTIVE_STATE: + { + if(Pint != 0) + { + if(PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_ZT2_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + if(Pext != 0) + { + if(PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_ZT2_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + + if(S1 == 0) + { + mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; + } + break; + } + }//switch(mZT2TrainState) + + mLastInputs = PCIInputs; + + CZT2ThreadData *Data = new CZT2ThreadData(); + Data->mTimeStamp = mReferenceTimer->nsecsElapsed(); +// Data->mDateTime = QDateTime::currentDateTime(); + Data->mS1 = S1; + Data->mPPExt = Pext; + Data->mPPInt = Pint; + + Data->mBogie = Bogie; + Data->mRank = Rank; + Data->mS1Count = CountS1; + + + emit ZT2DataUpdate(Data); + + }//if(PCIInputs != mLastInputs) + + + mMutex.lock(); + if(mExitLoop == true) + Run = false; + mMutex.unlock(); + + }//while + + mZT2Analyzing = false; + +} + +void CZT2AnalysisThread::TerminateAnalysis() +{ + mMutex.lock(); + mExitLoop = true; + mMutex.unlock(); +} + +bool CZT2AnalysisThread::UpdateDetectionConfig(CZTDetectionFunctionConfig *NewConfig) +{ + //do not update in the middle of a train analysis. + bool Go; + mMutex.lock(); + Go = mZT2Analyzing; + mMutex.unlock(); + + if(Go == true) + return false; + + //No need for a Mutex here since the thread is + //not analyzing. + mDetectionConfig = *NewConfig; + + + return true; +} + +void CZT2AnalysisThread::RegisterDetection(unsigned int DetectionID, unsigned int Rank,qint64 TimeStamp) +{ + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == false) + return; + + + switch(DetectionID) + { + case DETECTION_ZT2_PRE_DETECTION: + { + break; + } + case DETECTION_ZT2_MAGNETIC_SENCOR_COUNT: + { + break; + } + case DETECTION_ZT2_PPI_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive == false) + { + return; + } + break; + } + case DETECTION_ZT2_PPE_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive == false) + { + return; + } + break; + } + } + + + CZTDetectionData *DetectData = new CZTDetectionData; + DetectData->mTimeStap = TimeStamp; + DetectData->mRank = Rank; + DetectData->mDetectionID = DetectionID; + + emit DetectionTriggered(DetectData); + + + qDebug("%s -> Rang %d",CZTData::GetErrorString(DetectionID),Rank); +} + diff --git a/sources/PCIIO/PCIThread.h b/sources/PCIIO/PCIThread.h new file mode 100644 index 0000000..9d8447c --- /dev/null +++ b/sources/PCIIO/PCIThread.h @@ -0,0 +1,90 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est un thread qui lit la carte PCI d'I/O sur laquelle sont + branchées les entrées à haute fréquence. La machine à états analyse le + passage du train et détecte les déclenchements (sondes, frotteur négatif, + pneu porteur). On utilise un thread car l'analyse doit se faire à très + haute fréquence sans être ralentie par l'interface graphique. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZT2ANALYSISTHREAD_H +#define ZT2ANALYSISTHREAD_H + +#include +#include "GlobalDefine.h" +#include "Station.h" +#include +#include "ZTData.h" +#include "QElapsedTimer" + +class CPCIIOMgr; +//class CAbstractLazerProbe; + +class CZT2AnalysisThread : public QObject +{ + Q_OBJECT +public: + CZT2AnalysisThread(); + unsigned int Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks,QElapsedTimer *RefTimer); + void TerminateAnalysis(); + bool UpdateDetectionConfig(CZTDetectionFunctionConfig*); + +private: + enum eTrainState + { + ZT2_PRE_DETECTION_STATE, + ZT2_WAIT_FOR_S1_STATE, + ZT2_S1_ACTIVE_STATE, + + ZT1_TRAIN_TRANSIT_FINISHED_STATE + + }; + + void RegisterDetection(unsigned int DetectionID, unsigned int Rank, qint64 TimeStamp); + + unsigned int mZT2TrainState; + unsigned int mLastInputs; + + bool mExitLoop; + QMutex mMutex; + bool mZT2Analyzing; + + CPCIIOMgr *mPCIInputsHandle; + GenericInputMasks_t *mInputMasksPtr; + + QElapsedTimer *mReferenceTimer; + + CZTDetectionFunctionConfig mDetectionConfig; + + +public slots: + void AnalyzeZT2Train(); + +signals: + void ZT2DataUpdate(CZT2ThreadData* ); + void DetectionTriggered(CZTDetectionData* ); +}; + +#endif // ZT2ANALYSISTHREAD_H diff --git a/sources/PCIIOMgr.cpp b/sources/PCIIOMgr.cpp new file mode 100644 index 0000000..8572988 --- /dev/null +++ b/sources/PCIIOMgr.cpp @@ -0,0 +1,37 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe abstraite pour le polymorphisme de la carte d'entrées PCI interne. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "PCIIOMgr.h" + +CPCIIOMgr::CPCIIOMgr() +{ +} + +CPCIIOMgr::~CPCIIOMgr() +{ + +} diff --git a/sources/PCIIOMgr.h b/sources/PCIIOMgr.h new file mode 100644 index 0000000..57c248f --- /dev/null +++ b/sources/PCIIOMgr.h @@ -0,0 +1,52 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef PCIIOMGR_H +#define PCIIOMGR_H + +enum ePCIIORetValues +{ + PCIIO_OK, + PCIIO_DEVICE_ALREADY_OPENED, + PCIIO_CANNOT_OPEN_DEVICE, + PCIIO_DEVICE_MISMATCH, + PCIIO_INPUTS_SUBDEVICE_MISMATCH, + PCIIO_OUTPUTS_SUBDEVICE_MISMATCH +}; + + +class CPCIIOMgr +{ +public: + CPCIIOMgr(); + virtual ~CPCIIOMgr(); + + virtual unsigned int OpenPCIInterface(void) = 0; + virtual unsigned int GetInputs(void) = 0; +}; + +#endif // PCIIOMGR_H diff --git a/sources/RamMonitor.cpp b/sources/RamMonitor.cpp new file mode 100644 index 0000000..af24515 --- /dev/null +++ b/sources/RamMonitor.cpp @@ -0,0 +1,162 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe permet de connaître la quantité de RAM utilisée par le programme. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "RamMonitor.h" +#include +#include + +//singleton instantiation +CRamMonitor CRamMonitor::mSingleton; + +CRamMonitor::CRamMonitor() +{ + mLastRamUsage = 0; + GetRamUsage(); + + connect(&mRamUsageTimer,SIGNAL(timeout()),this,SLOT(RamUsageTimerExpired())); + + QString FileName; + FileName = "./LOG/RamLog.csv"; + +#ifdef LOG_RAM_USAGE + mRamLogFile = new QFile(FileName); + if(mRamLogFile) + { + mRamLogFile->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text | QIODevice::Unbuffered); + + QString temp; + mRamLogFile->write(temp.sprintf("********************************************************************\n").toAscii().data()); + mRamLogFile->write(temp.sprintf("Création le %s à %s\n",QDateTime::currentDateTime().date().toString("yyyy-MM-dd").toAscii().data(),QDateTime::currentDateTime().time().toString("hh:mm:ss").toAscii().data()).toAscii().data()); + mRamLogFile->write(temp.sprintf("********************************************************************\n").toAscii().data()); + } +#endif +} + +CRamMonitor::~CRamMonitor() +{ +#ifdef LOG_RAM_USAGE + mRamLogFile->close(); + delete mRamLogFile; +#endif +} + +long CRamMonitor::GetRamUsage(bool print) +{ + long rss = 0; + FILE *fp = NULL; + if((fp = fopen("/proc/self/statm","r")) == NULL) + { + fclose(fp); + if(print) + qDebug("cannot open statm"); + + return 0; + } + else + { + if(fscanf(fp,"%*s%ld",&rss) != 1) + { + fclose(fp); + + if(print) + qDebug("Cannot read ram size"); + + return 0; + } + else + { + fclose(fp); + rss *= (long)sysconf(_SC_PAGESIZE); + + if(print) + qDebug("Ram usage: %ld",rss); + + mLastRamUsage = rss; + return rss; + } + } + + //return rss; +} + +long CRamMonitor::GetRamDelta(bool print) +{ + long rss = 0; + FILE *fp = NULL; + if((fp = fopen("/proc/self/statm","r")) == NULL) + { + fclose(fp); + if(print) + qDebug("cannot open statm"); + + return 0; + } + else + { + if(fscanf(fp,"%*s%ld",&rss) != 1) + { + fclose(fp); + + if(print) + qDebug("Cannot read ram size"); + + return 0; + } + else + { + fclose(fp); + rss *= (long)sysconf(_SC_PAGESIZE); + + if(print) + { + qDebug("Ram usage: Previous = %ld [%ldk], Actual = %ld [%ldk], Delta = %ld [%ldk]",mLastRamUsage,mLastRamUsage/1024,rss,rss/1024,(rss-mLastRamUsage),(rss-mLastRamUsage)/1024); + #ifdef LOG_RAM_USAGE + mRamLogFile->write(QString().sprintf("%ld\n",rss).toAscii().data()); + #endif + } + + mLastRamUsage = rss; + return rss; + } + } +} + +void CRamMonitor::StartTimer() +{ + mRamUsageTimer.setSingleShot(false); + mRamUsageTimer.start(5000); +} + +void CRamMonitor::StopTimer() +{ + mRamUsageTimer.stop(); +} + +void CRamMonitor::RamUsageTimerExpired() +{ + GetRamDelta(true); +} diff --git a/sources/RamMonitor.h b/sources/RamMonitor.h new file mode 100644 index 0000000..d7adc7f --- /dev/null +++ b/sources/RamMonitor.h @@ -0,0 +1,70 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130201 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "GlobalDefine.h" + +#ifndef RAMMONITOR_H +#define RAMMONITOR_H + +#include +#include +#include + + + + +class CRamMonitor : public QObject +{ + Q_OBJECT +public: + + //CEngLog is a singleton class + static CRamMonitor* instance(){return &mSingleton;} + static CRamMonitor mSingleton; + + CRamMonitor(); + ~CRamMonitor(); + + long GetRamUsage(bool print = false); + long GetRamDelta(bool print = false); + + void StartTimer(); + void StopTimer(); + +private: + long mLastRamUsage; + QTimer mRamUsageTimer; + +#ifdef LOG_RAM_USAGE + QFile *mRamLogFile; +#endif + +public slots: + void RamUsageTimerExpired(); + +}; + +#endif // RAMMONITOR_H diff --git a/sources/SeaMaxLinux/Makefile b/sources/SeaMaxLinux/Makefile new file mode 100644 index 0000000..3647e20 --- /dev/null +++ b/sources/SeaMaxLinux/Makefile @@ -0,0 +1,39 @@ +# +# $Id: Makefile,v 1.6 2007/01/12 20:20:05 thomasw Exp $ +# +# General build makefile. (Includes) + +INCLUDEDIR ?= /usr/local/include + +CP ?= /bin/cp +RM ?= /bin/rm + + +## ============================================================================ +FILES = seamaxlin.h cethernet.h + + +## ============================================================================ +all: $(FILES) + @echo " *Include dir is prepared." + @echo + +objs: $(FILES) + @echo " *Include dir is prepared." + @echo + +install: $(FILES) + @echo " *Installing header files to $(INCLUDEDIR)" + @for n in $(FILES); do $(CP) -r $$n $(INCLUDEDIR) || exit 1; done + @echo " Done installing header files." + @echo + +uninstall: + @echo " *Uninstalling header files from $(INCLUDEDIR)" + @for n in $(FILES); do $(RM) -rf ${INCLUDEDIR}/$$n || exit 1; done + @echo " Header files removed." + @echo + +clean: $(FILES) + @echo " *Nothing to clean in Include dir." + @echo diff --git a/sources/SeaMaxLinux/cethernet.h b/sources/SeaMaxLinux/cethernet.h new file mode 100644 index 0000000..8192a73 --- /dev/null +++ b/sources/SeaMaxLinux/cethernet.h @@ -0,0 +1,122 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2008, Sealevel Systems +// +// For help please contact us by email at support@sealevel.com. +// +// $Id: cethernet.h,v 1.6 2008/09/24 13:47:40 thomasw Exp $ +// ---------------------------------------------------------------------------- + +#ifndef CETHERNET_H__ +#define CETHERNET_H__ + +// This is for inclusion by the C++ wrapper. +#ifdef __cplusplus + extern "C" { +#endif + +// ---------------------------------------------------------------------------- +// | Structs used in this library. | +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief The device type -- SeaIO_Ethernet or SeaLink_Dev. +/// In the windows version of this library, this function can find both types +/// of devices. To make things simpler, this version of CEthernet only works +/// with SeaIO_Ethernet devices. +// ---------------------------------------------------------------------------- +typedef enum ceth_device_type +{ + SeaIO_Ethernet = 1, ///< Ethernet enabled SeaIO devices. + SeaLink_Dev = 2, ///< Skeletal SeaLink device support. + Sealevel_All_Devices = 99 ///< Any type. +} ceth_device_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief The type of information to set with the set_information function. +/// You may optionally OR two of the commands together. You cannot OR SetDHCP +/// and SetIPAddress. If you do OR one of the IP related functions with +/// SetName, the name parameter should be the last parameter. +// ---------------------------------------------------------------------------- +typedef enum ceth_set_types +{ + SetIPAddress = 1, ///< Option to set a device's IP address. + SetName = 4, ///< Option to set the device's name. + SetDHCP = 2 ///< Option to enable DHCP mode. +} ceth_set_types; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief An IP, NetMask, or GateWay Address. +/// This is a union which will allow you to access the data in one of three +/// data type methods -- long (all 4 bytes at once), short (2 bytes at a time), +/// or char (1 byte at a time). If you access the data 1 byte at a time, through +/// the c array, each octet is the same as the human readable ip address. ie the +/// first octet (0) in the IP 192.168.0.1 can be accessed through +/// ceth_ip_addr.c[2]. +// ---------------------------------------------------------------------------- +typedef union ceth_ip_addr +{ + unsigned long i; ///< Access all 4 bytes at once. + unsigned short s[2]; ///< Access to two bytes at a time. + unsigned char c[4]; ///< Access to each individual byte. +} ceth_ip_addr; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief This is a MAC address storage struct. +/// This struct can only be accessed one byte at a time. +// ---------------------------------------------------------------------------- +typedef struct ceth_addr_info +{ + unsigned char c[6]; ///< The six byte of the MAC address. +} ceth_addr_info; + +// ---------------------------------------------------------------------------- +/// \ingroup group_cethernet_all +/// \brief This is the device info struct. +/// find_devices() expects a list of this structs. The data fields of this +/// struct are filled in in find_device(). Please note that the MAC address can +/// only be retrieved as a privileged user (RAW Sockets). +// ---------------------------------------------------------------------------- +typedef struct ceth_device +{ + ceth_device_type type; ///< SeaLink or SeaIO. + ceth_addr_info mac_address; ///< Device MAC address. + ceth_ip_addr ip_address; ///< IP address. + ceth_ip_addr net_mask; ///< Device Netmask. + ceth_ip_addr gateway; ///< Device Gateway. + char name[20]; ///< Device name (max 8 bytes). + unsigned char dhcp_enabled; ///< Is DHCP mode enabled? + struct ceth_device *next; ///< Pointer to next device. + void *prop_data; ///< Skeleton. Unused. +} ceth_device, *ceth_device_p; + +// ---------------------------------------------------------------------------- +// | The C library function prototypes. | +// ---------------------------------------------------------------------------- + +ceth_device *CEthernet_Alloc(int number); +void CEthernet_Free(ceth_device *list); +int CEthernet_find_devices(ceth_device_type type, int num, ceth_device *list); +int CEthernet_set_information(ceth_device *device, ceth_set_types command, ...); +int CEthernet_recover_module(ceth_device *device); + +// ---------------------------------------------------------------------------- +// | The C++ class! | +// ---------------------------------------------------------------------------- +#ifdef __cplusplus + } + +class CCEthernet { +public: + ceth_device *Alloc(int number); + void Free(ceth_device *list); + int find_devices(ceth_device_type type, int number, ceth_device *list); + int set_information(ceth_device *device, ceth_set_types command, ...); + int recover_module(ceth_device *device); +}; + +#endif //__cplusplus +#endif //CETHERNET_H__ diff --git a/sources/SeaMaxLinux/seamaxlin.h b/sources/SeaMaxLinux/seamaxlin.h new file mode 100644 index 0000000..0eea2b0 --- /dev/null +++ b/sources/SeaMaxLinux/seamaxlin.h @@ -0,0 +1,586 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2008, Sealevel Systems +// +// For help please contact us by email at support@sealevel.com. +// +// $Id: seamaxlin.h,v 1.11 2009/07/13 19:49:55 kmoody Exp $ +// ---------------------------------------------------------------------------- +#ifndef PUBLIC_DOCUMENTATION +/*! \mainpage Linux SeaMax API Documentation + * \section warning Internal Disclaimer + * + * WARNING! This document is intended for internal use only. + */ +#else +/*! \mainpage Linux SeaMAX API Documentation + * + * \section intro_sec Introduction + * + * Sealevel digital and analog I/O modules supported by the SeaMAX software + * suite are designed to work with third party applications via the SeaMAX API. + * To help simplify application development, the following documentation + * details the functions of the SeaMAX API. To help you get started, example + * C and C++ source code is provided. + * + * \section start Getting Started + * + * There are three modules that are included in the SeaMAX API: + * + * \li \ref group_seamax_all
+ * The foundation of SeaMAX with functions for configuring, interfacing, + * and modifying supported Sealevel digital I/O modules and devices. + * \li \ref group_cethernet_all
+ * The Ethernet module contains functions related to the discovery and + * configuration of Sealevel I/O devices with an Ethernet interface. + * \li \ref modbusbreakdown
+ * The Modbus Specification contains detailed descriptions of all RTU + * and TCP Modbus commands applicable to SeaIO and SeaDAC modules. + * + * The 'Modules' tab above lists all SeaMAX modules and their functions. For + * additional information regarding legacy products and technical + * specifications, please refer to the 'Related Pages' tab above. + * + * \section questions Questions & Comments + * + * Send your questions and comments to Sealevel Systems. For technical + * assistance, please include your model or part number and any device + * settings that may apply. Technical support is available Monday to + * Friday from 8:00AM to 5:00PM (US Eastern Time Zone, UTC-6 hours) by + * email (support@sealevel.com) or by phone at +1 (864) 843.4343. + */ + + + +/// \defgroup group_seamax_all SeaMAX API +/// The SeaMAX API consists of the functions outline below, and provides an +/// interface for construction, transmission, and reception of Modbus RTU and +/// TCP commands. For more information, click a function name below for +/// detailed information on function use, parameter types, and return codes. +/// +/// \note Not every function below may apply to your specific Sealevel I/O +/// device. Refer to the \ref modbusbreakdown "modbus breakdown". + +/// \defgroup group_cethernet_all SeaMAX Ethernet Discovery/Configuration API +/// +/// The SeaMAX Ethernet Discover API includes functions used for configuration +/// and discovery of Ethernet enabled Sealevel I/O devices. For specifics, +/// click any of the function names below to view function use, parameters, and +/// return code information. + +/// \ingroup group_seamax_all +/// \defgroup group_seamax_oop Object-Oriented SeaMAX Modbus Interface +/// This is a C++ wrapper for the standard SeaMAX Modbus interface library. +/// This library is designed to aid in the construction, transmission, and +/// reception of Modbus RTU and TCP commands. This library is designed for use +/// with Sealevel SeaIO modules. +/// + +/// \ingroup group_seamax_all +/// \defgroup group_seamax_fun Functional SeaMAX Modbus Interface +/// This is a simple C library to aid in the construction, transmission, and +/// reception of Modbus RTU and TCP commands. This library is designed for use +/// with Sealevel SeaIO modules. +/// + +/// \ingroup group_cethernet_all +/// \defgroup group_cethernet_oop Object Oriented CEthernet Interface +/// This is a C++ wrapper for the standard CEthernet library. This library is +/// designed to aid in the discovery and configuration of Ethernet enabled +/// SeaIO modules. +/// + +/// \ingroup group_cethernet_all +/// \defgroup group_cethernet_fun Functional CEthernet Interface +/// This is a simple C library to aid in the discovery and configuration +/// of Ethernet enabled SeaIO modules. +/// +#endif + +#ifndef SEAMAXLIN_H__ +#define SEAMAXLIN_H__ + +#include "thirdparty/ftdi.h" + +// Sealevel vendor ID number +#define VENDOR 0x0c52 + +// This is used for proper inclusion when used with C++ +#ifdef __cplusplus + extern "C" { +#endif + + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef SeaMaxLin +/// Pointer to a SeaMax object. The data structure this points to is private +/// and should not be accessed directly, but through the function calls instead. +// ---------------------------------------------------------------------------- +typedef long SeaMaxLin; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef HANDLE +/// A handle or pointer to another data structure. +/// This particular pointer is used to pass the serial communications struct. +// ---------------------------------------------------------------------------- +typedef int HANDLE; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef slave_address_t +/// The slave ID of a device. This value can be from 1 to 247. +// ---------------------------------------------------------------------------- +typedef unsigned char slave_address_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef address_loc_t +/// An address specific to your device. Check read/write functions for +/// specific use. +// ---------------------------------------------------------------------------- +typedef unsigned short address_loc_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \typedef address_range_t +/// The range of address to be used. Check read/write functions for specific +/// use. +// ---------------------------------------------------------------------------- +typedef unsigned short address_range_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The module connection type. +/// Currently there is only support for RTU and TCP type connections. +// ---------------------------------------------------------------------------- +typedef enum +{ + NO_CONNECT = 0, ///< Connection not open. + MODBUS_RTU = 1, ///< An RTU type connection. 232, 485, USB. + MODBUS_TCP = 2, ///< An ethernet connection. + FTDI_DIRECT = 3 ///< An ethernet connection. +} seaio_mode_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The current baud rate used by a RTU type module. +/// If the module is TCP type, then BR9600, the default, will be used. +/// Note these are not the same values used by the termios library. +// ---------------------------------------------------------------------------- +typedef enum +{ + BRNONE = 0, ///< Default value, no connection, or unkown baud rate. + BR1200 = 1, ///< 1200 baud. + BR2400 = 2, ///< 2400 baud. + BR4800 = 3, ///< 4800 baud. + BR9600 = 4, ///< 9600 baud. + BR14400 = 5, ///< 14400 baud. + BR19200 = 6, ///< 19200 baud. + BR28800 = 7, ///< 28800 baud. + BR38400 = 8, ///< 38400 baud. + BR57600 = 9, ///< 57600 baud. + BR115200 = 10 ///< 115200 baud. +} baud_rates_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The currently used parity. +/// Parity is a quick and simple method of checking for errors. It doesn't +/// work all the time, but it is very simple to implement. +// ---------------------------------------------------------------------------- +typedef enum +{ + P_NONE = 0, ///< No parity (Default). + P_ODD = 1, ///< Odd parity. + P_EVEN = 2 ///< Even parity. +} parity_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The type of read / write to preform. +/// Note that not all types can be written. For example an attempt to write to +/// D_INPUTS or INPUTREG would cause an EINVAL error. Also you can not directly +/// write to SETUPREGS, you must use an appropriate Ioctl. +// ---------------------------------------------------------------------------- +typedef enum +{ + COILS = 1, ///< Coils are any relay type outputs. + D_INPUTS = 2, ///< Digitial inputs. Single bit inputs. + HOLDINGREG = 3, ///< Configuration registers. + INPUTREG = 4, ///< Registers only used on A/D type devices. + SETUPREG = 5, ///< Advanced device configuration registers. + SEAMAXPIO = 6 ///< Programmable type I/O. +} seaio_type_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \ingroup group_seamax_all +/// \brief The type of IOCTL operation desired. +/// Read the manual carefully when using these. There are some specific +/// methods that must be followed to use correctly. +// ---------------------------------------------------------------------------- +typedef enum +{ + IOCTL_READ_COMM_PARAM = 1, ///< Read communication parameters. + IOCTL_SET_ADDRESS = 2, ///< Set device slave ID. + IOCTL_SET_COMM_PARAM = 3, ///< Set communication parameters. + IOCTL_GET_PIO = 4, ///< Get direction of programmable I/O. + IOCTL_SET_PIO = 5, ///< Set direction of programmable I/O. + IOCTL_GET_ADDA_CONFIG = 6, ///< Get A/D configuration information. + IOCTL_SET_ADDA_CONFIG = 7, ///< Set the A/D configuration. + IOCTL_GET_EXT_CONFIG = 8, ///< Extended module id (SeaDAC). + IOCTL_GET_ADDA_EXT_CONFIG = 9, ///< Information about D/A jumpers. +} IOCTL_t; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief 48 Bit pio configuration. +/// This struct is contained within the \a SeaMAX_PIO_ioctl_s struct. It is +/// used whenever retrieving or setting port direction on a PIO device with +/// 48 bits of I/O. +// ---------------------------------------------------------------------------- +typedef struct PIO48_config_s +{ + unsigned char channel1; ///< Bits 0-5 map ports 1-6. (0:O, 1:I) +} PIO48_config_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief 96 Bit pio configuration. +/// This struct is contained within the \a SeaMAX_PIO_ioctl_s struct. It is +/// used whenever retrieving or setting port direction on a PIO device with +/// 96 bits of I/O. +// ---------------------------------------------------------------------------- +typedef struct PIO96_config_s +{ + unsigned char channel1; ///< Bits 0-5 map ports 1-6. (0:O, 1:I) + unsigned char channel2; ///< Bits 0-5 map ports 7-12. (0:O, 1:I) +} PIO96_config_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief This struct is used to set the address of a particular device. +/// In this way, it becomes unnecessary to manually turn the screw terminal to +/// configure a particular SeaIO device. It also allows for more devices than +/// the physically selectable 15 addresses. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_address_s +{ + unsigned char new_address; ///< Address value from 1 to 247. +} seaio_ioctl_address_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief Communication parameters (desired) struct. +/// This struct can be used to set a desired communication configuration. +/// Note that you must first call get params before you attempt to set params, +/// or it will fail. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_comms_s +{ + baud_rates_t new_baud_rate; ///< Desire baud rate (/a baud_rates_t). + parity_t new_parity; ///< Desire parity (/a parity_t). +} seaio_ioctl_comms_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief Communication parameters (current) struct. +/// This struct can be used to store the current communication parameters. +/// Note that you will have call get params before you may set a configuration, +/// or it will fail. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_get_params_s +{ + unsigned short model; ///< Device model number (410, 462, ...) + unsigned char bridge_type; ///< Bridge type (M, E, U, S, or N). + baud_rates_t baud_rate; ///< The device's communication baud rate. + parity_t parity; ///< The device's communication parity. + unsigned char magic_cookie; ///< \internal Multithread saftey. +} seaio_ioctl_get_params_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief PIO data/setup struct. +/// This struct can be used to read data from a PIO device, or configure a PIO +/// device. +// ---------------------------------------------------------------------------- +typedef struct SeaMAX_PIO_ioctl_s +{ + unsigned short model; ///< Device model number (462, 463, ...) + union + { + PIO48_config_s PIO48; ///< PIO directions /a PIO48_config_s + PIO96_config_s PIO96; ///< PIO directions /a PIO96_config_s + } config_state; +} SeaMAX_PIO_ioctl_s; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief PIO data/setup struct. +/// This struct can be used to read data from a PIO device, or configure a PIO +/// device. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_ext_config +{ + unsigned short model; ///< Device model number (SeaDAC) +} seaio_ioctl_ext_config; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The IOCTL struct used in the majority of the IOCTL calls. +/// Every call except the three involving A/D and D/A converters use this +/// struct. This struct is actually the union of several smaller structs, so +/// that it can be used multiple times. +// ---------------------------------------------------------------------------- +typedef struct seaio_ioctl_s +{ + union + { + seaio_ioctl_address_s address; ///< IOCTL_SET_ADDRESS + seaio_ioctl_comms_s comms; ///< IOCTL_READ_COMM_PARAM + seaio_ioctl_get_params_s params; ///< IOCTL_SET_COMM_PARAM + SeaMAX_PIO_ioctl_s pio; ///< IOCTL_GET/SET_PIO + seaio_ioctl_ext_config config; ///< IOCTL_GET_EXT_CONFIG + } u; ///< Keep size down to largest struct inside. +} seaio_ioctl_s; + +// ---------------------------------------------------------------------------- +// | ADDA structs and types. | +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief ADDA conversion range configuration type. +/// This is the range of voltages that the A/D will convert into values from +/// 0x000 to 0xFFF (0-4095). Plus to minus conversions do use a sign bit, so +/// 4095 is not necessarily the highest value. +// ---------------------------------------------------------------------------- +typedef enum +{ + ZERO_TO_FIVE = 0, ///< 0-5V (0x000-0xFFF) + PLS_MIN_FIVE = 1, ///< -5-5V (0x800-0x7FF) + ZERO_TO_TEN = 2, ///< 0-10V (0x000-0xFFF) + PLS_MIN_TEN = 3 ///< -10-10V (0x800-0x7FF) +} channel_range_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// ADDA mode configuration type. +/// This is how the board is physically configured to read Analog signals. The +/// way to measure. You can either measure 16 signals with a single common +/// ground, 8 isolated signals, or the current pulled through internal resistors +/// from 8 separate signals. +// ---------------------------------------------------------------------------- +typedef enum +{ + SINGLE_ENDED = 0, ///< 16 common ground channels. + DIFFERENTIAL = 1, ///< 8 differential channels. + CURRENT_LOOP = 2 ///< 8 current loop measurements. +} channel_mode_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief ADDA reference type configuration. +/// This controls the mux that is in charge of input to the single A/D chip on +/// an A/D capable device. This provides some small A/D diagnostics if you +/// desire to use them. +// ---------------------------------------------------------------------------- +typedef enum +{ + ANALOG_OFFSET = 0, ///< The A/D inputs available on the device. + GND_OFFSET = 1, ///< A ground value. Should always read 0V. + AD_REF_OFFSET = 2, ///< A/D reference value. Should always read 0V. + DA_CHANNEL_1 = 4, ///< D/A channel one as input. + DA_CHANNEL_2 = 8 ///< D/A channel two as input. +} ad_reference_type; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief The ADDA data struct used in the ADDA ioctl calls. +/// Contains information about device configuration. +// ---------------------------------------------------------------------------- +typedef struct adda_config +{ + /// Overall device settings. + struct + { + unsigned char reference_offset; ///< A/D Mux address. + unsigned char channel_mode; ///< Measurement mode. + + } device; + + /// Each channel uses 2 bits for configuration. + /// Each of the bytes in this struct uses the lowest + /// two bits for each channel configuration. + struct + { + unsigned char ch_1; + unsigned char ch_2; + unsigned char ch_3; + unsigned char ch_4; + unsigned char ch_5; + unsigned char ch_6; + unsigned char ch_7; + unsigned char ch_8; + unsigned char ch_9; + unsigned char ch_10; + unsigned char ch_11; + unsigned char ch_12; + unsigned char ch_13; + unsigned char ch_14; + unsigned char ch_15; + unsigned char ch_16; + + } channels; +} adda_config; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief Data struct returned by get ext adda ioctl. +/// Contains information about the physical jumper configuration of the device. +// ---------------------------------------------------------------------------- +typedef struct adda_ext_config +{ + unsigned char ad_multiplier_enabled; ///< A/D amplifier. + + channel_range_type da_channel_1_range; ///< D/A1 range. + channel_range_type da_channel_2_range; ///< D/A2 range +} adda_ext_config; + +// ---------------------------------------------------------------------------- +/// \ingroup group_seamax_all +/// \brief SeaDAC Lite range configuration type. +/// This is the range of available SeaDAC products +// ---------------------------------------------------------------------------- +typedef enum +{ + SDL_8111 = 0x8111, ///< 4 inputs and 4 reed outputs + SDL_8112, ///< 4 inputs and 4 form-c outputs + SDL_8113, ///< 4 inputs + SDL_8114, ///< 4 reed outputs + SDL_8115, ///< 4 form-c outputs + SDL_8126 = 0x8126 ///< 32 TTL I/O +} sdl_range_type; + +typedef enum +{ + SCL = 0x01, SDA = 0x02, TDO = 0x04, CS = 0x08, + GPIO_0 = 0x01, GPIO_1 = 0x02, GPIO_2 = 0x04, GPIO_3 = 0x08, + GPIO_4 = 0x10, GPIO_5 = 0x20, GPIO_6 = 0x40, GPIO_7 = 0x80 +} sdl_i2c_type; + +// ---------------------------------------------------------------------------- +// SeaMaxModule struct. +// This structure is used internally to keep track of a module that open() has +// been called on. +// ---------------------------------------------------------------------------- +typedef struct seaMaxModule +{ + int throttle; //Throttling delay for RTU mode. + seaio_mode_t commMode; //Communication medium (RTU or TCP). + HANDLE hDevice; //Device comm interface. + int mutex; //Multithread (force sequential). + struct termios *initalConfig; //Original serial configuration. + struct ftdi_context ftdic; //For SeaDAC Lite modules + int deviceType; + +} seaMaxModule; + +// ---------------------------------------------------------------------------- +// | private prototypes | +// ---------------------------------------------------------------------------- +int InitializeI2C(seaMaxModule*); +void ExecuteQueue(seaMaxModule*); +void InitializeQueue(void); +void ExecuteQueue(seaMaxModule*); +void ReadRegister(unsigned char, unsigned char, unsigned char*); +void WriteRegister(unsigned char, unsigned char, unsigned char); +void SetGPIO(unsigned char, unsigned char); + +// ---------------------------------------------------------------------------- +// | API prototypes | +// ---------------------------------------------------------------------------- + +SeaMaxLin *SeaMaxLinCreate(void); +int SeaMaxLinDestroy(SeaMaxLin *SeaMaxPointer); +int SeaMaxLinOpen(SeaMaxLin *SeaMaxPointer, char *filename); +int SeaMaxLinClose(SeaMaxLin *SeaMaxPointer); + +int SeaMaxLinRead(SeaMaxLin *SeaMaxPointer, slave_address_t slaveId, + seaio_type_t type, address_loc_t starting_address, + address_range_t range, void *data); + +int SeaDacLinRead(SeaMaxLin *SeaMaxPointer, unsigned char *data, + int numBytes); + +int SeaMaxLinWrite(SeaMaxLin *SeaMaxPointer, slave_address_t slaveId, + seaio_type_t type, address_loc_t starting_address, + address_range_t range, unsigned char *data); + +int SeaDacLinWrite(SeaMaxLin *SeaMaxPointer, unsigned char *data, + int numBytes); + +int SeaMaxLinIoctl(SeaMaxLin *SeaMaxPointer, slave_address_t slaveId, + IOCTL_t which, void *data); + +int SeaMaxLinSetIMDelay(SeaMaxLin *SeaMaxPointer, int delay); + +int SeaDacGetPIO(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +int SeaDacSetPIO(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +int SeaDacSetPIODirection(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +int SeaDacGetPIODirection(SeaMaxLin *SeaMaxPointer, unsigned char* data); + +HANDLE SeaMaxLinGetCommHandle(SeaMaxLin *SeaMaxPointer); + + + +// ---------------------------------------------------------------------------- +// | End of C library function calls. | +// ---------------------------------------------------------------------------- +#ifdef __cplusplus + } + +class CSeaMaxLin { +public: + + CSeaMaxLin(void); + ~CSeaMaxLin(void); + int Open(char *filename); + int Close(void); + + int Read(slave_address_t slaveId, seaio_type_t type, + address_loc_t starting_address, address_range_t range, + void *data); + + int Read(unsigned char *data, int length); + + int Write(slave_address_t slaveId, seaio_type_t type, + address_loc_t starting_address, + address_range_t range, unsigned char *data); + + int Write(unsigned char *data, int length); + + int Ioctl(slave_address_t slaveId, IOCTL_t which, void *data); + + int set_intermessage_delay(int delay); + + int GetPIO(unsigned char* data); + + int SetPIO(unsigned char* data); + + int SetPIODirection(unsigned char* data); + + int GetPIODirection(unsigned char* data); + + HANDLE getCommHandle(void); + +private: + SeaMaxLin *SeaMaxPointer; +}; + +#endif //__cplusplus +#endif //SEAMAXLIN_H__ diff --git a/sources/SeaMaxLinux/thirdparty/ftdi.h b/sources/SeaMaxLinux/thirdparty/ftdi.h new file mode 100644 index 0000000..45fb907 --- /dev/null +++ b/sources/SeaMaxLinux/thirdparty/ftdi.h @@ -0,0 +1,356 @@ +/*************************************************************************** + ftdi.h - description + ------------------- + begin : Fri Apr 4 2003 + copyright : (C) 2003 by Intra2net AG + email : opensource@intra2net.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License * + * version 2.1 as published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef __libftdi_h__ +#define __libftdi_h__ + +#include + +#define FTDI_DEFAULT_EEPROM_SIZE 128 + +/** FTDI chip type */ +enum ftdi_chip_type { TYPE_AM=0, TYPE_BM=1, TYPE_2232C=2, TYPE_R=3, TYPE_2232H=4, TYPE_4232H=5 }; +/** Parity mode for ftdi_set_line_property() */ +enum ftdi_parity_type { NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4 }; +/** Number of stop bits for ftdi_set_line_property() */ +enum ftdi_stopbits_type { STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2 }; +/** Number of bits for ftdi_set_line_property() */ +enum ftdi_bits_type { BITS_7=7, BITS_8=8 }; +/** Break type for ftdi_set_line_property2() */ +enum ftdi_break_type { BREAK_OFF=0, BREAK_ON=1 }; + +/** MPSSE bitbang modes */ +enum ftdi_mpsse_mode +{ + BITMODE_RESET = 0x00, + BITMODE_BITBANG= 0x01, + BITMODE_MPSSE = 0x02, + BITMODE_SYNCBB = 0x04, + BITMODE_MCU = 0x08, + /* CPU-style fifo mode gets set via EEPROM */ + BITMODE_OPTO = 0x10, + BITMODE_CBUS = 0x20 +}; + +/** Port interface for FT2232C */ +enum ftdi_interface +{ + INTERFACE_ANY = 0, + INTERFACE_A = 1, + INTERFACE_B = 2, + INTERFACE_C = 3, + INTERFACE_D = 4 +}; + +/* Shifting commands IN MPSSE Mode*/ +#define MPSSE_WRITE_NEG 0x01 /* Write TDI/DO on negative TCK/SK edge*/ +#define MPSSE_BITMODE 0x02 /* Write bits, not bytes */ +#define MPSSE_READ_NEG 0x04 /* Sample TDO/DI on negative TCK/SK edge */ +#define MPSSE_LSB 0x08 /* LSB first */ +#define MPSSE_DO_WRITE 0x10 /* Write TDI/DO */ +#define MPSSE_DO_READ 0x20 /* Read TDO/DI */ +#define MPSSE_WRITE_TMS 0x40 /* Write TMS/CS */ + +/* FTDI MPSSE commands */ +#define SET_BITS_LOW 0x80 +/*BYTE DATA*/ +/*BYTE Direction*/ +#define SET_BITS_HIGH 0x82 +/*BYTE DATA*/ +/*BYTE Direction*/ +#define GET_BITS_LOW 0x81 +#define GET_BITS_HIGH 0x83 +#define LOOPBACK_START 0x84 +#define LOOPBACK_END 0x85 +#define TCK_DIVISOR 0x86 +/* Value Low */ +/* Value HIGH */ /*rate is 12000000/((1+value)*2) */ +#define DIV_VALUE(rate) (rate > 6000000)?0:((6000000/rate -1) > 0xffff)? 0xffff: (6000000/rate -1) + +/* Commands in MPSSE and Host Emulation Mode */ +#define SEND_IMMEDIATE 0x87 +#define WAIT_ON_HIGH 0x88 +#define WAIT_ON_LOW 0x89 + +/* Commands in Host Emulation Mode */ +#define READ_SHORT 0x90 +/* Address_Low */ +#define READ_EXTENDED 0x91 +/* Address High */ +/* Address Low */ +#define WRITE_SHORT 0x92 +/* Address_Low */ +#define WRITE_EXTENDED 0x93 +/* Address High */ +/* Address Low */ + +/* Definitions for flow control */ +#define SIO_RESET 0 /* Reset the port */ +#define SIO_MODEM_CTRL 1 /* Set the modem control register */ +#define SIO_SET_FLOW_CTRL 2 /* Set flow control register */ +#define SIO_SET_BAUD_RATE 3 /* Set baud rate */ +#define SIO_SET_DATA 4 /* Set the data characteristics of the port */ + +#define FTDI_DEVICE_OUT_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT) +#define FTDI_DEVICE_IN_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN) + +/* Requests */ +#define SIO_RESET_REQUEST SIO_RESET +#define SIO_SET_BAUDRATE_REQUEST SIO_SET_BAUD_RATE +#define SIO_SET_DATA_REQUEST SIO_SET_DATA +#define SIO_SET_FLOW_CTRL_REQUEST SIO_SET_FLOW_CTRL +#define SIO_SET_MODEM_CTRL_REQUEST SIO_MODEM_CTRL +#define SIO_POLL_MODEM_STATUS_REQUEST 0x05 +#define SIO_SET_EVENT_CHAR_REQUEST 0x06 +#define SIO_SET_ERROR_CHAR_REQUEST 0x07 +#define SIO_SET_LATENCY_TIMER_REQUEST 0x09 +#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A +#define SIO_SET_BITMODE_REQUEST 0x0B +#define SIO_READ_PINS_REQUEST 0x0C +#define SIO_READ_EEPROM_REQUEST 0x90 +#define SIO_WRITE_EEPROM_REQUEST 0x91 +#define SIO_ERASE_EEPROM_REQUEST 0x92 + + +#define SIO_RESET_SIO 0 +#define SIO_RESET_PURGE_RX 1 +#define SIO_RESET_PURGE_TX 2 + +#define SIO_DISABLE_FLOW_CTRL 0x0 +#define SIO_RTS_CTS_HS (0x1 << 8) +#define SIO_DTR_DSR_HS (0x2 << 8) +#define SIO_XON_XOFF_HS (0x4 << 8) + +#define SIO_SET_DTR_MASK 0x1 +#define SIO_SET_DTR_HIGH ( 1 | ( SIO_SET_DTR_MASK << 8)) +#define SIO_SET_DTR_LOW ( 0 | ( SIO_SET_DTR_MASK << 8)) +#define SIO_SET_RTS_MASK 0x2 +#define SIO_SET_RTS_HIGH ( 2 | ( SIO_SET_RTS_MASK << 8 )) +#define SIO_SET_RTS_LOW ( 0 | ( SIO_SET_RTS_MASK << 8 )) + +#define SIO_RTS_CTS_HS (0x1 << 8) + +/* marker for unused usb urb structures + (taken from libusb) */ +#define FTDI_URB_USERCONTEXT_COOKIE ((void *)0x1) + +/** + \brief Main context structure for all libftdi functions. + + Do not access directly if possible. +*/ +struct ftdi_context +{ + /* USB specific */ + /** libusb's usb_dev_handle */ + struct usb_dev_handle *usb_dev; + /** usb read timeout */ + int usb_read_timeout; + /** usb write timeout */ + int usb_write_timeout; + + /* FTDI specific */ + /** FTDI chip type */ + enum ftdi_chip_type type; + /** baudrate */ + int baudrate; + /** bitbang mode state */ + unsigned char bitbang_enabled; + /** pointer to read buffer for ftdi_read_data */ + unsigned char *readbuffer; + /** read buffer offset */ + unsigned int readbuffer_offset; + /** number of remaining data in internal read buffer */ + unsigned int readbuffer_remaining; + /** read buffer chunk size */ + unsigned int readbuffer_chunksize; + /** write buffer chunk size */ + unsigned int writebuffer_chunksize; + + /* FTDI FT2232C requirecments */ + /** FT2232C interface number: 0 or 1 */ + int interface; /* 0 or 1 */ + /** FT2232C index number: 1 or 2 */ + int index; /* 1 or 2 */ + /* Endpoints */ + /** FT2232C end points: 1 or 2 */ + int in_ep; + int out_ep; /* 1 or 2 */ + + /** Bitbang mode. 1: (default) Normal bitbang mode, 2: FT2232C SPI bitbang mode */ + unsigned char bitbang_mode; + + /** EEPROM size. Default is 128 bytes for 232BM and 245BM chips */ + int eeprom_size; + + /** String representation of last error */ + char *error_str; + + /** Buffer needed for async communication */ + char *async_usb_buffer; + /** Number of URB-structures we can buffer */ + unsigned int async_usb_buffer_size; +}; + +/** + \brief list of usb devices created by ftdi_usb_find_all() +*/ +struct ftdi_device_list +{ + /** pointer to next entry */ + struct ftdi_device_list *next; + /** pointer to libusb's usb_device */ + struct usb_device *dev; +}; + +/** + \brief FTDI eeprom structure +*/ +struct ftdi_eeprom +{ + /** vendor id */ + int vendor_id; + /** product id */ + int product_id; + + /** self powered */ + int self_powered; + /** remote wakeup */ + int remote_wakeup; + /** chip type */ + int BM_type_chip; + + /** input in isochronous transfer mode */ + int in_is_isochronous; + /** output in isochronous transfer mode */ + int out_is_isochronous; + /** suspend pull downs */ + int suspend_pull_downs; + + /** use serial */ + int use_serial; + /** fake usb version */ + int change_usb_version; + /** usb version */ + int usb_version; + /** maximum power */ + int max_power; + + /** manufacturer name */ + char *manufacturer; + /** product name */ + char *product; + /** serial number */ + char *serial; + + /** eeprom size in bytes. This doesn't get stored in the eeprom + but is the only way to pass it to ftdi_eeprom_build. */ + int size; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + + int ftdi_init(struct ftdi_context *ftdi); + struct ftdi_context *ftdi_new(); + int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface interface); + + void ftdi_deinit(struct ftdi_context *ftdi); + void ftdi_free(struct ftdi_context *ftdi); + void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usbdev); + + int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devlist, + int vendor, int product); + void ftdi_list_free(struct ftdi_device_list **devlist); + void ftdi_list_free2(struct ftdi_device_list *devlist); + int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct usb_device *dev, + char * manufacturer, int mnf_len, + char * description, int desc_len, + char * serial, int serial_len); + + int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product); + int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, + const char* description, const char* serial); + int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev); + + int ftdi_usb_close(struct ftdi_context *ftdi); + int ftdi_usb_reset(struct ftdi_context *ftdi); + int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi); + int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi); + int ftdi_usb_purge_buffers(struct ftdi_context *ftdi); + + int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate); + int ftdi_set_line_property(struct ftdi_context *ftdi, enum ftdi_bits_type bits, + enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity); + int ftdi_set_line_property2(struct ftdi_context *ftdi, enum ftdi_bits_type bits, + enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity, + enum ftdi_break_type break_type); + + int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size); + int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); + int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); + + int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size); + int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); + int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); + + int ftdi_write_data_async(struct ftdi_context *ftdi, unsigned char *buf, int size); + void ftdi_async_complete(struct ftdi_context *ftdi, int wait_for_more); + + int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask); + int ftdi_disable_bitbang(struct ftdi_context *ftdi); + int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode); + int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins); + + int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency); + int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency); + + int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status); + + /* flow control */ + int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl); + int ftdi_setdtr_rts(struct ftdi_context *ftdi, int dtr, int rts); + int ftdi_setdtr(struct ftdi_context *ftdi, int state); + int ftdi_setrts(struct ftdi_context *ftdi, int state); + + int ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable); + int ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable); + + /* set eeprom size */ + void ftdi_eeprom_setsize(struct ftdi_context *ftdi, struct ftdi_eeprom *eeprom, int size); + + /* init and build eeprom from ftdi_eeprom structure */ + void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom); + int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output); + int ftdi_eeprom_decode(struct ftdi_eeprom *eeprom, unsigned char *output, int size); + + /* "eeprom" needs to be valid 128 byte eeprom (generated by the eeprom generator) + the checksum of the eeprom is valided */ + int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid); + int ftdi_read_eeprom_getsize(struct ftdi_context *ftdi, unsigned char *eeprom, int maxsize); + int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_erase_eeprom(struct ftdi_context *ftdi); + + char *ftdi_get_error_string(struct ftdi_context *ftdi); + +#ifdef __cplusplus +} +#endif + +#endif /* __libftdi_h__ */ diff --git a/sources/SerialPort/libqextserialport.a b/sources/SerialPort/libqextserialport.a new file mode 100644 index 0000000..3576446 Binary files /dev/null and b/sources/SerialPort/libqextserialport.a differ diff --git a/sources/SerialPort/qextserialport.h b/sources/SerialPort/qextserialport.h new file mode 100755 index 0000000..5334e94 --- /dev/null +++ b/sources/SerialPort/qextserialport.h @@ -0,0 +1,240 @@ +/**************************************************************************** +** Copyright (c) 2000-2003 Wayne Roth +** Copyright (c) 2004-2007 Stefan Sander +** Copyright (c) 2007 Michal Policht +** Copyright (c) 2008 Brandon Fosdick +** Copyright (c) 2009-2010 Liam Staskawicz +** Copyright (c) 2011 Debao Zhang +** All right reserved. +** Web: http://code.google.com/p/qextserialport/ +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ + +#ifndef _QEXTSERIALPORT_H_ +#define _QEXTSERIALPORT_H_ + +#include +#include "qextserialport_global.h" +#ifdef Q_OS_UNIX +#include +#endif +/*line status constants*/ +// ### QESP2.0 move to enum +#define LS_CTS 0x01 +#define LS_DSR 0x02 +#define LS_DCD 0x04 +#define LS_RI 0x08 +#define LS_RTS 0x10 +#define LS_DTR 0x20 +#define LS_ST 0x40 +#define LS_SR 0x80 + +/*error constants*/ +// ### QESP2.0 move to enum +#define E_NO_ERROR 0 +#define E_INVALID_FD 1 +#define E_NO_MEMORY 2 +#define E_CAUGHT_NON_BLOCKED_SIGNAL 3 +#define E_PORT_TIMEOUT 4 +#define E_INVALID_DEVICE 5 +#define E_BREAK_CONDITION 6 +#define E_FRAMING_ERROR 7 +#define E_IO_ERROR 8 +#define E_BUFFER_OVERRUN 9 +#define E_RECEIVE_OVERFLOW 10 +#define E_RECEIVE_PARITY_ERROR 11 +#define E_TRANSMIT_OVERFLOW 12 +#define E_READ_FAILED 13 +#define E_WRITE_FAILED 14 +#define E_FILE_NOT_FOUND 15 +#define E_PERMISSION_DENIED 16 +#define E_AGAIN 17 + +enum BaudRateType +{ +#if defined(Q_OS_UNIX) || defined(qdoc) + BAUD50 = 50, //POSIX ONLY + BAUD75 = 75, //POSIX ONLY + BAUD134 = 134, //POSIX ONLY + BAUD150 = 150, //POSIX ONLY + BAUD200 = 200, //POSIX ONLY + BAUD1800 = 1800, //POSIX ONLY +# if defined(B76800) || defined(qdoc) + BAUD76800 = 76800, //POSIX ONLY +# endif +# if (defined(B230400) && defined(B4000000)) || defined(qdoc) + BAUD230400 = 230400, //POSIX ONLY + BAUD460800 = 460800, //POSIX ONLY + BAUD500000 = 500000, //POSIX ONLY + BAUD576000 = 576000, //POSIX ONLY + BAUD921600 = 921600, //POSIX ONLY + BAUD1000000 = 1000000, //POSIX ONLY + BAUD1152000 = 1152000, //POSIX ONLY + BAUD1500000 = 1500000, //POSIX ONLY + BAUD2000000 = 2000000, //POSIX ONLY + BAUD2500000 = 2500000, //POSIX ONLY + BAUD3000000 = 3000000, //POSIX ONLY + BAUD3500000 = 3500000, //POSIX ONLY + BAUD4000000 = 4000000, //POSIX ONLY +# endif +#endif //Q_OS_UNIX +#if defined(Q_OS_WIN) || defined(qdoc) + BAUD14400 = 14400, //WINDOWS ONLY + BAUD56000 = 56000, //WINDOWS ONLY + BAUD128000 = 128000, //WINDOWS ONLY + BAUD256000 = 256000, //WINDOWS ONLY +#endif //Q_OS_WIN + BAUD110 = 110, + BAUD300 = 300, + BAUD600 = 600, + BAUD1200 = 1200, + BAUD2400 = 2400, + BAUD4800 = 4800, + BAUD9600 = 9600, + BAUD19200 = 19200, + BAUD38400 = 38400, + BAUD57600 = 57600, + BAUD115200 = 115200 +}; + +enum DataBitsType +{ + DATA_5 = 5, + DATA_6 = 6, + DATA_7 = 7, + DATA_8 = 8 +}; + +enum ParityType +{ + PAR_NONE, + PAR_ODD, + PAR_EVEN, +#if defined(Q_OS_WIN) || defined(qdoc) + PAR_MARK, //WINDOWS ONLY +#endif + PAR_SPACE +}; + +enum StopBitsType +{ + STOP_1, +#if defined(Q_OS_WIN) || defined(qdoc) + STOP_1_5, //WINDOWS ONLY +#endif + STOP_2 +}; + +enum FlowType +{ + FLOW_OFF, + FLOW_HARDWARE, + FLOW_XONXOFF +}; + +/** + * structure to contain port settings + */ +struct PortSettings +{ + BaudRateType BaudRate; + DataBitsType DataBits; + ParityType Parity; + StopBitsType StopBits; + FlowType FlowControl; + long Timeout_Millisec; +}; + +class QextSerialPortPrivate; +class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QextSerialPort) + Q_ENUMS(QueryMode) + Q_PROPERTY(QString portName READ portName WRITE setPortName) + Q_PROPERTY(QueryMode queryMode READ queryMode WRITE setQueryMode) +public: + enum QueryMode { + Polling, + EventDriven + }; + + explicit QextSerialPort(QueryMode mode = EventDriven, QObject *parent = 0); + explicit QextSerialPort(const QString &name, QueryMode mode = EventDriven, QObject *parent = 0); + explicit QextSerialPort(const PortSettings &s, QueryMode mode = EventDriven, QObject *parent = 0); + QextSerialPort(const QString &name, const PortSettings &s, QueryMode mode = EventDriven, QObject *parent=0); + + ~QextSerialPort(); + + QString portName() const; + QueryMode queryMode() const; + BaudRateType baudRate() const; + DataBitsType dataBits() const; + ParityType parity() const; + StopBitsType stopBits() const; + FlowType flowControl() const; + + bool open(OpenMode mode); + bool isSequential() const; + void close(); + void flush(); + qint64 bytesAvailable() const; + bool canReadLine() const; + QByteArray readAll(); + + ulong lastError() const; + + ulong lineStatus(); + QString errorString(); + +public Q_SLOTS: + void setPortName(const QString &name); + void setQueryMode(QueryMode mode); + void setBaudRate(BaudRateType); + void setDataBits(DataBitsType); + void setParity(ParityType); + void setStopBits(StopBitsType); + void setFlowControl(FlowType); + void setTimeout(long); + + void setDtr(bool set=true); + void setRts(bool set=true); + +Q_SIGNALS: + void dsrChanged(bool status); + +protected: + qint64 readData(char *data, qint64 maxSize); + qint64 writeData(const char *data, qint64 maxSize); + +private: + Q_DISABLE_COPY(QextSerialPort) + +#ifdef Q_OS_WIN + Q_PRIVATE_SLOT(d_func(), void _q_onWinEvent(HANDLE)) +#endif + Q_PRIVATE_SLOT(d_func(), void _q_canRead()) + + QextSerialPortPrivate *const d_ptr; +}; + +#endif diff --git a/sources/SerialPort/qextserialport_global.h b/sources/SerialPort/qextserialport_global.h new file mode 100755 index 0000000..824d455 --- /dev/null +++ b/sources/SerialPort/qextserialport_global.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** Copyright (c) 2000-2003 Wayne Roth +** Copyright (c) 2004-2007 Stefan Sander +** Copyright (c) 2007 Michal Policht +** Copyright (c) 2008 Brandon Fosdick +** Copyright (c) 2009-2010 Liam Staskawicz +** Copyright (c) 2011 Debao Zhang +** All right reserved. +** Web: http://code.google.com/p/qextserialport/ +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +****************************************************************************/ + +#ifndef QEXTSERIALPORT_GLOBAL_H +#define QEXTSERIALPORT_GLOBAL_H + +#include + +#ifdef QEXTSERIALPORT_BUILD_SHARED +# define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT +#elif defined(QEXTSERIALPORT_USING_SHARED) +# define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT +#else +# define QEXTSERIALPORT_EXPORT +#endif + +// ### for compatible with old version. should be removed in QESP 2.0 +#ifdef _TTY_NOWARN_ +# define QESP_NO_WARN +#endif +#ifdef _TTY_NOWARN_PORT_ +# define QESP_NO_PORTABILITY_WARN +#endif + +/*if all warning messages are turned off, flag portability warnings to be turned off as well*/ +#ifdef QESP_NO_WARN +# define QESP_NO_PORTABILITY_WARN +#endif + +/*macros for warning and debug messages*/ +#ifdef QESP_NO_PORTABILITY_WARN +# define QESP_PORTABILITY_WARNING while (false)qWarning +#else +# define QESP_PORTABILITY_WARNING qWarning +#endif /*QESP_NOWARN_PORT*/ + +#ifdef QESP_NO_WARN +# define QESP_WARNING while (false)qWarning +#else +# define QESP_WARNING qWarning +#endif /*QESP_NOWARN*/ + +#endif // QEXTSERIALPORT_GLOBAL_H + diff --git a/sources/Simulator/SImulatorOutputModule.cpp b/sources/Simulator/SImulatorOutputModule.cpp new file mode 100644 index 0000000..e223254 --- /dev/null +++ b/sources/Simulator/SImulatorOutputModule.cpp @@ -0,0 +1,107 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable d'un module d'entrées externe simulé. Dérivée de COutputModule, elle + permet d'émuler les sorties du module externe en réimplémentant les fonctions + génériques de sa classe de base. La classe notifie le simulateur d'un changement + d'état des sorties afin que ce dernier puisse les afficher visuellement. +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SImulatorOutputModule.h" +#include "ZTSimulator.h" + +CSImulatorOutputModule::CSImulatorOutputModule() +{ + mOutputBuffer = 0; + mSimulatorPtr = 0; +} + +unsigned int CSImulatorOutputModule::SetOutput(unsigned char *buffer) +{ +// quint32 temp; +// mRdWrLock.lockForWrite(); +// mOutputBuffer |= FlagMask; +// temp = mOutputBuffer; +// mRdWrLock.unlock(); + Q_UNUSED(buffer) + + return RET_OK; +} + +unsigned int CSImulatorOutputModule::SetOutput(quint32 buffer) +{ + quint32 temp; + mRdWrLock.lockForWrite(); + mOutputBuffer = buffer; + temp = mOutputBuffer; + mRdWrLock.unlock(); + + +// mSimulatorPtr->UpdateOutputsDisplay(temp); + emit UpdateOutputsDisplay(temp); + + return RET_OK; +} + +unsigned int CSImulatorOutputModule::SetOutputFlags(quint32 FlagMask) +{ + quint32 temp; + mRdWrLock.lockForWrite(); + mOutputBuffer |= FlagMask; + temp = mOutputBuffer; + mRdWrLock.unlock(); + + emit UpdateOutputsDisplay(temp); +// mSimulatorPtr->UpdateOutputsDisplay(temp); + + return RET_OK; +} + +unsigned int CSImulatorOutputModule::ClearOutputFlags(quint32 FlagMask) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mOutputBuffer &= ~FlagMask; + temp = mOutputBuffer; + mRdWrLock.unlock(); + + /* mSimulatorPtr->UpdateOutputsDisplay(temp)*/; + emit UpdateOutputsDisplay(temp); + + return RET_OK; +} + + +unsigned int CSImulatorOutputModule::ToggleOutputFlags(quint32 FlagMask) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mOutputBuffer ^= FlagMask; + temp = mOutputBuffer; + mRdWrLock.unlock(); + +// mSimulatorPtr->UpdateOutputsDisplay(temp); + emit UpdateOutputsDisplay(temp); + + return RET_OK; +} diff --git a/sources/Simulator/SImulatorOutputModule.h b/sources/Simulator/SImulatorOutputModule.h new file mode 100644 index 0000000..dc8b4a2 --- /dev/null +++ b/sources/Simulator/SImulatorOutputModule.h @@ -0,0 +1,61 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATOROUTPUTMODULE_H +#define SIMULATOROUTPUTMODULE_H + +#include "GlobalDefine.h" +#include "OutputModule.h" +#include +#include + +class CZTSimulator; + +class CSImulatorOutputModule:public QObject, public COutputModule +{ + Q_OBJECT +public: + CSImulatorOutputModule(); + void BindSimPtr(CZTSimulator *Ptr){mSimulatorPtr = Ptr;} + + virtual unsigned int SetOutput(unsigned char* buffer); + virtual unsigned int SetOutput(quint32 buffer); + virtual unsigned int SetOutputFlags(quint32 Flags); + virtual unsigned int ClearOutputFlags(quint32 Flags); + virtual unsigned int ToggleOutputFlags(quint32 Flags); + +private: + quint32 mOutputBuffer; + QReadWriteLock mRdWrLock; + CZTSimulator *mSimulatorPtr; + + signals: + void UpdateOutputsDisplay(quint32); + +}; + +#endif // SIMULATOROUTPUTMODULE_H diff --git a/sources/Simulator/SimulationScenario.cpp b/sources/Simulator/SimulationScenario.cpp new file mode 100644 index 0000000..3988e99 --- /dev/null +++ b/sources/Simulator/SimulationScenario.cpp @@ -0,0 +1,256 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Gère la création et l'exécution d'un scénario de passage de train simulé. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SimulationScenario.h" + +#define BOGIE_DELAY 100 +#define SENSOR_DELAY 100 + +CSimulationScenario::CSimulationScenario() +{ + mCurStep = 0; + + mScenarioTimer = new QTimer(); + mScenarioTimer->setSingleShot(true); + connect(mScenarioTimer,SIGNAL(timeout()),this,SLOT(ScenarioTimerExpired())); +} + +CSimulationScenario::~CSimulationScenario() +{ + DestroyScenario(); +} + +unsigned int CSimulationScenario::CreateScenario() +{ + + +// //MPM10 +// InsertNewStep(STEP_ACTION_REGISTER_ZT1_ITI,300); +// InsertNewStep(STEP_ACTION_OCCUPY_ZT1_APPROACH,300); +// InsertNewStep(STEP_ACTION_OCCUPY_ZT1,300); + +// for(int bogie = 1; bogie <= 3; bogie++) +// { + +// //if(bogie != 5 /*&& bogie != 6*/) +//// InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0); +//// InsertNewStep(STEP_ACTION_ACTIVATE_PGE,5); + +// InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY); +// InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY); + +// InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0); +// InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0); + +//// if(bogie != 5 && bogie != 6) +// InsertNewStep(STEP_ACTION_ACTIVATE_FN,5); +// InsertNewStep(STEP_ACTION_ACTIVATE_FN,5); + +//// if(bogie == 12) +//// InsertNewStep(STEP_ACTION_ACTIVATE_PPI,0); + +// InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY); +// InsertNewStep(STEP_ACTION_DEACTIVATE_S2,SENSOR_DELAY); + + +// InsertNewStep(STEP_ACTION_DEACTIVATE_FN,5); + +// InsertNewStep(STEP_ACTION_DEACTIVATE_PPI,5); + +// InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY); +// InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY); + + +// //if(bogie != 5 /*&& bogie != 6 && bogie != 7*/) +//// InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0); +//// InsertNewStep(STEP_ACTION_ACTIVATE_PGE,5); +// InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY); +// InsertNewStep(STEP_ACTION_DEACTIVATE_S2,BOGIE_DELAY); +// InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0); +// InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0); + +// } + + +// // InsertNewStep(STEP_ACTION_DESTROY_ZT1_ITI,800); +// InsertNewStep(STEP_ACTION_FREE_ZT1_APPROACH,800); +// InsertNewStep(STEP_ACTION_FREE_ZT1,800); + + + + + +//// //ZT2 + + +// InsertNewStep(STEP_ACTION_REGISTER_ZT2_ITI,300); +// InsertNewStep(STEP_ACTION_OCCUPY_ZT2,300); + +// for(int bogie = 1; bogie <= 18; bogie++) +// { +// InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_S1,SENSOR_DELAY); +// InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_S1,BOGIE_DELAY); + +// // if(bogie == 5 || bogie == 2) +// { +// // InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_PPE,5); +// // InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_PPE,1); + +// } + +// // if(bogie == 3 || bogie == 10) +// { +//// InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_PPI,3); +//// InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_PPI,1); + +// } + +// //if(bogie != 3) +// { +// InsertNewStep(STEP_ACTION_ACTIVATE_ZT2_S1,SENSOR_DELAY); +// InsertNewStep(STEP_ACTION_DEACTIVATE_ZT2_S1,BOGIE_DELAY); +// } + + +// } + +// InsertNewStep(STEP_ACTION_DESTROY_ZT2_ITI,800); +// InsertNewStep(STEP_ACTION_FREE_ZT2,800); + + + +//// MR + InsertNewStep(STEP_ACTION_REGISTER_ZT1_ITI,300); + InsertNewStep(STEP_ACTION_OCCUPY_ZT1_APPROACH,300); + InsertNewStep(STEP_ACTION_OCCUPY_ZT1,300); + + for(int bogie = 1; bogie <= 12; bogie++) + { + // if(bogie != 5 && bogie != 7) + InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0); + InsertNewStep(STEP_ACTION_ACTIVATE_PGE,0); + InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY); + InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY); + InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0); + InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0); + + +// if(bogie != 5 && bogie != 8) + InsertNewStep(STEP_ACTION_ACTIVATE_FN,0); + + InsertNewStep(STEP_ACTION_ACTIVATE_S1,SENSOR_DELAY); + InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY); + InsertNewStep(STEP_ACTION_DEACTIVATE_S1,BOGIE_DELAY); +// if(bogie == 12) +// InsertNewStep(STEP_ACTION_ACTIVATE_PPI,0); + +// if(bogie != 5 && bogie != 8) + InsertNewStep(STEP_ACTION_DEACTIVATE_FN,0); + +// InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY); + InsertNewStep(STEP_ACTION_DEACTIVATE_S2,BOGIE_DELAY); + +// if(bogie == 12) +// InsertNewStep(STEP_ACTION_DEACTIVATE_PPI,0); + + if(bogie != 2 && bogie != 11) + InsertNewStep(STEP_ACTION_ACTIVATE_PGI,0); + if(bogie != 2 && bogie != 11) + InsertNewStep(STEP_ACTION_ACTIVATE_PGE,0); + InsertNewStep(STEP_ACTION_ACTIVATE_S2,SENSOR_DELAY); + InsertNewStep(STEP_ACTION_DEACTIVATE_S2,BOGIE_DELAY); + InsertNewStep(STEP_ACTION_DEACTIVATE_PGI,0); + InsertNewStep(STEP_ACTION_DEACTIVATE_PGE,0); + + } + + + InsertNewStep(STEP_ACTION_DESTROY_ZT1_ITI,800); + + InsertNewStep(STEP_ACTION_FREE_ZT1,800); + + InsertNewStep(STEP_ACTION_FREE_ZT1_APPROACH,800); + + return RET_OK; +} + +unsigned int CSimulationScenario::DestroyScenario() +{ + for(int i = 0; i < mScenarioStepsList.size(); i++) + { + delete mScenarioStepsList.at(i); + } + mScenarioStepsList.clear(); + return RET_OK; +} +unsigned int CSimulationScenario::Start() +{ + emit ExecuteNextStep(mScenarioStepsList.at(mCurStep)); + mScenarioTimer->start(mScenarioStepsList.at(mCurStep)->StepDelayMillisecs); + return RET_OK; +} +unsigned int CSimulationScenario::Reset() +{ + mScenarioTimer->stop(); + mCurStep = 0; + return RET_OK; +} + +void CSimulationScenario::ScenarioTimerExpired() +{ + if(mCurStep == mScenarioStepsList.size()) //the simulation is finished + { + Reset(); + emit ScenarioCompleted(); + return; + } + + emit ExecuteNextStep(mScenarioStepsList.at(mCurStep)); + mScenarioTimer->start(mScenarioStepsList.at(mCurStep)->StepDelayMillisecs); + mCurStep++; + +} + +//Cette fonction ajoute un événement dans la liste. Le paramètre Delay correspond +//au nombre de millisecondes de délai entre l'exécution de cet événement et l'exécution +//de l'événement subséquent. Un délai de 0 correspond au délai le plus court que la boucle +//d'exécution est capable de générer. +//Ex.: InsertNewStep(STEP_ACTION_REGISTER_ZT1_ITI,300); +//Activera l'entrée itinéraire ZT1 dans le simulateur et l'étape suivante sera +//exécutée 300ms plus tard. +//NOTE: Les délais sont approximatifs et gagnent de la précision lorsque le programme +//roule sur un ordinateur plus puissant. +unsigned int CSimulationScenario::InsertNewStep(unsigned int StepID, int Delay) +{ + CSimulationStep *NewStep = new CSimulationStep; + + NewStep->StepAction = StepID; + NewStep->StepDelayMillisecs = Delay; + mScenarioStepsList.append(NewStep); + + return mScenarioStepsList.size(); +} diff --git a/sources/Simulator/SimulationScenario.h b/sources/Simulator/SimulationScenario.h new file mode 100644 index 0000000..1816797 --- /dev/null +++ b/sources/Simulator/SimulationScenario.h @@ -0,0 +1,111 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATIONSCENARIO_H +#define SIMULATIONSCENARIO_H +#include "GlobalDefine.h" +#include +#include +#include + + +enum eStepActionID +{ + STEP_ACTION_DELAY, + STEP_ACTION_ACTIVATE_S1, + STEP_ACTION_DEACTIVATE_S1, + STEP_ACTION_ACTIVATE_S2, + STEP_ACTION_DEACTIVATE_S2, + STEP_ACTION_ACTIVATE_FN, + STEP_ACTION_DEACTIVATE_FN, + STEP_ACTION_ACTIVATE_PPI, + STEP_ACTION_DEACTIVATE_PPI, + STEP_ACTION_ACTIVATE_PPE, + STEP_ACTION_DEACTIVATE_PPE, + STEP_ACTION_ACTIVATE_PGI, + STEP_ACTION_DEACTIVATE_PGI, + STEP_ACTION_ACTIVATE_PGE, + STEP_ACTION_DEACTIVATE_PGE, + STEP_ACTION_REGISTER_ZT1_ITI, + STEP_ACTION_DESTROY_ZT1_ITI, + STEP_ACTION_REGISTER_ZT2_ITI, + STEP_ACTION_DESTROY_ZT2_ITI, + STEP_ACTION_OCCUPY_ZT1_APPROACH, + STEP_ACTION_FREE_ZT1_APPROACH, + STEP_ACTION_OCCUPY_ZT1, + STEP_ACTION_FREE_ZT1, + STEP_ACTION_OCCUPY_ZT2_APPROACH, + STEP_ACTION_FREE_ZT2_APPROACH, + STEP_ACTION_OCCUPY_ZT2, + STEP_ACTION_FREE_ZT2, + STEP_ACTION_ACTIVATE_ZT2_S1, + STEP_ACTION_DEACTIVATE_ZT2_S1, + STEP_ACTION_ACTIVATE_ZT2_PPI, + STEP_ACTION_DEACTIVATE_ZT2_PPI, + STEP_ACTION_ACTIVATE_ZT2_PPE, + STEP_ACTION_DEACTIVATE_ZT2_PPE, + + STEP_ACTION_SCENARIO_END +}; + +class CSimulationStep +{ +public: + unsigned int StepAction; //the action to execute + int StepDelayMillisecs; //the amount of time before the next action +}; + +class CSimulationScenario : public QObject +{ + Q_OBJECT +public: + CSimulationScenario(); + virtual ~CSimulationScenario(); + + unsigned int CreateScenario(); + unsigned int DestroyScenario(); + unsigned int Start(); + unsigned int Pause(); + unsigned int Reset(); + + unsigned int InsertNewStep(unsigned int StepID, int Delay); + +private: + QList mScenarioStepsList; + int mCurStep; + QTimer *mScenarioTimer; + +signals: + void ExecuteNextStep(CSimulationStep*); + void ScenarioCompleted(); + +public slots: + void ScenarioTimerExpired(); +}; + + +#endif // SIMULATIONSCENARIO_H diff --git a/sources/Simulator/SimulatorIOManager.cpp b/sources/Simulator/SimulatorIOManager.cpp new file mode 100644 index 0000000..8eb8bf2 --- /dev/null +++ b/sources/Simulator/SimulatorIOManager.cpp @@ -0,0 +1,87 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable gestionnaire simulé d'entrées/sorties externes. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#include "SimulatorIOManager.h" + +CSimulatorIOManager::CSimulatorIOManager() +{ + +} +CSimulatorIOManager::~CSimulatorIOManager() +{ + delete mInputsModule; + delete mOutputsModule; + delete mMixedModule; +} + +void CSimulatorIOManager::DestroyModule() +{ + delete mInputsModule; + delete mOutputsModule; + delete mMixedModule; +} + +unsigned int CSimulatorIOManager::InitIO() +{ + CEngLog::instance()->AddLogString(QString("CSimulatorIOManager::Init()")); + mInputsModule = new CSimulatorInputModule(); + mOutputsModule = new CSImulatorOutputModule; + mMixedModule = new CSimulatorMixedModule(); + return RET_OK; +} + +CIOModule *CSimulatorIOManager::GetModule(eIOModuleType_t type, unsigned int ModuleID) +{ + Q_UNUSED(ModuleID); + switch(type) + { + case IO_MODULE_INPUT_TYPE: + { + return mInputsModule; + break; + } + case IO_MODULE_OUTPUT_TYPE: + { + return mOutputsModule; + break; + } + case IO_MODULE_MIXED_TYPE: + { + return mMixedModule; + break; + } + default: + case IO_MODULE_INVALID_TYPE: + { + return 0; + break; + } + } + + return 0; +} diff --git a/sources/Simulator/SimulatorIOManager.h b/sources/Simulator/SimulatorIOManager.h new file mode 100644 index 0000000..05e1301 --- /dev/null +++ b/sources/Simulator/SimulatorIOManager.h @@ -0,0 +1,51 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATORIOMANAGER_H +#define SIMULATORIOMANAGER_H +#include "IOManager.h" +#include "SimulatorInputModule.h" +#include "SImulatorOutputModule.h" +#include "SimulatorMixedModule.h" + +class CSimulatorIOManager: public CIOManager +{ +public: + CSimulatorIOManager(); + virtual ~CSimulatorIOManager(); + + virtual unsigned int InitIO(); + virtual CIOModule *GetModule(eIOModuleType_t type, unsigned int ModuleID); + void DestroyModule(); + +private: + CSimulatorInputModule *mInputsModule; + CSImulatorOutputModule *mOutputsModule; + CSimulatorMixedModule *mMixedModule; +}; + +#endif // SIMULATORIOMANAGER_H diff --git a/sources/Simulator/SimulatorInputModule.cpp b/sources/Simulator/SimulatorInputModule.cpp new file mode 100644 index 0000000..8febdf0 --- /dev/null +++ b/sources/Simulator/SimulatorInputModule.cpp @@ -0,0 +1,98 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable d'un module simulé d'entrées externes. Dérivée de CInputModule, elle + permet d'émuler les entrées du module externe en réimplémentant les fonctions + génériques de sa classe de base. Le simulateur peut changer l'état des entrées + par les fonctions Set... + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SimulatorInputModule.h" +#include "Angrignon.h" + +CSimulatorInputModule::CSimulatorInputModule() +{ + mInputBuf = 0; +} + +CSimulatorInputModule::~CSimulatorInputModule() +{ + +} + +//unsigned int CSimulatorInputModule::GetInputs(unsigned char *DataBuf) +//{ + +// memcpy(DataBuf,&mInputBuf,sizeof(mInputBuf)); + +// return RET_OK; +//} + +unsigned int CSimulatorInputModule::GetInputs() +{ + unsigned int temp; + mRdWrLock.lockForRead(); + temp = mInputBuf; + mRdWrLock.unlock(); + return temp; +} + +unsigned int CSimulatorInputModule::GetInputBuf() +{ + unsigned int temp; + mRdWrLock.lockForRead(); + temp = mInputBuf; + mRdWrLock.unlock(); + return temp; +} + +unsigned int CSimulatorInputModule::SetInputBufFlags(unsigned int FlagMask) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mInputBuf |= FlagMask; + temp = mInputBuf; + mRdWrLock.unlock(); + return temp; +} + +unsigned int CSimulatorInputModule::SetInputBufValue(unsigned int value) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mInputBuf = value; + temp = mInputBuf; + mRdWrLock.unlock(); + return temp; +} + +unsigned int CSimulatorInputModule::ClearInputBufFlags(unsigned int FlagMask) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mInputBuf &= ~FlagMask; + temp = mInputBuf; + mRdWrLock.unlock(); + return temp; +} diff --git a/sources/Simulator/SimulatorInputModule.h b/sources/Simulator/SimulatorInputModule.h new file mode 100644 index 0000000..5162fec --- /dev/null +++ b/sources/Simulator/SimulatorInputModule.h @@ -0,0 +1,55 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATORINPUTMODULE_H +#define SIMULATORINPUTMODULE_H +#include "GlobalDefine.h" +#include "InputModule.h" +#include + +class CSimulatorInputModule : public CInputModule +{ +public: + CSimulatorInputModule(); + ~CSimulatorInputModule(); + + unsigned int GetInputs(unsigned char *DataBuf); + virtual unsigned int GetInputs(); + unsigned int GetInputBuf(); + + unsigned int SetInputBufValue(unsigned int value); + unsigned int SetInputBufFlags(unsigned int FlagMask); + unsigned int ClearInputBufFlags(unsigned int FlagMask); + +private: + + unsigned int mInputBuf; + QReadWriteLock mRdWrLock; + +}; + +#endif // SIMULATORINPUTMODULE_H diff --git a/sources/Simulator/SimulatorLazerProbe.cpp b/sources/Simulator/SimulatorLazerProbe.cpp new file mode 100644 index 0000000..f09b236 --- /dev/null +++ b/sources/Simulator/SimulatorLazerProbe.cpp @@ -0,0 +1,132 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable d'une sonde lazer simulée. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SimulatorLazerProbe.h" +#include "AbstractLazerProbeMgr.h" +#include "GlobalDefine.h" + +CSimulatorLazerProbe::CSimulatorLazerProbe(unsigned int ProbeID, unsigned int ProbeType) +{ + mProbeID = ProbeID; + mProbeType = ProbeType; + mData = 100; + mProbeAlive = true; +} + +CSimulatorLazerProbe::~CSimulatorLazerProbe() +{ + +} + +unsigned int CSimulatorLazerProbe::OpenPort(QString PortName) +{ + mPortName = PortName; + return LAZERPROBES_MGR_RET_OK; +} + +unsigned int CSimulatorLazerProbe::GetType() +{ + return mProbeType; +} + +QString CSimulatorLazerProbe::GetPortName() +{ + return mPortName; +} + +unsigned int CSimulatorLazerProbe::GetID() +{ + return mProbeID; +} + +unsigned int CSimulatorLazerProbe::StartAcquisition() +{ + return LAZERPROBES_MGR_RET_OK; +} + +unsigned int CSimulatorLazerProbe::StopAcquisition() +{ + return LAZERPROBES_MGR_RET_OK; +} + +unsigned int CSimulatorLazerProbe::GetLastData() +{ + unsigned int temp; + +// mMutex.lock(); +// temp = mData; +// mMutex.unlock(); + + + mRdWrLock.lockForRead(); + temp = mData; + mRdWrLock.unlock(); + + return temp; +} + +unsigned int CSimulatorLazerProbe::SetData(unsigned int data) +{ + mRdWrLock.lockForWrite(); + mData = data; + mRdWrLock.unlock(); + + emit NewProbeData(data,mProbeType); + + return data; +} + +unsigned int CSimulatorLazerProbe::FlushProbeData() +{ + return RET_OK; +} + +bool CSimulatorLazerProbe::IsProbeAlive() +{ + bool alive; + mRdWrLock.lockForRead(); + alive = mProbeAlive; + mRdWrLock.unlock(); + + return alive; +} + +unsigned int CSimulatorLazerProbe::SetProbeAlive() +{ + mRdWrLock.lockForWrite(); + mProbeAlive = true; + mRdWrLock.unlock(); + return RET_OK; +} + +unsigned int CSimulatorLazerProbe::SetProbeDead() +{ + mRdWrLock.lockForWrite(); + mProbeAlive = false; + mRdWrLock.unlock(); + return RET_OK; +} diff --git a/sources/Simulator/SimulatorLazerProbe.h b/sources/Simulator/SimulatorLazerProbe.h new file mode 100644 index 0000000..1310da5 --- /dev/null +++ b/sources/Simulator/SimulatorLazerProbe.h @@ -0,0 +1,71 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATORLAZERPROBE_H +#define SIMULATORLAZERPROBE_H +#include "AbstractLazerProbe.h" +#include +#include +#include + +class CSimulatorLazerProbe : public QObject, public CAbstractLazerProbe +{ + Q_OBJECT +public: + CSimulatorLazerProbe(unsigned int ProbeID, unsigned int ProbeType); + ~CSimulatorLazerProbe(); + + unsigned int OpenPort(QString PortName); + unsigned int GetType(); + QString GetPortName(); + unsigned int GetID(); + unsigned int StartAcquisition(); + unsigned int StopAcquisition(); + unsigned int GetLastData(); + unsigned int SetData(unsigned int data); + unsigned int FlushProbeData(); + bool IsProbeAlive(); + + unsigned int SetProbeAlive(); + unsigned int SetProbeDead(); + + unsigned int mData; + +private: + QString mPortName; + unsigned int mProbeID; + unsigned int mProbeType; + QMutex mMutex; + QReadWriteLock mRdWrLock; + bool mProbeAlive; + +signals: + void NewProbeData(unsigned int,unsigned int); + +}; + +#endif // SIMULATORLAZERPROBE_H diff --git a/sources/Simulator/SimulatorLazerProbesMgr.cpp b/sources/Simulator/SimulatorLazerProbesMgr.cpp new file mode 100644 index 0000000..e24f10d --- /dev/null +++ b/sources/Simulator/SimulatorLazerProbesMgr.cpp @@ -0,0 +1,75 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable du gestionnaire de sondes lazer simulé. + Crée les objets CSimulatorLazerProbe et les rend disponibles via la fonction + générique GetLazerProbeHandle. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SimulatorLazerProbesMgr.h" + +CSimulatorLazerProbesMgr::CSimulatorLazerProbesMgr() +{ + mInternalLazerProbe = mExternalLazerProbe = 0; +} + +CSimulatorLazerProbesMgr::~CSimulatorLazerProbesMgr() +{ + if(mExternalLazerProbe) + delete mExternalLazerProbe; + + if(mInternalLazerProbe) + delete mInternalLazerProbe; +} + +CAbstractLazerProbe *CSimulatorLazerProbesMgr::GetLazerProbeHandle(eLazerProbeType_t LazerProbeType, unsigned int LazerProbeID) +{ + Q_UNUSED(LazerProbeID) + switch(LazerProbeType) + { + case LAZER_PROBE_TYPE_EXTERNAL: + { + return mExternalLazerProbe; + break; + } + case LAZER_PROBE_TYPE_INTERNAL: + { + return mInternalLazerProbe; + break; + } + case LAZER_PROBE_TYPE_INVALID: + default: + { + return 0; + } + + } +} + +unsigned int CSimulatorLazerProbesMgr::InitLazerProbes() +{ + mExternalLazerProbe = new CSimulatorLazerProbe(1,LAZER_PROBE_TYPE_EXTERNAL); + mInternalLazerProbe = new CSimulatorLazerProbe(1,LAZER_PROBE_TYPE_INTERNAL); + return LAZERPROBES_MGR_RET_OK; +} diff --git a/sources/Simulator/SimulatorLazerProbesMgr.h b/sources/Simulator/SimulatorLazerProbesMgr.h new file mode 100644 index 0000000..d058c58 --- /dev/null +++ b/sources/Simulator/SimulatorLazerProbesMgr.h @@ -0,0 +1,48 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATORLAZERPROBESMGR_H +#define SIMULATORLAZERPROBESMGR_H + +#include "AbstractLazerProbeMgr.h" +#include "SimulatorLazerProbe.h" + +class CSimulatorLazerProbesMgr : public CAbstractLazerProbeMgr +{ +public: + CSimulatorLazerProbesMgr(); + ~CSimulatorLazerProbesMgr(); + + virtual unsigned int InitLazerProbes(void); + virtual CAbstractLazerProbe *GetLazerProbeHandle(eLazerProbeType_t LazerProbeType, unsigned int LazerProbeID); + +private: + CAbstractLazerProbe *mInternalLazerProbe, *mExternalLazerProbe; + +}; + +#endif // SIMULATORLAZERPROBESMGR_H diff --git a/sources/Simulator/SimulatorMixedModule.cpp b/sources/Simulator/SimulatorMixedModule.cpp new file mode 100644 index 0000000..cff677e --- /dev/null +++ b/sources/Simulator/SimulatorMixedModule.cpp @@ -0,0 +1,60 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable d'un module d'entrées/sorties externe mixte simulé. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SimulatorMixedModule.h" + + + +CSimulatorMixedModule::CSimulatorMixedModule() +{ + mRealExtenalMixedModule = 0; +} + +void CSimulatorMixedModule::BindRealExternalMixedModule(CAnalogInputModule *MixedModule) +{ + mRealExtenalMixedModule = MixedModule; +} + +unsigned int CSimulatorMixedModule::GetAnalogInput(int Channel, int *Data) +{ + Q_UNUSED(Channel); + Q_UNUSED(Data); + + if(mRealExtenalMixedModule == 0) + return 0; + + return mRealExtenalMixedModule->GetAnalogInput(Channel,Data); +// return 1; +} + +unsigned int CSimulatorMixedModule::GetAnalogInput(int Channel, double &Data) +{ + int reading; + unsigned int ret = GetAnalogInput(Channel,&reading); + Data = (double)reading; + return ret; +} diff --git a/sources/Simulator/SimulatorMixedModule.h b/sources/Simulator/SimulatorMixedModule.h new file mode 100644 index 0000000..f360205 --- /dev/null +++ b/sources/Simulator/SimulatorMixedModule.h @@ -0,0 +1,47 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATORMIXEDMODULE_H +#define SIMULATORMIXEDMODULE_H +#include "GlobalDefine.h" +#include "AnalogInputModule.h" + +class CSimulatorMixedModule: public CAnalogInputModule +{ +public: + CSimulatorMixedModule(); + + virtual unsigned int GetAnalogInput(int Channel, int *Data); + virtual unsigned int GetAnalogInput(int Channel, double &Data); + + void BindRealExternalMixedModule(CAnalogInputModule *MixedModule); + +private: + CAnalogInputModule *mRealExtenalMixedModule; +}; + +#endif // SIMULATORMIXEDMODULE_H diff --git a/sources/Simulator/SimulatorPCIIO.cpp b/sources/Simulator/SimulatorPCIIO.cpp new file mode 100644 index 0000000..fa3beb6 --- /dev/null +++ b/sources/Simulator/SimulatorPCIIO.cpp @@ -0,0 +1,83 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable d'une carte d'entrées PCI. Dérivée de CPCIIOMgr, elle + permet d'émuler les entrées de la carte PCI en réimplémentant les fonctions + génériques de sa classe de base. Les fonctions SetInputBufFlags et SetInputBufValue + permettent au simulateur d'assigner les valeurs des entrées qui doivent être + lues par le programme. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SimulatorPCIIO.h" + +CSimulatorPCIIO::CSimulatorPCIIO() +{ + mSimPCIInputsBuffer = 0; +} + +unsigned int CSimulatorPCIIO::GetInputs() +{ + unsigned int temp; + + mRdWrLock.lockForRead(); //lock for thread access + temp = mSimPCIInputsBuffer; + mRdWrLock.unlock(); + + return temp; +} + +unsigned int CSimulatorPCIIO::OpenPCIInterface() +{ + return PCIIO_OK; +} + +unsigned int CSimulatorPCIIO::SetInputBufFlags(unsigned int FlagMask) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mSimPCIInputsBuffer |= FlagMask; + temp = mSimPCIInputsBuffer; + mRdWrLock.unlock(); + return temp; +} + +unsigned int CSimulatorPCIIO::SetInputBufValue(unsigned int value) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mSimPCIInputsBuffer = value; + temp = mSimPCIInputsBuffer; + mRdWrLock.unlock(); + return temp; +} + +unsigned int CSimulatorPCIIO::ClearInputBufFlags(unsigned int FlagMask) +{ + unsigned int temp; + mRdWrLock.lockForWrite(); + mSimPCIInputsBuffer ^= FlagMask; + temp = mSimPCIInputsBuffer; + mRdWrLock.unlock(); + return temp; +} diff --git a/sources/Simulator/SimulatorPCIIO.h b/sources/Simulator/SimulatorPCIIO.h new file mode 100644 index 0000000..4e96bc7 --- /dev/null +++ b/sources/Simulator/SimulatorPCIIO.h @@ -0,0 +1,51 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATORPCIIO_H +#define SIMULATORPCIIO_H +#include "PCIIOMgr.h" +#include + +class CSimulatorPCIIO : public CPCIIOMgr +{ +public: + CSimulatorPCIIO(); + + virtual unsigned int OpenPCIInterface(void); + virtual unsigned int GetInputs(void); + + unsigned int SetInputBufValue(unsigned int value); + unsigned int SetInputBufFlags(unsigned int FlagMask); + unsigned int ClearInputBufFlags(unsigned int FlagMask); + +private: + unsigned int mSimPCIInputsBuffer; + QReadWriteLock mRdWrLock; + +}; + +#endif // SIMULATORPCIIO_H diff --git a/sources/Simulator/SimulatorThread.cpp b/sources/Simulator/SimulatorThread.cpp new file mode 100644 index 0000000..f45c7db --- /dev/null +++ b/sources/Simulator/SimulatorThread.cpp @@ -0,0 +1,279 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est un thread qui roule en parallèle au programme. Elle est + responsable de l'analyse en temps réel du passage d'un train. Elle fait la + lecture des entrées sur la carte PCI et analyse les déclenchements au fur + et à mesure qu'un train chemine sur la ZT2 + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#include "SimulatorThread.h" +#include "PCIIOMgr.h" +#include "AbstractLazerProbe.h" +#include +#include "ZTconfigmgr.h" + +//const char * ErrorString[25] = {"Erreur de comptage S1-S2", +// "Déclenchement frotteur négatif", +// "Déclenchement pneu de guidage intérieur", +// "Déclenchement pneu de guidage extérieur", +// "Déclenchement pneu porteur intérieur", +// "Déclenchement pneu porteur extérieur", +// "Pré-détection frotteur négatif"}; + +CSimulatorThread::CSimulatorThread() +{ + mExitLoop = false; + mSimThreadRunning = false; + mLogElement = 0; +} + +unsigned int CSimulatorThread::Init(CSimulatorInputModule *InputModule, CSImulatorOutputModule *OutputModule, CSimulatorPCIIO *PCIIO, CSimulatorLazerProbe *InternalLazerProbe,CSimulatorLazerProbe *ExternalLazerProbe,GenericInputMasks_t *StationInputMasks) +{ + mInputModule = InputModule; + mOutputModule = OutputModule; + mPCIIO = PCIIO; + mInternalLazerProbe = InternalLazerProbe; + mExternalLazerProbe = ExternalLazerProbe; + mStationInputMasks = StationInputMasks; + + + return RET_OK; +} + +void CSimulatorThread::SetLogElement(CLogElement *element) +{ + mLogElement = element; +} + +void CSimulatorThread::StartSim() +{ + + if(mLogElement == 0) + return; + + qDebug("Sim Thread started!"); + mExitLoop = false; + mSimThreadRunning = true; + + bool Run = true; + CZT1LogElement *ZT1LogData = 0; + CZT2LogElement *ZT2LogData = 0; + + if(mLogElement->mZTLogType == ZT1_LOG_TYPE) + ZT1LogData = (CZT1LogElement*) mLogElement; + else + ZT2LogData = (CZT2LogElement*) mLogElement; + + QElapsedTimer AcquisitionTimer; + AcquisitionTimer.start(); + + qint64 index = 0; + qint64 NextEventTime; + + //Init the lazer probes values. + + + if(ZT1LogData != 0) + { + bool ExtSet = false, IntSet = false; + for(int i = 0; i < ZT1LogData->mZTLogData.size(); i++) + { + if(ZT1LogData->mZTLogData.at(i)->mZT1ThreadData != 0) + { + if(ExtSet == false) + { + if(ZT1LogData->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue != 0) + { + mExternalLazerProbe->SetData(ZT1LogData->mZTLogData.at(i)->mZT1ThreadData->mPGExtValue); + ExtSet = true; + } + } + if(IntSet == false) + { + if(ZT1LogData->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue != 0) + { + mInternalLazerProbe->SetData(ZT1LogData->mZTLogData.at(i)->mZT1ThreadData->mPGIntValue); + IntSet = true; + } + } + + if(IntSet == true && ExtSet == true) + break; + } + } + +// mInternalLazerProbe->SetData(ZT1LogData->mFlags.mIntPGOffset); +// mExternalLazerProbe->SetData(ZT1LogData->mFlags.mExtPGOffset); + NextEventTime = ZT1LogData->mZTLogData.at(index)->mTimestamp; + } + else + { +// if(ZT2LogData->mZTLogData.at(index)->mZT2ThreadData != 0) +// NextEventTime = ZT2LogData->mZTLogData.at(index)->mZT2ThreadData->mTimeStamp; +// else + NextEventTime = ZT2LogData->mZTLogData.at(index)->mTimestamp; + } + + unsigned int PCIStartBuf = mPCIIO->GetInputs(); +// mPCIIO->SetInputBufValue(0); + unsigned int ModuleStartBuf = mInputModule->GetInputBuf(); +// mInputModule->SetInputBufValue(mInputModule); + + NextEventTime = 0; + mSimTimer.start(); + + while(Run == true) + { + + + if(mSimTimer.nsecsElapsed() >= NextEventTime) + { + // qDebug("%lld - %lld",mSimTimer.nsecsElapsed(),NextEventTime); + if(ZT1LogData != 0) + { + CZT1ThreadData *Data = ZT1LogData->mZTLogData.at(index)->mZT1ThreadData; + if(Data != 0) + { + unsigned int PCIData = PCIStartBuf; + + if(Data->mFN == 1) + PCIData ^= mStationInputMasks->InputZT1FNMask; + if(Data->mPExt == 1) + PCIData ^= mStationInputMasks->InputZT1PIMask; + if(Data->mPInt == 1) + PCIData ^= mStationInputMasks->InputZT1PIMask; + if(Data->mS1 == 1) + PCIData |= mStationInputMasks->InputZT1S1Mask; + if(Data->mS2 == 1) + PCIData |= mStationInputMasks->InputZT1S2Mask; + + mPCIIO->SetInputBufValue(PCIData); + + mExternalLazerProbe->SetData(Data->mPGExtValue); + mInternalLazerProbe->SetData(Data->mPGIntValue); + } + + unsigned int InputModuleData = ModuleStartBuf; + + CZT1LogData *LogData = ZT1LogData->mZTLogData.at(index); + if(LogData->mCIZT1 == 1) + { + InputModuleData |= mStationInputMasks->InputZT1ITIMask; + } + if(LogData->mCDVARM_ZT1 == 1) + { + InputModuleData &= ~(mStationInputMasks->InputCDVZT1Mask); + } + if(LogData->mCDVApproach_ZT1 == 1) + { + InputModuleData &= ~(mStationInputMasks->InputCDVZT1ApproachMask); + } + + mInputModule->SetInputBufValue(InputModuleData); + + index++; + if(index >= ZT1LogData->mZTLogData.size()) + { + Run = false; + } + else + { +// NextEventTime = ZT1LogData->mZTLogData.at(index)->mTimestamp; + NextEventTime = ZT1LogData->mZTLogData.at(index)->mTimestamp - ZT1LogData->mZTLogData.at(index-1)->mTimestamp; + //qDebug("Next %lld",NextEventTime); + mSimTimer.start(); + } + } + else + { + CZT2ThreadData *Data = ZT2LogData->mZTLogData.at(index)->mZT2ThreadData; + if(Data != 0) + { + unsigned int PCIData = PCIStartBuf; + + if(Data->mPPInt == 1) + PCIData ^= mStationInputMasks->InputZT2PIMask; + if(Data->mPPExt == 1) + PCIData ^= mStationInputMasks->InputZT2PEMask; + if(Data->mS1 == 1) + PCIData |= mStationInputMasks->InputZT2S1Mask; + + mPCIIO->SetInputBufValue(PCIData); + } + + + unsigned int InputModuleData = ModuleStartBuf; + CZT2LogData *LogData = ZT2LogData->mZTLogData.at(index); + if(LogData->mCIZT2 == 1) + { + InputModuleData |= mStationInputMasks->InputZT2ITIMask; + } + if(LogData->mCDVARM_ZT2 == 1) + { + InputModuleData ^= mStationInputMasks->InputCDVZT2Mask; + } + if(LogData->mCDVApproach_ZT2 == 1) + { + InputModuleData ^= mStationInputMasks->InputCDVZT2ApproachMask; + } + + mInputModule->SetInputBufValue(InputModuleData); + + index++; + if(index >= ZT2LogData->mZTLogData.size()) + { + Run = false; + } + else + { +// if(ZT2LogData->mZTLogData.at(index)->mZT2ThreadData != 0) +// NextEventTime = ZT2LogData->mZTLogData.at(index)->mZT2ThreadData->mTimeStamp; +// else + NextEventTime = ZT2LogData->mZTLogData.at(index)->mTimestamp; + } + + + } + } + + mMutex.lock(); + if(mExitLoop == true) + Run = false; + mMutex.unlock(); + }//while + + mSimThreadRunning = false; + emit SimFinished(); + +} + +void CSimulatorThread::Terminate() +{ + mMutex.lock(); + mExitLoop = true; + mMutex.unlock(); +} + diff --git a/sources/Simulator/SimulatorThread.h b/sources/Simulator/SimulatorThread.h new file mode 100644 index 0000000..ad49008 --- /dev/null +++ b/sources/Simulator/SimulatorThread.h @@ -0,0 +1,87 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est un thread qui lit la carte PCI d'I/O sur laquelle sont + branchées les entrées à haute fréquence. La machine à états analyse le + passage du train et détecte les déclenchements (sondes, frotteur négatif, + pneu porteur). On utilise un thread car l'analyse doit se faire à très + haute fréquence sans être ralentie par l'interface graphique. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SIMULATORTHREAD_H +#define SIMULATORTHREAD_H + +#define ZT2_ANALYSIS_LOOP_PERIOD 500000 //500 us + +#include +#include "GlobalDefine.h" +#include "Station.h" +#include +#include "ZTData.h" +#include "QElapsedTimer" +#include "SimulatorInputModule.h" +#include "SImulatorOutputModule.h" +#include "SimulatorPCIIO.h" +#include "SimulatorLazerProbe.h" +#include "LogMgr.h" + +class CPCIIOMgr; +//class CAbstractLazerProbe; + +class CSimulatorThread : public QObject +{ + Q_OBJECT +public: + CSimulatorThread(); + unsigned int Init(CSimulatorInputModule *InputModule, CSImulatorOutputModule *OutputModule, CSimulatorPCIIO *PCIIO, CSimulatorLazerProbe *InternalLazerProbe,CSimulatorLazerProbe *ExternalLazerProbe,GenericInputMasks_t *StationInputMasks); + void Terminate(); + void SetLogElement(CLogElement *element); + +private: + + CSimulatorInputModule *mInputModule; + CSImulatorOutputModule *mOutputModule; + CSimulatorPCIIO *mPCIIO; + CSimulatorLazerProbe *mInternalLazerProbe, *mExternalLazerProbe; + + CLogElement *mLogElement; + GenericInputMasks_t *mStationInputMasks; + + QElapsedTimer mSimTimer; + + bool mExitLoop; + QMutex mMutex; + bool mSimThreadRunning; + + + +public slots: + void StartSim(); + +signals: + void SimFinished(); + +}; + +#endif // SIMULATORTHREAD_H diff --git a/sources/Simulator/ZTSimulator.cpp b/sources/Simulator/ZTSimulator.cpp new file mode 100644 index 0000000..8c5e5ee --- /dev/null +++ b/sources/Simulator/ZTSimulator.cpp @@ -0,0 +1,1301 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe consiste en un simulateur qui permet d'émuler les entrées/sorties + Il offre aussi un générateur de scénarios pour simuler le passage d'un train et + la génération de déclenchements. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZTSimulator.h" +#include +#include "SimpleTextBoxWidget.h" +#include +#include "ZTPage.h" +#include +#include "ZTconfigmgr.h" +#include +#include "TrainLogFileMgr.h" +#include "ZTData.h" +#include +#include +#include + + +CZTSimulator::CZTSimulator(CSimulatorIOManager *IOMgrPtr) +{ + static QGraphicsTextItem *Label; + Label = new QGraphicsTextItem("Simulateur",this); + mIOMgrPtr = IOMgrPtr; + mStationPtr = 0; + mUSBDriveInterfacePtr = 0; + + + mSimThread = new QThread; + mSimWorkerThread = new CSimulatorThread(); + mSimWorkerThread->moveToThread(mSimThread); + connect(mSimThread,SIGNAL(started()),mSimWorkerThread,SLOT(StartSim())); + connect(mSimWorkerThread,SIGNAL(SimFinished()),this,SLOT(FileSimFinished())); + mSimLogElement = 0; + + mFileSimLoopDelayTimer.setSingleShot(true); + connect(&mFileSimLoopDelayTimer,SIGNAL(timeout()),this,SLOT(FileLoopDelayExpired())); +} + +CZTSimulator::~CZTSimulator() +{ + delete mLazerProbesUpdateTimer; + delete mSimulationElapsedTimer; + mSimThread->quit(); + mSimThread->wait(1000); + delete mSimThread; + delete mSimWorkerThread; + DestroyLogElement(); +} + +void CZTSimulator::Show() +{ + QGraphicsRectItem *BoundingRect = new QGraphicsRectItem(rect(),this); + Q_UNUSED(BoundingRect) +} + +void CZTSimulator::SetPGTreshold(qint32 Treshold) +{ + mPGTreshold = Treshold; +} + +unsigned int CZTSimulator::Init(CZTPage *MainPagePtr, CStation *Station, CIOManager *IOMgrPtr,CPCIIOMgr *PCIIO,CAbstractLazerProbeMgr *LazerProbesMgr,CUSBDriveInterface *UsbDriveInterface, CAnalogInputModule *RealAnalogModule) +{ + mMainPagePtr = MainPagePtr; + mStationPtr = Station; + mPCIIO = (CSimulatorPCIIO*)PCIIO; + mLazerProbesMgr = (CSimulatorLazerProbesMgr*)LazerProbesMgr; + mIOMgrPtr = (CSimulatorIOManager*)IOMgrPtr; + + mInternalLazerProbe = (CSimulatorLazerProbe*)mLazerProbesMgr->GetLazerProbeHandle(LAZER_PROBE_TYPE_INTERNAL,1); + mExternalLazerProbe = (CSimulatorLazerProbe*)mLazerProbesMgr->GetLazerProbeHandle(LAZER_PROBE_TYPE_EXTERNAL,1); + mLazerProbesUpdateTimer = new QTimer(); + mLazerProbesUpdateTimer->setSingleShot(false); +// mPGEValue = mPGIValue = CZTConfigMgr::instance()->GetLaserSensorCalib() - 50; //Init low + + mStationInputMasks = mStationPtr->GetInputMasks(); //the station inputs are kind of simulator outputs... + mStationOutputMasks = mStationPtr->GetOutputMasks(); + + mInputModule = (CSimulatorInputModule*) mIOMgrPtr->GetModule(IO_MODULE_INPUT_TYPE,1); + mOutputModule = (CSImulatorOutputModule*) mIOMgrPtr->GetModule(IO_MODULE_OUTPUT_TYPE,1); + mOutputModule->BindSimPtr(this); + connect(mOutputModule,SIGNAL(UpdateOutputsDisplay(quint32)),this,SLOT(UpdateOutputsDisplay(quint32))); + mMixedModule = (CSimulatorMixedModule*) mIOMgrPtr->GetModule(IO_MODULE_MIXED_TYPE,1); + + if(RealAnalogModule != 0) //If external module is not detected, try the DataQ module + { + mMixedModule->BindRealExternalMixedModule(RealAnalogModule); + } + else + { + mMixedModule->BindRealExternalMixedModule(0); + } + + + mSimWorkerThread->Init(mInputModule,mOutputModule,mPCIIO,mInternalLazerProbe,mExternalLazerProbe,mStationInputMasks); + + mUSBDriveInterfacePtr = UsbDriveInterface; + + //Create Simulator GUI: + + + //Create CDV graphical items list, + //adjust all their position on screen and + //set parameters + for(int i = 0; i < mStationPtr->GetCDVList()->size(); i++) + { + int x = 0, y = 20; + CCDVItem *NewCDVGraphicalItem; + if(mStationPtr->GetCDVList()->at(i)->GetCDVType() == CDV_NORMAL_TYPE) + { + NewCDVGraphicalItem = new CCDVItem(mStationPtr->GetCDVList()->at(i),this); + } + else + { + //NewCDVGraphicalItem = new CSwitchCDVItem(mStationPtr->GetCDVList()->at(i),this); + NewCDVGraphicalItem = new CCDVItem(mStationPtr->GetCDVList()->at(i),this); + } + NewCDVGraphicalItem->SetParameters(mStationPtr->GetCDVList()->at(i)->GetLabel()); + mSimCDVItemsList.append(NewCDVGraphicalItem); + NewCDVGraphicalItem->resize(70,20); + x = (mStationPtr->GetCDVList()->at(i)->GetCDVGraphicalPos() * NewCDVGraphicalItem->geometry().width())+5; + if(mStationPtr->GetCDVList()->at(i)->GetCDVWay() == 2) + y = 50; + NewCDVGraphicalItem->setPos(x,y); + connect(NewCDVGraphicalItem,SIGNAL(CDVRightClicked(CCDVItem*)),this,SLOT(CDVItemRightClicked(CCDVItem*))); + //start with all CDVs free + mInputModule->SetInputBufFlags(mStationPtr->GetCDVList()->at(i)->GetInputMask()); + + } + + //Buttons + mITIZT1ToggleBtn = new CToggleTextButtonWidget(QString("Détruire\nITI ZT1"),QString("Commander\nITI ZT1"),QPixmap(),QPixmap(),50,100,15,0); + mITIZT1ToggleBtn->setParentItem(this); + mITIZT1ToggleBtn->setPos(5,110); + connect(mITIZT1ToggleBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ItineraryToggleSwitchActivate(CToggleTextButtonWidget*))); + connect(mITIZT1ToggleBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ItineraryToggleSwitchDeActivate(CToggleTextButtonWidget*))); + + if(mStationInputMasks->InputZT1_AltITIMask != 0) + { + mITIZT1AltToggleBtn = new CToggleTextButtonWidget(QString("Détruire\nITI ZT1(10/22)"),QString("Commander\nITI ZT1(10/22)"),QPixmap(),QPixmap(),50,100,13,0); + mITIZT1AltToggleBtn->setParentItem(this); + mITIZT1AltToggleBtn->setPos(115,110); + connect(mITIZT1AltToggleBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ItineraryToggleSwitchActivate(CToggleTextButtonWidget*))); + connect(mITIZT1AltToggleBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ItineraryToggleSwitchDeActivate(CToggleTextButtonWidget*))); + } + + mITIZT2ToggleBtn = new CToggleTextButtonWidget(QString("Détruire\nITI ZT2"),QString("Commander\nITI ZT2"),QPixmap(),QPixmap(),50,100,15,0); + mITIZT2ToggleBtn->setParentItem(this); + mITIZT2ToggleBtn->setPos(5,170); + connect(mITIZT2ToggleBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ItineraryToggleSwitchActivate(CToggleTextButtonWidget*))); + connect(mITIZT2ToggleBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ItineraryToggleSwitchDeActivate(CToggleTextButtonWidget*))); + + mS1SimBtn = new CToggleTextButtonWidget(QString("S1"),QString("S1"),QPixmap(),QPixmap()); + mS1SimBtn->setParentItem(this); + mS1SimBtn->setPos(300,110); + connect(mS1SimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mS1SimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mS2SimBtn = new CToggleTextButtonWidget(QString("S2"),QString("S2"),QPixmap(),QPixmap()); + mS2SimBtn->setParentItem(this); + mS2SimBtn->setPos(250,110); + connect(mS2SimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mS2SimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mFNSimBtn = new CToggleTextButtonWidget(QString("FN"),QString("FN"),QPixmap(),QPixmap()); + mFNSimBtn->setParentItem(this); + mFNSimBtn->setPos(350,110); + connect(mFNSimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mFNSimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mPPESimBtn = new CToggleTextButtonWidget(QString("PPE"),QString("PPE"),QPixmap(),QPixmap()); + mPPESimBtn->setParentItem(this); + mPPESimBtn->setPos(400,110); + connect(mPPESimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mPPESimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mPPISimBtn = new CToggleTextButtonWidget(QString("PPI"),QString("PPI"),QPixmap(),QPixmap()); + mPPISimBtn->setParentItem(this); + mPPISimBtn->setPos(450,110); + connect(mPPISimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mPPISimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mZT2S1SimBtn = new CToggleTextButtonWidget(QString("S1 ZT2"),QString("S1 ZT2"),QPixmap(),QPixmap()); + mZT2S1SimBtn->setParentItem(this); + mZT2S1SimBtn->setPos(250,150); + connect(mZT2S1SimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mZT2S1SimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mZT2PPESimBtn = new CToggleTextButtonWidget(QString("PPE ZT2"),QString("PPE ZT2"),QPixmap(),QPixmap()); + mZT2PPESimBtn->setParentItem(this); + mZT2PPESimBtn->setPos(325,150); + connect(mZT2PPESimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mZT2PPESimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mZT2PPISimBtn = new CToggleTextButtonWidget(QString("PPI ZT2"),QString("PPI ZT2"),QPixmap(),QPixmap()); + mZT2PPISimBtn->setParentItem(this); + mZT2PPISimBtn->setPos(410,150); + connect(mZT2PPISimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mZT2PPISimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mAN1SimBtn = new CToggleTextButtonWidget(QString("AN1"),QString("AN1"),QPixmap(),QPixmap()); + mAN1SimBtn->setParentItem(this); + mAN1SimBtn->setPos(250,190); + connect(mAN1SimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mAN1SimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT1SensorBtnDeActivate(CToggleTextButtonWidget*))); + + mAN2SimBtn = new CToggleTextButtonWidget(QString("AN2"),QString("AN2"),QPixmap(),QPixmap()); + mAN2SimBtn->setParentItem(this); + mAN2SimBtn->setPos(300,190); + connect(mAN2SimBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnActivate(CToggleTextButtonWidget*))); + connect(mAN2SimBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(ZT2SensorBtnDeActivate(CToggleTextButtonWidget*))); + + + mSimulationStartBtn = new CPushButton(this,"./Images/Play Normal.png"); + mSimulationStartBtn->setPos(320,225); + mSimulationStartBtn->resize(50,50); + connect(mSimulationStartBtn,SIGNAL(clicked(CPushButton*)),this,SLOT(SimulationScenarioButtonPressed(CPushButton*))); + + mSimFileOpenBtn = new CPushButton(this,"./Images/open-file-icon.png"); + mSimFileOpenBtn->setPos(250,225); + mSimFileOpenBtn->resize(50,50); + connect(mSimFileOpenBtn,SIGNAL(clicked(CPushButton*)),this,SLOT(SimulationScenarioButtonPressed(CPushButton*))); + + QGraphicsProxyWidget *Proxy = new QGraphicsProxyWidget(this); + mLoopSimCheckbox = new QCheckBox("Loop Simulation"); + Proxy->setWidget(mLoopSimCheckbox); + Proxy->setPos(5,325); + mLoopSimCheckbox->show(); + + Proxy = new QGraphicsProxyWidget(this); + mProbesAliveCheckBox = new QCheckBox("Lazer defect."); + Proxy->setWidget(mProbesAliveCheckBox); + Proxy->setPos(5,225); + connect(mProbesAliveCheckBox,SIGNAL(stateChanged(int)),this,SLOT(SimulDefectLazerCheckboxChanged(int))); + + mScenario = new CSimulationScenario; + connect(mScenario,SIGNAL(ExecuteNextStep(CSimulationStep*)),this,SLOT(SimulationScenarioExecStep(CSimulationStep*))); + connect(mScenario,SIGNAL(ScenarioCompleted()),this,SLOT(SimulationScenarioFinished())); + mScenario->CreateScenario(); + + connect(mLazerProbesUpdateTimer,SIGNAL(timeout()),this,SLOT(LazerProbesSimTimerExpired())); + mSimulationElapsedTimer = new QElapsedTimer(); + + Proxy = new QGraphicsProxyWidget(this); + mUSBKeyEmuEnableCheckBox = new QCheckBox("Emulation\nClef USB"); + Proxy->setWidget(mUSBKeyEmuEnableCheckBox); + Proxy->setPos(5,250); + connect(mUSBKeyEmuEnableCheckBox,SIGNAL(stateChanged(int)),this,SLOT(USBEmulationCheckboxChanged(int))); + + mUSBKeyPresenceToggleBtn = new CToggleTextButtonWidget(QString("Branchée"),QString("Débranchée"),QPixmap(),QPixmap(),25,100); + mUSBKeyPresenceToggleBtn->setParentItem(this); + mUSBKeyPresenceToggleBtn->setPos(8,300); + mUSBKeyPresenceToggleBtn->hide(); + connect(mUSBKeyPresenceToggleBtn,SIGNAL(ToggleBtnActivate(CToggleTextButtonWidget*)),this,SLOT(USBEmulationPresenceToggled(CToggleTextButtonWidget*))); + connect(mUSBKeyPresenceToggleBtn,SIGNAL(ToggleBtnDeActivate(CToggleTextButtonWidget*)),this,SLOT(USBEmulationPresenceToggled(CToggleTextButtonWidget*))); + + + int row = 300, col = 250; + QString label; + + for(int Led = 0; Led < GENERIC_OUTPUT_NB_ID; Led++) + { + switch(Led) + { + case GENERIC_OUTPUT_VP1_ID: + { + label = "VP1"; + break; + } + case GENERIC_OUTPUT_VP2_ID: + { + label = "VP2"; + break; + } + case GENERIC_OUTPUT_VP3_ID: + { + label = "VP3"; + break; + } + case GENERIC_OUTPUT_VP4_ID: + { + label = "VP4"; + break; + } + case GENERIC_OUTPUT_VP5_ID: + { + label = "VP5"; + break; + } + case GENERIC_OUTPUT_VP6_ID: + { + label = "VP6"; + break; + } + case GENERIC_OUTPUT_DPE_ID: + { + label = "PPE"; + break; + } + case GENERIC_OUTPUT_DPI_ID: + { + label = "PPI"; + break; + } + case GENERIC_OUTPUT_V00_ID: + { + label = "V00"; + break; + } + case GENERIC_OUTPUT_VF1_ID: + { + label = "VF1"; + row += 50; + col = 250; + break; + } + case GENERIC_OUTPUT_VF2_ID: + { + label = "VF2"; + break; + } + case GENERIC_OUTPUT_VF3_ID: + { + label = "VF3"; + break; + } + case GENERIC_OUTPUT_VF4_ID: + { + label = "VF4"; + break; + } + case GENERIC_OUTPUT_VF5_ID: + { + label = "VF5"; + break; + } + case GENERIC_OUTPUT_DPG_ID: + { + label = "DPG"; + break; + } + case GENERIC_OUTPUT_DFR_ID: + { + label = "DFR"; + break; + } + case GENERIC_OUTPUT_RF_ID: + { + label = "RF"; + break; + } + case GENERIC_OUTPUT_VEL_ID: + { + label = "VEL"; + break; + } + case GENERIC_OUTPUT_VEL2_ID: + { + label = "VEL2"; + break; + } + case GENERIC_OUTPUT_WP1_ID: + { + label = "WP1"; + row += 50; + col = 250; + break; + } + case GENERIC_OUTPUT_WP2_ID: + { + label = "WP2"; + break; + } + case GENERIC_OUTPUT_WP3_ID: + { + label = "WP3"; + break; + } + case GENERIC_OUTPUT_WP4_ID: + { + label = "WP4"; + break; + } + case GENERIC_OUTPUT_WP5_ID: + { + label = "WP5"; + break; + } + case GENERIC_OUTPUT_WP6_ID: + { + label = "WP6"; + break; + } + case GENERIC_OUTPUT_DPI2_ID: + { + label = "PPI2"; + break; + } + case GENERIC_OUTPUT_DPE2_ID: + { + label = "PPE2"; + break; + } + case GENERIC_OUTPUT_V002_ID: + { + label = "V002"; + break; + } + case GENERIC_OUTPUT_RF2_ID: + { + label = "RF2"; + break; + } + case GENERIC_OUTPUT_PEQ1_ID: + { + label = "PEQ1"; + row = 300; + col = 150; + break; + } + case GENERIC_OUTPUT_PEQ2_ID: + { + row = 350; + col = 150; + label = "PEQ2"; + break; + } + case GENERIC_OUTPUT_WATCHDOG_ID: + { + row = 400; + col = 150; + label = "VIGIE"; + break; + } + } + + LedWidget[Led] = new CLedWidget(label,this); + LedWidget[Led]->setPos(col,row); + + col += 35; + } + + mPPISimBtn->ForceActivation(true); + mPPESimBtn->ForceActivation(true); + mZT2PPESimBtn->ForceActivation(true); + mZT2PPISimBtn->ForceActivation(true); + mFNSimBtn->ForceActivation(true); + + UpdateSimulatorDisplay(); + + return RET_OK; +} + +void CZTSimulator::UpdateSimulatorDisplay() +{ + for(int i = 0; i < mSimCDVItemsList.size(); i++) + mSimCDVItemsList.at(i)->UpdateState(); +} + +void CZTSimulator::CDVItemRightClicked(CCDVItem *ClickedItem) +{ + CCDV *CDVPtr = ClickedItem->GetCDV(); + + switch(CDVPtr->GetCDVState()) + { + case CDV_STATE_FREE: + case CDV_STATE_ITI_CMD: + { + mInputModule->ClearInputBufFlags(CDVPtr->GetInputMask()); + break; + } + case CDV_STATE_OCCUPIED: + { + mInputModule->SetInputBufFlags(CDVPtr->GetInputMask()); + break; + } + } +} + +void CZTSimulator::ItineraryToggleSwitchActivate(CToggleTextButtonWidget *Button) +{ + if(Button == mITIZT1ToggleBtn) + { + mInputModule->SetInputBufFlags(mStationInputMasks->InputZT1_StdITIMask); + } + else if(Button == mITIZT1AltToggleBtn) + { + mInputModule->SetInputBufFlags(mStationInputMasks->InputZT1_AltITIMask); + } + else if(Button == mITIZT2ToggleBtn) + { + mInputModule->SetInputBufFlags(mStationInputMasks->InputZT2ITIMask); + } + else + return; + +} + +void CZTSimulator::ItineraryToggleSwitchDeActivate(CToggleTextButtonWidget *Button) +{ + if(Button == mITIZT1ToggleBtn) + { + mInputModule->ClearInputBufFlags(mStationInputMasks->InputZT1_StdITIMask); + } + else if(Button == mITIZT1AltToggleBtn) + { + mInputModule->ClearInputBufFlags(mStationInputMasks->InputZT1_AltITIMask); + } + else if(Button == mITIZT2ToggleBtn) + { + mInputModule->ClearInputBufFlags(mStationInputMasks->InputZT2ITIMask); + } + else + return; + +} + +void CZTSimulator::ZT1SensorBtnActivate(CToggleTextButtonWidget *SensorBtn) +{ + if(SensorBtn == mS1SimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1S1Mask); + } + if(SensorBtn == mS2SimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1S2Mask); + } + if(SensorBtn == mFNSimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1FNMask); + } + if(SensorBtn == mPPESimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1PEMask); + } + if(SensorBtn == mPPISimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1PIMask); + } + if(SensorBtn == mAN1SimBtn) + { + mInputModule->SetInputBufFlags(mStationInputMasks->InputZT1ANMask); + } +} + +void CZTSimulator::ZT1SensorBtnDeActivate(CToggleTextButtonWidget *SensorBtn) +{ + if(SensorBtn == mS1SimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1S1Mask); + } + if(SensorBtn == mS2SimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1S2Mask); + } + if(SensorBtn == mFNSimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1FNMask); + } + if(SensorBtn == mPPESimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1PEMask); + } + if(SensorBtn == mPPISimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1PIMask); + } + if(SensorBtn == mAN1SimBtn) + { + mInputModule->ClearInputBufFlags(mStationInputMasks->InputZT1ANMask); + } +} + +void CZTSimulator::ZT2SensorBtnActivate(CToggleTextButtonWidget *Btn) +{ + if(Btn == mZT2S1SimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT2S1Mask); + } + if(Btn == mZT2PPISimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT2PIMask); + } + if(Btn == mZT2PPESimBtn) + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT2PEMask); + } + if(Btn == mAN2SimBtn) + { + mInputModule->SetInputBufFlags(mStationInputMasks->InputZT2ANMask); + } +} +void CZTSimulator::ZT2SensorBtnDeActivate(CToggleTextButtonWidget *Btn) +{ + if(Btn == mZT2S1SimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT2S1Mask); + } + if(Btn == mZT2PPISimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT2PIMask); + } + if(Btn == mZT2PPESimBtn) + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT2PEMask); + } + if(Btn == mAN2SimBtn) + { + mInputModule->ClearInputBufFlags(mStationInputMasks->InputZT2ANMask); + } +} + +void CZTSimulator::SimulationScenarioButtonPressed(CPushButton *Btn) +{ + Q_UNUSED(Btn) + + if(Btn == mSimulationStartBtn) + { + if(mSimLogElement != 0) + { + mSimWorkerThread->SetLogElement(mSimLogElement); + mSimThread->start(QThread::NormalPriority); + } + else + { + StartSim(); + } + + } + else if(Btn == mSimFileOpenBtn) + { + QString SimFilePath = QFileDialog::getOpenFileName(0, tr("Fichier de passage"), "./Trains", tr("Passages (*.bin)")); + + if(SimFilePath.isEmpty() == false) + { + unsigned int ret; + DestroyLogElement(); + + mSimLogElement = CTrainLogFileMgr::instance()->OpenTrainLog(SimFilePath,ret,0,true); + } + + } + +// mSimulationElapsedTimer->restart(); +// mLazerProbesUpdateTimer->start(SIM_LAZER_PROBES_UPDATE_TIMEOUT); +// mScenario->Start(); +} + +void CZTSimulator::DestroyLogElement() +{ + if(mSimLogElement == 0) + return; + + if(mSimLogElement->mZTLogType == ZT1_LOG_TYPE) + { + CZT1LogElement *temp = (CZT1LogElement*)mSimLogElement; + delete temp; +// for(int i = 0; i < temp->mZTLogData.size(); i++) +// delete temp->mZTLogData.at(i); +// temp->mZTLogData.clear(); + } + if(mSimLogElement->mZTLogType == ZT2_LOG_TYPE) + { + CZT2LogElement *temp = (CZT2LogElement*)mSimLogElement; + delete temp; +/* for(int i = 0; i < temp->mZTLogData.size(); i++) + delete temp->mZTLogData.at(i); + temp->mZTLogData.clear()*/; + } + + delete mSimLogElement; + mSimLogElement = 0; +} + +void CZTSimulator::StartSim() +{ + mInternalLazerProbe->SetData(mPGIValue); + mExternalLazerProbe->SetData(mPGEValue); + mSimulationElapsedTimer->restart(); + //mLazerProbesUpdateTimer->start(SIM_LAZER_PROBES_UPDATE_TIMEOUT); + mScenario->Start(); +} + +void CZTSimulator::SimulationScenarioExecStep(CSimulationStep *Step) +{ + +// static quint32 temp = 1; +// mOutputModule->ClearOutputFlags(temp); +// temp <<= 1; + switch(Step->StepAction) + { + case STEP_ACTION_DELAY: + { + break; + } + case STEP_ACTION_ACTIVATE_S1: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1S1Mask); + break; + } + case STEP_ACTION_DEACTIVATE_S1: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1S1Mask); + break; + } + case STEP_ACTION_ACTIVATE_S2: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1S2Mask); + break; + } + case STEP_ACTION_DEACTIVATE_S2: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1S2Mask); + break; + } + case STEP_ACTION_ACTIVATE_FN: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1FNMask); + break; + } + case STEP_ACTION_DEACTIVATE_FN: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1FNMask); + break; + } + case STEP_ACTION_ACTIVATE_PPI: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1PIMask); + break; + } + case STEP_ACTION_DEACTIVATE_PPI: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1PIMask); + break; + } + case STEP_ACTION_ACTIVATE_PPE: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT1PEMask); + break; + } + case STEP_ACTION_DEACTIVATE_PPE: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT1PEMask); + break; + } + case STEP_ACTION_ACTIVATE_PGI: + { + mPGIValue = (mPGTreshold * mPGTreshold) + 50; + mInternalLazerProbe->SetData(mPGIValue); + break; + } + case STEP_ACTION_DEACTIVATE_PGI: + { + mPGIValue = mPGTreshold; + mInternalLazerProbe->SetData(mPGIValue); + break; + } + case STEP_ACTION_ACTIVATE_PGE: + { + mPGEValue = (mPGTreshold * mPGTreshold) + 50; + mExternalLazerProbe->SetData(mPGEValue); + break; + } + case STEP_ACTION_DEACTIVATE_PGE: + { + mPGEValue = mPGTreshold; + mExternalLazerProbe->SetData(mPGEValue); + break; + } + case STEP_ACTION_REGISTER_ZT1_ITI: + { + mInputModule->SetInputBufFlags(mStationInputMasks->InputZT1ITIMask); + break; + } + case STEP_ACTION_DESTROY_ZT1_ITI: + { + mInputModule->ClearInputBufFlags(mStationInputMasks->InputZT1ITIMask); + break; + } + case STEP_ACTION_REGISTER_ZT2_ITI: + { + mInputModule->SetInputBufFlags(mStationInputMasks->InputZT2ITIMask); + break; + } + case STEP_ACTION_DESTROY_ZT2_ITI: + { + mInputModule->ClearInputBufFlags(mStationInputMasks->InputZT2ITIMask); + break; + } + case STEP_ACTION_OCCUPY_ZT1_APPROACH: + { + CCDV *ApproachCDVPtr = mStationPtr->GetZT1ApproachCDV(); + for(int i = 0; i < mSimCDVItemsList.size(); i++) + { + if(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask() == ApproachCDVPtr->GetInputMask()) + { + mInputModule->ClearInputBufFlags(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask()); + break; + } + } + + break; + } + case STEP_ACTION_FREE_ZT1_APPROACH: + { + CCDV *ApproachCDVPtr = mStationPtr->GetZT1ApproachCDV(); + for(int i = 0; i < mSimCDVItemsList.size(); i++) + { + if(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask() == ApproachCDVPtr->GetInputMask()) + { + mInputModule->SetInputBufFlags(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask()); + break; + } + } + break; + } + case STEP_ACTION_OCCUPY_ZT1: + { + CCDV *ZT1CDVPtr = mStationPtr->GetZT1CDV(); + for(int i = 0; i < mSimCDVItemsList.size(); i++) + { + if(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask() == ZT1CDVPtr->GetInputMask()) + { + mInputModule->ClearInputBufFlags(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask()); + break; + } + } + break; + } + case STEP_ACTION_FREE_ZT1: + { + CCDV *ZT1CDVPtr = mStationPtr->GetZT1CDV(); + for(int i = 0; i < mSimCDVItemsList.size(); i++) + { + if(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask() == ZT1CDVPtr->GetInputMask()) + { + mInputModule->SetInputBufFlags(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask()); + break; + } + } + break; + } + case STEP_ACTION_OCCUPY_ZT2_APPROACH: + { + break; + } + case STEP_ACTION_FREE_ZT2_APPROACH: + { + break; + } + case STEP_ACTION_OCCUPY_ZT2: + { + CCDV *ZT2CDVPtr = mStationPtr->GetZT2CDV(); + for(int i = 0; i < mSimCDVItemsList.size(); i++) + { + if(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask() == ZT2CDVPtr->GetInputMask()) + { + mInputModule->ClearInputBufFlags(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask()); + break; + } + } + break; + } + case STEP_ACTION_FREE_ZT2: + { + CCDV *ZT2CDVPtr = mStationPtr->GetZT2CDV(); + for(int i = 0; i < mSimCDVItemsList.size(); i++) + { + if(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask() == ZT2CDVPtr->GetInputMask()) + { + mInputModule->SetInputBufFlags(mSimCDVItemsList.at(i)->GetCDV()->GetInputMask()); + break; + } + } + break; + } + case STEP_ACTION_ACTIVATE_ZT2_S1: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT2S1Mask); + break; + } + case STEP_ACTION_DEACTIVATE_ZT2_S1: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT2S1Mask); + break; + } + case STEP_ACTION_ACTIVATE_ZT2_PPI: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT2PIMask); + break; + } + case STEP_ACTION_DEACTIVATE_ZT2_PPI: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT2PIMask); + break; + } + case STEP_ACTION_ACTIVATE_ZT2_PPE: + { + mPCIIO->ClearInputBufFlags(mStationInputMasks->InputZT2PEMask); + break; + } + case STEP_ACTION_DEACTIVATE_ZT2_PPE: + { + mPCIIO->SetInputBufFlags(mStationInputMasks->InputZT2PEMask); + break; + } + case STEP_ACTION_SCENARIO_END: + { + break; + } + } + +} +void CZTSimulator::SimulationScenarioFinished() +{ + mLazerProbesUpdateTimer->stop(); + if(mLoopSimCheckbox->checkState() == Qt::Checked) + { + StartSim(); + } + +} + +void CZTSimulator::LazerProbesSimTimerExpired() +{ + static qreal inc=1; + //qreal sine = qSin(mSimulationElapsedTimer->elapsed()); + qreal sine = qSin(++inc/10); + sine += 1; + sine /= 2; + int Calib = 500000;//CZTConfigMgr::instance()->GetLaserSensorCalib(); + //int value = (int)(Calib*sine); + + //mPGEValue = mPGIValue = value; + //mPGEValue = mPGIValue = 0; + + mInternalLazerProbe->SetData(mPGIValue); + mExternalLazerProbe->SetData(mPGEValue); +} + +void CZTSimulator::FileSimFinished() +{ + mSimThread->quit(); + mSimThread->wait(); + + if(mLoopSimCheckbox->checkState() == Qt::Checked) + { + mFileSimLoopDelayTimer.start(1000); +// mSimThread->start(QThread::NormalPriority); + } +} + +void CZTSimulator::UpdateOutputsDisplay(quint32 Outputs) +{ + if((Outputs & mStationOutputMasks->OutputVP1Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VP1_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VP1_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVP2Mask) != 0) + { + + LedWidget[GENERIC_OUTPUT_VP2_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VP2_ID]->LedOFF(); + + } + if((Outputs & mStationOutputMasks->OutputVP3Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VP3_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VP3_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVP4Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VP4_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VP4_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVP5Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VP5_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VP5_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVP6Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VP6_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VP6_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVF1Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VF1_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VF1_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVF2Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VF2_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VF2_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVF3Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VF3_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_VF3_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVF4Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VF4_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_VF4_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVF5Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VF5_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_VF5_ID]->LedOFF(); + } + + if((Outputs & mStationOutputMasks->OutputWP1Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_WP1_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_WP1_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputWP2Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_WP2_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_WP2_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputWP3Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_WP3_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_WP3_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputWP4Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_WP4_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_WP4_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputWP5Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_WP5_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_WP5_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputWP6Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_WP6_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_WP6_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputDPEMask) != 0) + { + LedWidget[GENERIC_OUTPUT_DPE_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_DPE_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputDPIMask) != 0) + { + LedWidget[GENERIC_OUTPUT_DPI_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_DPI_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputV00Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_V00_ID]->LedON(); + + + } + else + { + LedWidget[GENERIC_OUTPUT_V00_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputDPGMask) != 0) + { + LedWidget[GENERIC_OUTPUT_DPG_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_DPG_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputDFRMask) != 0) + { + LedWidget[GENERIC_OUTPUT_DFR_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_DFR_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputRFMask) != 0) + { + LedWidget[GENERIC_OUTPUT_RF_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_RF_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputRF2Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_RF2_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_RF2_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVELMask) != 0) + { + LedWidget[GENERIC_OUTPUT_VEL_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_VEL_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputVEL2Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_VEL2_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_VEL2_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputDPI2Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_DPI2_ID]->LedON(); + + } + else + { + LedWidget[GENERIC_OUTPUT_DPI2_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputDPE2Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_DPE2_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_DPE2_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputV002Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_V002_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_V002_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputPEQ1Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_PEQ1_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_PEQ1_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputPEQ2Mask) != 0) + { + LedWidget[GENERIC_OUTPUT_PEQ2_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_PEQ2_ID]->LedOFF(); + } + if((Outputs & mStationOutputMasks->OutputWatchdogMask) != 0) + { + LedWidget[GENERIC_OUTPUT_WATCHDOG_ID]->LedON(); + } + else + { + LedWidget[GENERIC_OUTPUT_WATCHDOG_ID]->LedOFF(); + } +} + + +void CZTSimulator::FileLoopDelayExpired() +{ + mSimThread->start(QThread::NormalPriority); +} + +void CZTSimulator::USBEmulationCheckboxChanged(int state) +{ + if(state == Qt::Checked) + { + mUSBKeyPresenceToggleBtn->show(); + mUSBDriveInterfacePtr->EnableDriveEmulation(true); + } + else + { + mUSBKeyPresenceToggleBtn->hide(); + mUSBDriveInterfacePtr->EnableDriveEmulation(false); + } +} + +void CZTSimulator::USBEmulationPresenceToggled(CToggleTextButtonWidget *btn) +{ + if(btn->GetActivationState() == true) + { + qDebug("Branchée"); + mUSBDriveInterfacePtr->EmulateDrivePresence(true); + } + else + { + qDebug("Débranchée"); + mUSBDriveInterfacePtr->EmulateDrivePresence(false); + } +} + +void CZTSimulator::SimulDefectLazerCheckboxChanged(int state) +{ + if(state == Qt::Checked) + { + mInternalLazerProbe->SetProbeDead(); + mExternalLazerProbe->SetProbeDead(); + } + else + { + mInternalLazerProbe->SetProbeAlive(); + mExternalLazerProbe->SetProbeAlive(); + } +} + diff --git a/sources/Simulator/ZTSimulator.h b/sources/Simulator/ZTSimulator.h new file mode 100644 index 0000000..c5e4652 --- /dev/null +++ b/sources/Simulator/ZTSimulator.h @@ -0,0 +1,148 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef CZTSIMULATOR_H +#define CZTSIMULATOR_H +#include +#include "SimulatorIOManager.h" +#include "GlobalDefine.h" +#include "Station.h" +#include "SimulatorLazerProbesMgr.h" +#include "SimulatorIOManager.h" +#include "SimulatorPCIIO.h" +#include "CDVItem.h" +#include "ToggleTextButtonWidget.h" +#include "PushButton.h" +#include +#include "SimulationScenario.h" +#include +#include "LedWidget.h" +#include "SimulatorThread.h" +#include +#include "USBDriveInterface.h" +#include "IOManager.h" + + + +#define SIM_LAZER_PROBES_UPDATE_TIMEOUT 1 //milliseconds +#define USE_REAL_ANALOG_EXTERNAL_MODULE + +class CZTPage; + + +class CZTSimulator : public QGraphicsWidget +{ + Q_OBJECT +public: + CZTSimulator(CSimulatorIOManager *mIOMgrPtr); + ~CZTSimulator(); + + + + + void Show(); + unsigned int Init(CZTPage *MainPagePtr, CStation *Station, CIOManager *IOMgrPtr,CPCIIOMgr *PCIIO,CAbstractLazerProbeMgr *LazerProbesMgr,CUSBDriveInterface *UsbDriveInterface, CAnalogInputModule *RealAnalogModule=0); + void UpdateSimulatorDisplay(); +// void UpdateOutputsDisplay(quint32 Outputs); + void StartSim(); + void SetPGTreshold(qint32 Treshold); + +private: + CSimulatorIOManager *mIOMgrPtr; + CSimulatorPCIIO *mPCIIO; + CSimulatorLazerProbesMgr *mLazerProbesMgr; + CSimulatorLazerProbe *mInternalLazerProbe, *mExternalLazerProbe; + CZTPage *mMainPagePtr; + CStation *mStationPtr; + CSimulatorInputModule *mInputModule; + CSImulatorOutputModule *mOutputModule; + CSimulatorMixedModule *mMixedModule; + + CSimulatorThread *mSimWorkerThread; + QThread *mSimThread; + CLogElement *mSimLogElement; + CUSBDriveInterface *mUSBDriveInterfacePtr; + + GenericInputMasks_t *mStationInputMasks; + GenericOutputMasks_t *mStationOutputMasks; + + //Simulator GUI items + QList mSimCDVItemsList; + CToggleTextButtonWidget *mITIZT1ToggleBtn, *mITIZT2ToggleBtn, *mITIZT1AltToggleBtn; + CToggleTextButtonWidget *mS1SimBtn, *mS2SimBtn, *mS1S2SimBtn, *mFNSimBtn, *mPPISimBtn, *mPPESimBtn; + CToggleTextButtonWidget *mZT2S1SimBtn, *mZT2PPISimBtn,*mZT2PPESimBtn; + CPushButton *mSimulationStartBtn, *mSimFileOpenBtn, *mSimDirOpenButton; + CToggleTextButtonWidget *mAN1SimBtn, *mAN2SimBtn; + QCheckBox *mLoopSimCheckbox; + QCheckBox *mProbesAliveCheckBox; + + //USB stick presence emulation + QCheckBox *mUSBKeyEmuEnableCheckBox; + CToggleTextButtonWidget *mUSBKeyPresenceToggleBtn; + + //General simulator stuff + QElapsedTimer *mSimulationElapsedTimer; + QTimer mFileSimLoopDelayTimer; + + //Simulation scenario stuff + CSimulationScenario *mScenario; + + //Lazer probes simulation + QTimer *mLazerProbesUpdateTimer; + unsigned int mPGTreshold; + unsigned int mPGIValue, mPGEValue; + + //Outputs display + CLedWidget *LedWidget[GENERIC_OUTPUT_NB_ID]; + + + void DestroyLogElement(); + + +public slots: + void CDVItemRightClicked(CCDVItem *ClickedItem); + void ItineraryToggleSwitchActivate(CToggleTextButtonWidget*); + void ItineraryToggleSwitchDeActivate(CToggleTextButtonWidget*); + void ZT1SensorBtnActivate(CToggleTextButtonWidget*); + void ZT1SensorBtnDeActivate(CToggleTextButtonWidget*); + void ZT2SensorBtnActivate(CToggleTextButtonWidget*); + void ZT2SensorBtnDeActivate(CToggleTextButtonWidget*); + void SimulationScenarioButtonPressed(CPushButton*); + void SimulationScenarioExecStep(CSimulationStep*); + void SimulationScenarioFinished(); + void LazerProbesSimTimerExpired(); + void FileSimFinished(); + void FileLoopDelayExpired(); + void USBEmulationCheckboxChanged(int state); + void USBEmulationPresenceToggled(CToggleTextButtonWidget*); + void UpdateOutputsDisplay(quint32); + void SimulDefectLazerCheckboxChanged(int state); + + +}; + +#endif // CZTSIMULATOR_H diff --git a/sources/Station.cpp b/sources/Station.cpp new file mode 100644 index 0000000..7584592 --- /dev/null +++ b/sources/Station.cpp @@ -0,0 +1,178 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe de base des définitions des différentes stations. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "Station.h" + +CStation::CStation() +{ + mZT1ApproachCDV = mZT1CDV = mZT1AlarmAutoAcquireCDV = mZT1SubsequentCDV = 0; + mZT2ApproachCDV = mZT2CDV = mZT2AlarmAutoAcquireCDV = 0; + mStationInputMasks.InputZT1_AltITIMask = 0;//Useful for Simulator only +} +CStation::~CStation() +{ + for(int i = 0; i < mCDVList.size(); i++) + delete mCDVList.at(i); + + mCDVList.clear(); +} + +unsigned int CStation::CheckStationKey(unsigned int ExternalInputs) +{ + unsigned int key = ExternalInputs; + unsigned int checkkey = mStationPhysicalKey; + unsigned int mask = mStationInputMasks.InputStationIDMask; + key &= mask; + if(key != checkkey) + { + CEngLog::instance()->AddLogString(QString("").sprintf("Incohérence de la clef physique. Physique: 0x%x, Attendue: 0x%x",key,mStationPhysicalKey),1); + return RET_ERROR; + } + CEngLog::instance()->AddLogString(QString("").sprintf("Clef physique de la station cohérente: 0x%x",key),3); + + return RET_OK; +} + +unsigned int CStation::BuildCDVList() +{ + if(BuildStationCDVList() == RET_OK) + { + return true; + } + mStationInputMasks.InputZT1_StdITIMask = mStationInputMasks.InputZT1ITIMask; //Useful for Simulator only + + return false; +} + + +bool CStation::IsZT1ApproachCDVOccupied() +{ + if(mZT1ApproachCDV) + return mZT1ApproachCDV->IsOccupied(); + + return false; +} + +bool CStation::IsZT1ApproachPresent() +{ + if(mZT1ApproachCDV == mZT1CDV) + return false; + + return true; +} + +bool CStation::IsZT1CDVOccupied() +{ + + if(mZT1CDV) + return mZT1CDV->IsOccupied(); + + return false; +} + +bool CStation::IsZT1AnalysisFinished() +{ + //Normally, the ZT1 analysis ends when the train quits the ZT1 CDV. + return !IsZT1CDVOccupied(); +} + +bool CStation::IsZT1SubsequentCDVOccupied() +{ + if(mZT1SubsequentCDV) + return mZT1SubsequentCDV->IsOccupied(); + + return false; +} + +bool CStation::IsZT2CDVOccupied() +{ + if(mZT2CDV) + return mZT2CDV->IsOccupied(); + + return false; +} + +bool CStation::IsZT1AlarmAutoAcquireCDVOccupied() +{ + if(mZT1AlarmAutoAcquireCDV) + return mZT1AlarmAutoAcquireCDV->IsOccupied(); + + return false; +} + +bool CStation::IsZT2AlarmAutoAcquireCDVOccupied() +{ + if(mZT2AlarmAutoAcquireCDV) + return mZT2AlarmAutoAcquireCDV->IsOccupied(); + + + return false; +} + +bool CStation::IsZT2ApproachCDVOccupied() +{ + if(mZT2ApproachCDV) + return mZT2ApproachCDV->IsOccupied(); + + return false; +} + +//NOTE: Reimplement this function in the station class if necessary (for instance, the +//Montmorency station has 2 ZT1 itineraries that change inputs masks according to +//which itinerary is commanded. +unsigned int CStation::UpdateStationMasks(unsigned int ExtInputData) +{ + Q_UNUSED(ExtInputData) + mStationInputMasks.InputZT1_StdITIMask = mStationInputMasks.InputZT1ITIMask; + return RET_OK; +} + +unsigned int CStation::UpdateCDVs(unsigned int ExtInputData) +{ + //Update CDVs states. + for(int CDV = 0; CDV < mCDVList.size(); CDV++) + { + mCDVList.at(CDV)->ComputeCDVState(ExtInputData,mStationInputMasks.InputZT1ITIMask,mStationInputMasks.InputZT2ITIMask); + } + + return RET_OK; +} + +bool CStation::StationHasZT2() +{ + return mStationHasZT2; +} + +GenericInputMasks_t *CStation::GetInputMasks() +{ +// qDebug("CStation get input masks"); + return &mStationInputMasks; +} + +GenericAnalogAcquisitionChannels_t *CStation::GetAnalogAcqChannels() +{ + return &mAnalogAcqChannels; +} diff --git a/sources/Station.h b/sources/Station.h new file mode 100644 index 0000000..9fe9d34 --- /dev/null +++ b/sources/Station.h @@ -0,0 +1,270 @@ +#ifndef CSTATION_H +#define CSTATION_H + +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#ifndef WINDOWS_OS +#include "ExternalIOMgr.h" +#endif +//#include "Seaio430driver.h" +//#include "Seaio440driver.h" +//#include "Seaio470driver.h" +#include "InputModule.h" +#include "OutputModule.h" +#include "MixedModule.h" +#include "LazerProbesMgr.h" +#include "LazerProbe.h" +#include "ZTData.h" +//#include "CDVItem.h" +#include "IOManager.h" +#include "CDV.h" + + +//Masques des sorties génériques communes à toutes les stations +typedef struct eGenericOutputMasks +{ + unsigned int OutputVP1Mask; + unsigned int OutputVP2Mask; + unsigned int OutputVP3Mask; + unsigned int OutputVP4Mask; + unsigned int OutputVP5Mask; + unsigned int OutputVP6Mask; + unsigned int OutputVF1Mask; + unsigned int OutputVF2Mask; + unsigned int OutputVF3Mask; + unsigned int OutputVF4Mask; + unsigned int OutputVF5Mask; + unsigned int OutputWP1Mask; + unsigned int OutputWP2Mask; + unsigned int OutputWP3Mask; + unsigned int OutputWP4Mask; + unsigned int OutputWP5Mask; + unsigned int OutputWP6Mask; + unsigned int OutputDPEMask; + unsigned int OutputDPIMask; + unsigned int OutputV00Mask; + unsigned int OutputDPGMask; + unsigned int OutputDFRMask; + unsigned int OutputRFMask; + unsigned int OutputRF2Mask; + unsigned int OutputVELMask; + unsigned int OutputVEL2Mask; + unsigned int OutputDPI2Mask; + unsigned int OutputDPE2Mask; + unsigned int OutputV002Mask; + unsigned int OutputPEQ1Mask; + unsigned int OutputPEQ2Mask; + unsigned int OutputWatchdogMask; +}GenericOutputMasks_t; + +//Identificatieurs des sorties génériques communes à toutes les stations +enum eGenericOutputIDs +{ + GENERIC_OUTPUT_VP1_ID, + GENERIC_OUTPUT_VP2_ID, + GENERIC_OUTPUT_VP3_ID, + GENERIC_OUTPUT_VP4_ID, + GENERIC_OUTPUT_VP5_ID, + GENERIC_OUTPUT_VP6_ID, + + GENERIC_OUTPUT_DPE_ID, + GENERIC_OUTPUT_DPI_ID, + GENERIC_OUTPUT_V00_ID, + + GENERIC_OUTPUT_VF1_ID, + GENERIC_OUTPUT_VF2_ID, + GENERIC_OUTPUT_VF3_ID, + GENERIC_OUTPUT_VF4_ID, + GENERIC_OUTPUT_VF5_ID, + + GENERIC_OUTPUT_DPG_ID, + GENERIC_OUTPUT_DFR_ID, + GENERIC_OUTPUT_RF_ID, + GENERIC_OUTPUT_VEL_ID, + GENERIC_OUTPUT_VEL2_ID, + + GENERIC_OUTPUT_WP1_ID, + GENERIC_OUTPUT_WP2_ID, + GENERIC_OUTPUT_WP3_ID, + GENERIC_OUTPUT_WP4_ID, + GENERIC_OUTPUT_WP5_ID, + GENERIC_OUTPUT_WP6_ID, + + GENERIC_OUTPUT_DPI2_ID, + GENERIC_OUTPUT_DPE2_ID, + GENERIC_OUTPUT_V002_ID, + + GENERIC_OUTPUT_RF2_ID, + + GENERIC_OUTPUT_PEQ1_ID, + GENERIC_OUTPUT_PEQ2_ID, + + GENERIC_OUTPUT_WATCHDOG_ID, + + GENERIC_OUTPUT_NB_ID +}; + +//Masques d'entrées génériques communes à toutes les stations +typedef struct eGenericInputMasks +{ + //PCI Input Module Masks + unsigned int InputZT1S1Mask; + unsigned int InputZT1S2Mask; + unsigned int InputZT1PIMask; + unsigned int InputZT1PEMask; + unsigned int InputZT1FNMask; + unsigned int InputZT2S1Mask; + unsigned int InputZT2PIMask; + unsigned int InputZT2PEMask; + + //External (ethernet) input module masks + unsigned int InputZT1ITIMask; + unsigned int InputZT2ITIMask; + unsigned int InputZT1ANMask; + unsigned int InputZT2ANMask; + unsigned int InputZT1ARFMask; + unsigned int InputZT2ARFMask; + unsigned int InputStationIDMask; + unsigned int InputZT1_StdITIMask; + unsigned int InputZT1_AltITIMask; + + //Logic input masks + unsigned int InputCDVZT1ApproachMask; + unsigned int InputCDVZT1Mask; + unsigned int InputCDVZT2ApproachMask; + unsigned int InputCDVZT2Mask; + +}GenericInputMasks_t; + +enum eGenericInputIDs +{ + GENERIC_INPUT_ZT1_S1_ID, + GENERIC_INPUT_ZT1_S2_ID, + GENERIC_INPUT_ZT1_PI_ID, + GENERIC_INPUT_ZT1_PE_ID, + GENERIC_INPUT_ZT1_FN_ID, + GENERIC_INPUT_ZT2_S1_ID, + GENERIC_INPUT_ZT2_PI_ID, + GENERIC_INPUT_ZT2_PE_ID, + GENERIC_INPUT_ZT1_ITI_ID, + GENERIC_INPUT_ZT2_ITI_ID, + GENERIC_INPUT_ZT1_AN_ID, + GENERIC_INPUT_ZT2_AN_ID, + GENERIC_INPUT_ZT1_ARF_ID, + GENERIC_INPUT_ZT2_ARF_ID, + GENERIC_INPUT_STATION_ID_0_ID, + GENERIC_INPUT_STATION_ID_1_ID, + GENERIC_INPUT_STATION_ID_2_ID, + GENERIC_INPUT_STATION_ID_3_ID, + GENERIC_INPUT_NB_ID +}; + +#define STATION_KEY_ID_0_MASK 0x08000 +#define STATION_KEY_ID_1_MASK 0x10000 +#define STATION_KEY_ID_2_MASK 0x20000 +#define STATION_KEY_ID_3_MASK 0x40000 + +typedef struct eGenericAnalogAcquisitionChannels +{ + unsigned int SDFAcquisitionChannel; + +}GenericAnalogAcquisitionChannels_t; + +class CStation +{ +public: + virtual ~CStation(); + + GenericInputMasks_t mStationInputMasks; //Instance des masques d'entrées. Initialisé dynamiquement au démarrage. + GenericOutputMasks_t mStationOutputMasks; //Instance des masques de sorties. Initialisé dynamiquement au démarrage. + GenericAnalogAcquisitionChannels_t mAnalogAcqChannels; //Canaux d'acquisition analogiques. Initialisé dynamiquement au démarrage. + + CStation(); + + unsigned int CheckStationKey(unsigned int ExternalInputs); + unsigned int GetStationKeyValue(void){return mStationPhysicalKey;} + unsigned int GetStationKey(); + QString GetStationTextualName(void){return mTextualStationName;} + QString GetStationShortName(void){return mTextualShortName;} + unsigned int BuildCDVList(); + + QList *GetCDVList(){return &mCDVList;} + virtual unsigned int UpdateCDVs(unsigned int ExtInputData); + virtual unsigned int UpdateStationMasks(unsigned int ExtInputData); + virtual GenericInputMasks_t *GetInputMasks(void); + virtual GenericAnalogAcquisitionChannels_t *GetAnalogAcqChannels(void); + GenericOutputMasks_t *GetOutputMasks(void){return &mStationOutputMasks;} + GenericAnalogAcquisitionChannels_t *GetAnalogChannels(){return &mAnalogAcqChannels;} + virtual bool IsZT1ApproachCDVOccupied(); + virtual bool IsZT1AnalysisFinished(); + virtual bool IsZT1CDVOccupied(); + bool IsZT1SubsequentCDVOccupied(); + bool IsZT2CDVOccupied(); + bool StationHasZT2(); + bool IsZT1AlarmAutoAcquireCDVOccupied(); + bool IsZT2AlarmAutoAcquireCDVOccupied(); + bool IsZT2ApproachCDVOccupied(); + bool IsZT1CIOpened(); + bool IsZT1ApproachPresent(); + + CCDV *GetZT1ApproachCDV(){return mZT1ApproachCDV;} + CCDV *GetZT1CDV(){return mZT1CDV;} + CCDV *GetZT1AlarmAutoAcquireCDV(){return mZT1AlarmAutoAcquireCDV;} + CCDV *GetZT2ApproachCDV(){return mZT2ApproachCDV;} + CCDV *GetZT2CDV(){return mZT2CDV;} + CCDV *GetZT2AlarmAutoAcquireCDV(){return mZT2AlarmAutoAcquireCDV;} + + + +protected: + CIOManager *mExtIOMgrPtr; + unsigned int mNbExtInputModules430; //Nombre de modules SEAIO430 installés dans le TO à cette station + unsigned int mNbExtOutputModules440; //Nombre de modules SEAIO440 installés dans le TO à cette station + unsigned int mNbExtMixedModules470; //Nombre de modules SEAIO470 installés dans le TO à cette station + unsigned int mStationPhysicalKey; //Clef physique de la station, chargée dynamiquement au démarrage. + QString mTextualStationName,mTextualShortName; //Noms textuels de la station + QList mCDVList; //Liste des CDVs qui sont présents dans cette station + bool mStationHasZT2; //Flag indiquant si la station possède une ZT2 + + CCDV *mZT1ApproachCDV, //Pointeur vers le CDV d'approche ZT1 (celui qui précède le CDV ZT1). + *mZT1SubsequentCDV, //Pointeur vers le CDV qui suit le CDV ZT1 + *mZT1CDV, //Pointeur vers le CDV ZT1 (celui sur lequel les équipements sont installés) + *mZT1AlarmAutoAcquireCDV; //Pointeurs vers le CDV dont la libération déclenche l'acquisition automatique des alarmes ZT1 au PCC + + CCDV *mZT2ApproachCDV, //Pointeur vers le CDV d'approche ZT2 (celui qui précède le CDV ZT2). + *mZT2CDV, //Pointeur vers le CDV ZT2 (celui sur lequel les équipements sont installés) + *mZT2AlarmAutoAcquireCDV; //Pointeurs vers le CDV dont la libération déclenche l'acquisition automatique des alarmes ZT2 au PCC + + + +private: + virtual unsigned int BuildStationCDVList() = 0; +}; + +#endif // CSTATION_H diff --git a/sources/Stations/Angrignon.cpp b/sources/Stations/Angrignon.cpp new file mode 100644 index 0000000..a952787 --- /dev/null +++ b/sources/Stations/Angrignon.cpp @@ -0,0 +1,167 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121217 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Angrignon.h" +#include +#ifndef WINDOWS_OS +#include "ExternalIOMgr.h" +#include "Seaio430driver.h" +#endif + +//rydy +CAngrignonStation::CAngrignonStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = ANGRIGNON_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = ANGRIGNON_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = ANGRIGNON_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = ANGRIGNON_STATION_KEY; + + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = ANGRIGNON_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = ANGRIGNON_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = ANGRIGNON_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = ANGRIGNON_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = ANGRIGNON_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = ANGRIGNON_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = ANGRIGNON_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = ANGRIGNON_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = ANGRIGNON_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = ANGRIGNON_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = ANGRIGNON_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = ANGRIGNON_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = ANGRIGNON_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = ANGRIGNON_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = ANGRIGNON_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = ANGRIGNON_IN_CDV_11A_MASK; + mStationInputMasks.InputCDVZT1Mask = ANGRIGNON_IN_CDV_11B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = ANGRIGNON_IN_CDV_12B_MASK; + mStationInputMasks.InputCDVZT2Mask = ANGRIGNON_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = ANGRIGNON_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = ANGRIGNON_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = ANGRIGNON_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = ANGRIGNON_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = ANGRIGNON_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = ANGRIGNON_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = ANGRIGNON_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = ANGRIGNON_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = ANGRIGNON_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = ANGRIGNON_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = ANGRIGNON_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = ANGRIGNON_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = ANGRIGNON_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = ANGRIGNON_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = ANGRIGNON_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = ANGRIGNON_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = ANGRIGNON_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = ANGRIGNON_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = ANGRIGNON_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = ANGRIGNON_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = ANGRIGNON_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = ANGRIGNON_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = ANGRIGNON_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = ANGRIGNON_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = ANGRIGNON_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = ANGRIGNON_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = ANGRIGNON_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = ANGRIGNON_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = ANGRIGNON_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = ANGRIGNON_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = ANGRIGNON_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = ANGRIGNON_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = ANGRIGNON_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mTextualStationName = "Angrignon"; + mTextualShortName = "ANG"; +} + +unsigned int CAngrignonStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(ANGRIGNON_IN_ZT2_ITI_MASK,ANGRIGNON_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(ANGRIGNON_IN_ZT2_ITI_MASK,ANGRIGNON_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(ANGRIGNON_IN_ZT2_ITI_MASK,ANGRIGNON_IN_CDV_13BC_MASK,CDV_NORMAL_TYPE,"13BC",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(ANGRIGNON_IN_ZT2_ITI_MASK,ANGRIGNON_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A ZT2",1,3); + mZT2CDV = NewCDV; + mZT2ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(ANGRIGNON_IN_ZT1_ITI_MASK,ANGRIGNON_IN_CDV_12B_MASK,CDV_NORMAL_TYPE,"12B",1,4); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + + NewCDV = new CCDV(ANGRIGNON_IN_ZT1_ITI_MASK,ANGRIGNON_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mZT1SubsequentCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + + NewCDV = new CCDV(ANGRIGNON_IN_ZT1_ITI_MASK,ANGRIGNON_IN_CDV_11B_MASK,CDV_NORMAL_TYPE,"11B ZT1",1,6); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(ANGRIGNON_IN_ZT1_ITI_MASK,ANGRIGNON_IN_CDV_11A_MASK,CDV_NORMAL_TYPE,"11A",1,7); + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(ANGRIGNON_IN_ZT1_ITI_MASK,ANGRIGNON_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B",1,8); + mCDVList.append(NewCDV); + + return RET_OK; +} + + diff --git a/sources/Stations/Angrignon.h b/sources/Stations/Angrignon.h new file mode 100644 index 0000000..36b0b09 --- /dev/null +++ b/sources/Stations/Angrignon.h @@ -0,0 +1,119 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121217 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef Angrignon_H +#define Angrignon_H +#include "Station.h" + +#define ANGRIGNON_STATION_KEY 0x0010000 +#define ANGRIGNON_NB_EXTERNAL_INPUT_430_MODULES 1 +#define ANGRIGNON_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define ANGRIGNON_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define ANGRIGNON_ZT1_S1_MASK 0x00000001 +#define ANGRIGNON_ZT1_S2_MASK 0x00000002 +#define ANGRIGNON_ZT1_PI_MASK 0x00000004 +#define ANGRIGNON_ZT1_PE_MASK 0x00000008 +#define ANGRIGNON_ZT1_FN_MASK 0x00000010 +#define ANGRIGNON_ZT2_S1_MASK 0x00000020 +#define ANGRIGNON_ZT2_PI_MASK 0x00000040 +#define ANGRIGNON_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for Angrignon +#define ANGRIGNON_IN_CDV_12A_MASK 0x00000001 +#define ANGRIGNON_IN_CDV_12B_MASK 0x00000002 +#define ANGRIGNON_IN_CDV_11B_MASK 0x00000004 +#define ANGRIGNON_IN_CDV_11A_MASK 0x00000008 +#define ANGRIGNON_IN_CDV_10B_MASK 0x00000010 +#define ANGRIGNON_IN_CDV_13A_MASK 0x00000020 +#define ANGRIGNON_IN_CDV_14A_MASK 0x00000040 +#define ANGRIGNON_IN_CDV_13BC_MASK 0x00000080 +#define ANGRIGNON_IN_CDV_14B_MASK 0x00000100 +#define ANGRIGNON_IN_ZT1_ITI_MASK 0x00000200 +#define ANGRIGNON_IN_ZT2_ITI_MASK 0x00000400 +#define ANGRIGNON_IN_ZT1_AN_MASK 0x00000800 +#define ANGRIGNON_IN_ZT2_AN_MASK 0x00001000 +#define ANGRIGNON_IN_ZT1_ARF_MASK 0x00002000 +#define ANGRIGNON_IN_ZT2_ARF_MASK 0x00004000 +#define ANGRIGNON_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for Angrignon +#define ANGRIGNON_OUT_VP1_MASK 0x00000001 +#define ANGRIGNON_OUT_VP2_MASK 0x00000002 +#define ANGRIGNON_OUT_VP3_MASK 0x00000004 +#define ANGRIGNON_OUT_VP4_MASK 0x00000008 +#define ANGRIGNON_OUT_VP5_MASK 0x00000010 +#define ANGRIGNON_OUT_VP6_MASK 0x00000020 +#define ANGRIGNON_OUT_VF1_MASK 0x00000040 +#define ANGRIGNON_OUT_VF2_MASK 0x00000080 +#define ANGRIGNON_OUT_VF3_MASK 0x00000100 +#define ANGRIGNON_OUT_VF4_MASK 0x00000200 +#define ANGRIGNON_OUT_VF5_MASK 0x00000400 +#define ANGRIGNON_OUT_WP1_MASK 0x00000800 +#define ANGRIGNON_OUT_WP2_MASK 0x00001000 +#define ANGRIGNON_OUT_WP3_MASK 0x00002000 +#define ANGRIGNON_OUT_WP4_MASK 0x00004000 +#define ANGRIGNON_OUT_WP5_MASK 0x00008000 +#define ANGRIGNON_OUT_WP6_MASK 0x00010000 +#define ANGRIGNON_OUT_DPE_MASK 0x00020000 +#define ANGRIGNON_OUT_DPI_MASK 0x00040000 +#define ANGRIGNON_OUT_V00_MASK 0x00080000 +#define ANGRIGNON_OUT_DPG_MASK 0x00100000 +#define ANGRIGNON_OUT_DFR_MASK 0x00200000 +#define ANGRIGNON_OUT_RF_MASK 0x00400000 +#define ANGRIGNON_OUT_RF2_MASK 0x00800000 +#define ANGRIGNON_OUT_VEL_MASK 0x01000000 +#define ANGRIGNON_OUT_VEL2_MASK 0x02000000 +#define ANGRIGNON_OUT_DPI2_MASK 0x04000000 +#define ANGRIGNON_OUT_DPE2_MASK 0x08000000 +#define ANGRIGNON_OUT_V002_MASK 0x10000000 +#define ANGRIGNON_OUT_PEQ1_MASK 0x20000000 +#define ANGRIGNON_OUT_PEQ2_MASK 0x40000000 +#define ANGRIGNON_OUT_WATCHDOG_MASK 0x80000000 + +#define ANGRIGNON_SDF_ACQUISITION_CHANNEL 0 + + +class CAngrignonStation : public CStation +{ +public: + + CAngrignonStation(); + + +private: + + virtual unsigned int BuildStationCDVList(); + +}; + +#endif // Angrignon_H + diff --git a/sources/Stations/BerriUQAM.cpp b/sources/Stations/BerriUQAM.cpp new file mode 100644 index 0000000..35b5c21 --- /dev/null +++ b/sources/Stations/BerriUQAM.cpp @@ -0,0 +1,162 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "BerriUQAM.h" +#include + +CBerriUQAMStation::CBerriUQAMStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = BERRIUQAM_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = BERRIUQAM_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = BERRIUQAM_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = BERRIUQAM_STATION_KEY; + + + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = BERRIUQAM_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = BERRIUQAM_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = BERRIUQAM_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = BERRIUQAM_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = BERRIUQAM_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = BERRIUQAM_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = BERRIUQAM_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = BERRIUQAM_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = BERRIUQAM_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = BERRIUQAM_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = BERRIUQAM_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = BERRIUQAM_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = BERRIUQAM_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = BERRIUQAM_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = BERRIUQAM_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = BERRIUQAM_IN_CDV_10B_MASK; + mStationInputMasks.InputCDVZT1Mask = BERRIUQAM_IN_CDV_11_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = BERRIUQAM_IN_CDV_12B_MASK; + mStationInputMasks.InputCDVZT2Mask = BERRIUQAM_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = BERRIUQAM_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = BERRIUQAM_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = BERRIUQAM_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = BERRIUQAM_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = BERRIUQAM_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = BERRIUQAM_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = BERRIUQAM_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = BERRIUQAM_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = BERRIUQAM_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = BERRIUQAM_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = BERRIUQAM_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = BERRIUQAM_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = BERRIUQAM_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = BERRIUQAM_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = BERRIUQAM_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = BERRIUQAM_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = BERRIUQAM_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = BERRIUQAM_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = BERRIUQAM_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = BERRIUQAM_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = BERRIUQAM_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = BERRIUQAM_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = BERRIUQAM_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = BERRIUQAM_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = BERRIUQAM_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = BERRIUQAM_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = BERRIUQAM_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = BERRIUQAM_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = BERRIUQAM_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = BERRIUQAM_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = BERRIUQAM_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = BERRIUQAM_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = BERRIUQAM_SDF_ACQUISITION_CHANNEL; + + + mStationHasZT2 = true; + mTextualStationName = "Berri UQAM"; + mTextualShortName = "BUQ4"; +} + +unsigned int CBerriUQAMStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + + NewCDV = new CCDV(BERRIUQAM_IN_ZT2_ITI_MASK,BERRIUQAM_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(BERRIUQAM_IN_ZT2_ITI_MASK,BERRIUQAM_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(BERRIUQAM_IN_ZT2_ITI_MASK,BERRIUQAM_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(BERRIUQAM_IN_ZT2_ITI_MASK,BERRIUQAM_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A (ZT2)",1,3); + mZT2CDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(BERRIUQAM_IN_ZT1_ITI_MASK,BERRIUQAM_IN_CDV_12B_MASK,CDV_NORMAL_TYPE,"12B",1,4); + mZT2ApproachCDV = NewCDV; //ZT2 Approach CDV must be the one before the ZT2 CDV because equipment is installed very close from CDV limit. + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + + NewCDV = new CCDV(BERRIUQAM_IN_ZT1_ITI_MASK,BERRIUQAM_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mZT1SubsequentCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(BERRIUQAM_IN_ZT1_ITI_MASK,BERRIUQAM_IN_CDV_11_MASK,CDV_NORMAL_TYPE,"11 (ZT1)",1,6); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(BERRIUQAM_IN_ZT1_ITI_MASK,BERRIUQAM_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B",1,7); + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(BERRIUQAM_IN_ZT1_ITI_MASK,BERRIUQAM_IN_CDV_10A_MASK,CDV_NORMAL_TYPE,"10A",1,8); + mCDVList.append(NewCDV); + + return RET_OK; +} diff --git a/sources/Stations/BerriUQAM.h b/sources/Stations/BerriUQAM.h new file mode 100644 index 0000000..c204c12 --- /dev/null +++ b/sources/Stations/BerriUQAM.h @@ -0,0 +1,118 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef BERRIUQAM_H +#define BERRIUQAM_H +#include "Station.h" + +#define BERRIUQAM_STATION_KEY 0x0028000 +#define BERRIUQAM_NB_EXTERNAL_INPUT_430_MODULES 1 +#define BERRIUQAM_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define BERRIUQAM_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define BERRIUQAM_ZT1_S1_MASK 0x00000001 +#define BERRIUQAM_ZT1_S2_MASK 0x00000002 +#define BERRIUQAM_ZT1_PI_MASK 0x00000004 +#define BERRIUQAM_ZT1_PE_MASK 0x00000008 +#define BERRIUQAM_ZT1_FN_MASK 0x00000010 +#define BERRIUQAM_ZT2_S1_MASK 0x00000020 +#define BERRIUQAM_ZT2_PI_MASK 0x00000040 +#define BERRIUQAM_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for Angrignon +#define BERRIUQAM_IN_CDV_12A_MASK 0x00000001 +#define BERRIUQAM_IN_CDV_12B_MASK 0x00000002 +#define BERRIUQAM_IN_CDV_11_MASK 0x00000004 +#define BERRIUQAM_IN_CDV_10B_MASK 0x00000008 +#define BERRIUQAM_IN_CDV_10A_MASK 0x00000010 +#define BERRIUQAM_IN_CDV_13A_MASK 0x00000020 +#define BERRIUQAM_IN_CDV_14A_MASK 0x00000040 +#define BERRIUQAM_IN_CDV_13B_MASK 0x00000080 +#define BERRIUQAM_IN_CDV_14B_MASK 0x00000100 +#define BERRIUQAM_IN_ZT1_ITI_MASK 0x00000200 +#define BERRIUQAM_IN_ZT2_ITI_MASK 0x00000400 +#define BERRIUQAM_IN_ZT1_AN_MASK 0x00000800 +#define BERRIUQAM_IN_ZT2_AN_MASK 0x00001000 +#define BERRIUQAM_IN_ZT1_ARF_MASK 0x00002000 +#define BERRIUQAM_IN_ZT2_ARF_MASK 0x00004000 +#define BERRIUQAM_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for Angrignon +#define BERRIUQAM_OUT_VP1_MASK 0x00000001 +#define BERRIUQAM_OUT_VP2_MASK 0x00000002 +#define BERRIUQAM_OUT_VP3_MASK 0x00000004 +#define BERRIUQAM_OUT_VP4_MASK 0x00000008 +#define BERRIUQAM_OUT_VP5_MASK 0x00000010 +#define BERRIUQAM_OUT_VP6_MASK 0x00000020 +#define BERRIUQAM_OUT_VF1_MASK 0x00000040 +#define BERRIUQAM_OUT_VF2_MASK 0x00000080 +#define BERRIUQAM_OUT_VF3_MASK 0x00000100 +#define BERRIUQAM_OUT_VF4_MASK 0x00000200 +#define BERRIUQAM_OUT_VF5_MASK 0x00000400 +#define BERRIUQAM_OUT_WP1_MASK 0x00000800 +#define BERRIUQAM_OUT_WP2_MASK 0x00001000 +#define BERRIUQAM_OUT_WP3_MASK 0x00002000 +#define BERRIUQAM_OUT_WP4_MASK 0x00004000 +#define BERRIUQAM_OUT_WP5_MASK 0x00008000 +#define BERRIUQAM_OUT_WP6_MASK 0x00010000 +#define BERRIUQAM_OUT_DPE_MASK 0x00020000 +#define BERRIUQAM_OUT_DPI_MASK 0x00040000 +#define BERRIUQAM_OUT_V00_MASK 0x00080000 +#define BERRIUQAM_OUT_DPG_MASK 0x00100000 +#define BERRIUQAM_OUT_DFR_MASK 0x00200000 +#define BERRIUQAM_OUT_RF_MASK 0x00400000 +#define BERRIUQAM_OUT_RF2_MASK 0x00800000 +#define BERRIUQAM_OUT_VEL_MASK 0x01000000 +#define BERRIUQAM_OUT_VEL2_MASK 0x02000000 +#define BERRIUQAM_OUT_DPI2_MASK 0x04000000 +#define BERRIUQAM_OUT_DPE2_MASK 0x08000000 +#define BERRIUQAM_OUT_V002_MASK 0x10000000 +#define BERRIUQAM_OUT_PEQ1_MASK 0x20000000 +#define BERRIUQAM_OUT_PEQ2_MASK 0x40000000 +#define BERRIUQAM_OUT_WATCHDOG_MASK 0x80000000 + +#define BERRIUQAM_SDF_ACQUISITION_CHANNEL 0 + +class CBerriUQAMStation : public CStation +{ +public: + + CBerriUQAMStation(); + + + +private: + + virtual unsigned int BuildStationCDVList(); +}; + +#endif // BERRIUQAM_H + diff --git a/sources/Stations/CoteVertu.cpp b/sources/Stations/CoteVertu.cpp new file mode 100644 index 0000000..d59b0ab --- /dev/null +++ b/sources/Stations/CoteVertu.cpp @@ -0,0 +1,162 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "CoteVertu.h" +#include + +CCoteVertuStation::CCoteVertuStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = COTEVERTU_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = COTEVERTU_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = COTEVERTU_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = COTEVERTU_STATION_KEY; + //Initialize mask structures + // + + + mStationInputMasks.InputZT1S1Mask = COTEVERTU_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = COTEVERTU_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = COTEVERTU_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = COTEVERTU_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = COTEVERTU_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = COTEVERTU_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = COTEVERTU_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = COTEVERTU_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = COTEVERTU_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = COTEVERTU_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = COTEVERTU_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = COTEVERTU_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = COTEVERTU_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = COTEVERTU_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = COTEVERTU_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = COTEVERTU_IN_CDV_11A_MASK; + mStationInputMasks.InputCDVZT1Mask = COTEVERTU_IN_CDV_11B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = COTEVERTU_IN_CDV_12B_MASK; + mStationInputMasks.InputCDVZT2Mask = COTEVERTU_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = COTEVERTU_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = COTEVERTU_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = COTEVERTU_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = COTEVERTU_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = COTEVERTU_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = COTEVERTU_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = COTEVERTU_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = COTEVERTU_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = COTEVERTU_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = COTEVERTU_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = COTEVERTU_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = COTEVERTU_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = COTEVERTU_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = COTEVERTU_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = COTEVERTU_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = COTEVERTU_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = COTEVERTU_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = COTEVERTU_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = COTEVERTU_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = COTEVERTU_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = COTEVERTU_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = COTEVERTU_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = COTEVERTU_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = COTEVERTU_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = COTEVERTU_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = COTEVERTU_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = COTEVERTU_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = COTEVERTU_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = COTEVERTU_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = COTEVERTU_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = COTEVERTU_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = COTEVERTU_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = COTEVERTU_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mTextualStationName = "Côte Vertu"; + mTextualShortName = "CVRT"; +} + +unsigned int CCoteVertuStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + + NewCDV = new CCDV(COTEVERTU_IN_ZT2_ITI_MASK,COTEVERTU_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(COTEVERTU_IN_ZT2_ITI_MASK,COTEVERTU_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(COTEVERTU_IN_ZT2_ITI_MASK,COTEVERTU_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(COTEVERTU_IN_ZT2_ITI_MASK,COTEVERTU_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A (ZT2)",1,3); + mZT2CDV = NewCDV; + mZT2ApproachCDV = NewCDV; //Approach = ZT2 CDV + mCDVList.append(NewCDV); + + NewCDV = new CCDV(COTEVERTU_IN_ZT1_ITI_MASK,COTEVERTU_IN_CDV_12B_MASK,CDV_NORMAL_TYPE,"12B",1,4); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + + NewCDV = new CCDV(COTEVERTU_IN_ZT1_ITI_MASK,COTEVERTU_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mZT1SubsequentCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + + NewCDV = new CCDV(COTEVERTU_IN_ZT1_ITI_MASK,COTEVERTU_IN_CDV_11B_MASK,CDV_NORMAL_TYPE,"11B (ZT1)",1,6); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(COTEVERTU_IN_ZT1_ITI_MASK,COTEVERTU_IN_CDV_11A_MASK,CDV_NORMAL_TYPE,"11A",1,7); + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(COTEVERTU_IN_ZT1_ITI_MASK,COTEVERTU_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B",1,8); + mCDVList.append(NewCDV); + + return RET_OK; +} diff --git a/sources/Stations/CoteVertu.h b/sources/Stations/CoteVertu.h new file mode 100644 index 0000000..a70eb70 --- /dev/null +++ b/sources/Stations/CoteVertu.h @@ -0,0 +1,118 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef COTEVERTU_H +#define COTEVERTU_H +#include "Station.h" + +#define COTEVERTU_STATION_KEY 0x0020000 +#define COTEVERTU_NB_EXTERNAL_INPUT_430_MODULES 1 +#define COTEVERTU_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define COTEVERTU_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define COTEVERTU_ZT1_S1_MASK 0x00000001 +#define COTEVERTU_ZT1_S2_MASK 0x00000002 +#define COTEVERTU_ZT1_PI_MASK 0x00000004 +#define COTEVERTU_ZT1_PE_MASK 0x00000008 +#define COTEVERTU_ZT1_FN_MASK 0x00000010 +#define COTEVERTU_ZT2_S1_MASK 0x00000020 +#define COTEVERTU_ZT2_PI_MASK 0x00000040 +#define COTEVERTU_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for Cote Vertu +#define COTEVERTU_IN_CDV_12A_MASK 0x00000001 +#define COTEVERTU_IN_CDV_12B_MASK 0x00000002 +#define COTEVERTU_IN_CDV_11B_MASK 0x00000004 +#define COTEVERTU_IN_CDV_11A_MASK 0x00000008 +#define COTEVERTU_IN_CDV_10B_MASK 0x00000010 +#define COTEVERTU_IN_CDV_13A_MASK 0x00000020 +#define COTEVERTU_IN_CDV_14A_MASK 0x00000040 +#define COTEVERTU_IN_CDV_13B_MASK 0x00000080 +#define COTEVERTU_IN_CDV_14B_MASK 0x00000100 +#define COTEVERTU_IN_ZT1_ITI_MASK 0x00000200 +#define COTEVERTU_IN_ZT2_ITI_MASK 0x00000400 +#define COTEVERTU_IN_ZT1_AN_MASK 0x00000800 +#define COTEVERTU_IN_ZT2_AN_MASK 0x00001000 +#define COTEVERTU_IN_ZT1_ARF_MASK 0x00002000 +#define COTEVERTU_IN_ZT2_ARF_MASK 0x00004000 +#define COTEVERTU_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for Cote Vertu +#define COTEVERTU_OUT_VP1_MASK 0x00000001 +#define COTEVERTU_OUT_VP2_MASK 0x00000002 +#define COTEVERTU_OUT_VP3_MASK 0x00000004 +#define COTEVERTU_OUT_VP4_MASK 0x00000008 +#define COTEVERTU_OUT_VP5_MASK 0x00000010 +#define COTEVERTU_OUT_VP6_MASK 0x00000020 +#define COTEVERTU_OUT_VF1_MASK 0x00000040 +#define COTEVERTU_OUT_VF2_MASK 0x00000080 +#define COTEVERTU_OUT_VF3_MASK 0x00000100 +#define COTEVERTU_OUT_VF4_MASK 0x00000200 +#define COTEVERTU_OUT_VF5_MASK 0x00000400 +#define COTEVERTU_OUT_WP1_MASK 0x00000800 +#define COTEVERTU_OUT_WP2_MASK 0x00001000 +#define COTEVERTU_OUT_WP3_MASK 0x00002000 +#define COTEVERTU_OUT_WP4_MASK 0x00004000 +#define COTEVERTU_OUT_WP5_MASK 0x00008000 +#define COTEVERTU_OUT_WP6_MASK 0x00010000 +#define COTEVERTU_OUT_DPE_MASK 0x00020000 +#define COTEVERTU_OUT_DPI_MASK 0x00040000 +#define COTEVERTU_OUT_V00_MASK 0x00080000 +#define COTEVERTU_OUT_DPG_MASK 0x00100000 +#define COTEVERTU_OUT_DFR_MASK 0x00200000 +#define COTEVERTU_OUT_RF_MASK 0x00400000 +#define COTEVERTU_OUT_RF2_MASK 0x00800000 +#define COTEVERTU_OUT_VEL_MASK 0x01000000 +#define COTEVERTU_OUT_VEL2_MASK 0x02000000 +#define COTEVERTU_OUT_DPI2_MASK 0x04000000 +#define COTEVERTU_OUT_DPE2_MASK 0x08000000 +#define COTEVERTU_OUT_V002_MASK 0x10000000 +#define COTEVERTU_OUT_PEQ1_MASK 0x20000000 +#define COTEVERTU_OUT_PEQ2_MASK 0x40000000 +#define COTEVERTU_OUT_WATCHDOG_MASK 0x80000000 + +#define COTEVERTU_SDF_ACQUISITION_CHANNEL 0 + +class CCoteVertuStation : public CStation +{ +public: + + CCoteVertuStation(); + + + +private: + + virtual unsigned int BuildStationCDVList(); +}; + +#endif // COTEVERTU_H + diff --git a/sources/Stations/HenriBourassa.cpp b/sources/Stations/HenriBourassa.cpp new file mode 100644 index 0000000..800f616 --- /dev/null +++ b/sources/Stations/HenriBourassa.cpp @@ -0,0 +1,155 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "HenriBourassa.h" +#include + +CHenriBourassaStation::CHenriBourassaStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = HENRIBOURASSA_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = HENRIBOURASSA_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = HENRIBOURASSA_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = HENRIBOURASSA_STATION_KEY; + + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = HENRIBOURASSA_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = HENRIBOURASSA_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = HENRIBOURASSA_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = HENRIBOURASSA_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = HENRIBOURASSA_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = HENRIBOURASSA_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = HENRIBOURASSA_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = HENRIBOURASSA_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = HENRIBOURASSA_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = HENRIBOURASSA_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = HENRIBOURASSA_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = HENRIBOURASSA_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = HENRIBOURASSA_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = HENRIBOURASSA_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = HENRIBOURASSA_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = HENRIBOURASSA_IN_CDV_11A_MASK; + mStationInputMasks.InputCDVZT1Mask = HENRIBOURASSA_IN_CDV_11B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = HENRIBOURASSA_IN_CDV_12BC_MASK; + mStationInputMasks.InputCDVZT2Mask = HENRIBOURASSA_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = HENRIBOURASSA_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = HENRIBOURASSA_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = HENRIBOURASSA_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = HENRIBOURASSA_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = HENRIBOURASSA_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = HENRIBOURASSA_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = HENRIBOURASSA_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = HENRIBOURASSA_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = HENRIBOURASSA_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = HENRIBOURASSA_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = HENRIBOURASSA_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = HENRIBOURASSA_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = HENRIBOURASSA_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = HENRIBOURASSA_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = HENRIBOURASSA_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = HENRIBOURASSA_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = HENRIBOURASSA_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = HENRIBOURASSA_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = HENRIBOURASSA_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = HENRIBOURASSA_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = HENRIBOURASSA_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = HENRIBOURASSA_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = HENRIBOURASSA_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = HENRIBOURASSA_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = HENRIBOURASSA_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = HENRIBOURASSA_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = HENRIBOURASSA_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = HENRIBOURASSA_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = HENRIBOURASSA_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = HENRIBOURASSA_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = HENRIBOURASSA_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = HENRIBOURASSA_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = HENRIBOURASSA_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mTextualStationName = "Henri Bourassa"; + mTextualShortName = "HBOU"; +} + + +unsigned int CHenriBourassaStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT2_ITI_MASK,HENRIBOURASSA_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT2_ITI_MASK,HENRIBOURASSA_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT2_ITI_MASK,HENRIBOURASSA_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT2_ITI_MASK,HENRIBOURASSA_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A (ZT2)",1,3); + mZT2CDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT1_ITI_MASK,HENRIBOURASSA_IN_CDV_12BC_MASK,CDV_NORMAL_TYPE,"12BC",1,4); + mCDVList.append(NewCDV); + mZT2ApproachCDV = NewCDV; + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT1_ITI_MASK,HENRIBOURASSA_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mZT1SubsequentCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT1_ITI_MASK,HENRIBOURASSA_IN_CDV_11B_MASK,CDV_NORMAL_TYPE,"11B (ZT1)",1,6); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT1_ITI_MASK,HENRIBOURASSA_IN_CDV_11A_MASK,CDV_NORMAL_TYPE,"11A",1,7); + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HENRIBOURASSA_IN_ZT1_ITI_MASK,HENRIBOURASSA_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B",1,8); + mCDVList.append(NewCDV); + + return RET_OK; +} diff --git a/sources/Stations/HenriBourassa.h b/sources/Stations/HenriBourassa.h new file mode 100644 index 0000000..288bef9 --- /dev/null +++ b/sources/Stations/HenriBourassa.h @@ -0,0 +1,118 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef HENRIBOURASSA_H +#define HENRIBOURASSA_H +#include "Station.h" + +#define HENRIBOURASSA_STATION_KEY 0x0018000 +#define HENRIBOURASSA_NB_EXTERNAL_INPUT_430_MODULES 1 +#define HENRIBOURASSA_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define HENRIBOURASSA_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define HENRIBOURASSA_ZT1_S1_MASK 0x00000001 +#define HENRIBOURASSA_ZT1_S2_MASK 0x00000002 +#define HENRIBOURASSA_ZT1_PI_MASK 0x00000004 +#define HENRIBOURASSA_ZT1_PE_MASK 0x00000008 +#define HENRIBOURASSA_ZT1_FN_MASK 0x00000010 +#define HENRIBOURASSA_ZT2_S1_MASK 0x00000020 +#define HENRIBOURASSA_ZT2_PI_MASK 0x00000040 +#define HENRIBOURASSA_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for HENRIBOURASSA +#define HENRIBOURASSA_IN_CDV_12A_MASK 0x00000001 +#define HENRIBOURASSA_IN_CDV_12BC_MASK 0x00000002 +#define HENRIBOURASSA_IN_CDV_11B_MASK 0x00000004 +#define HENRIBOURASSA_IN_CDV_11A_MASK 0x00000008 +#define HENRIBOURASSA_IN_CDV_10B_MASK 0x00000010 +#define HENRIBOURASSA_IN_CDV_13A_MASK 0x00000020 +#define HENRIBOURASSA_IN_CDV_14A_MASK 0x00000040 +#define HENRIBOURASSA_IN_CDV_13B_MASK 0x00000080 +#define HENRIBOURASSA_IN_CDV_14B_MASK 0x00000100 +#define HENRIBOURASSA_IN_ZT1_ITI_MASK 0x00000200 +#define HENRIBOURASSA_IN_ZT2_ITI_MASK 0x00000400 +#define HENRIBOURASSA_IN_ZT1_AN_MASK 0x00000800 +#define HENRIBOURASSA_IN_ZT2_AN_MASK 0x00001000 +#define HENRIBOURASSA_IN_ZT1_ARF_MASK 0x00002000 +#define HENRIBOURASSA_IN_ZT2_ARF_MASK 0x00004000 +#define HENRIBOURASSA_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for HENRIBOURASSA +#define HENRIBOURASSA_OUT_VP1_MASK 0x00000001 +#define HENRIBOURASSA_OUT_VP2_MASK 0x00000002 +#define HENRIBOURASSA_OUT_VP3_MASK 0x00000004 +#define HENRIBOURASSA_OUT_VP4_MASK 0x00000008 +#define HENRIBOURASSA_OUT_VP5_MASK 0x00000010 +#define HENRIBOURASSA_OUT_VP6_MASK 0x00000020 +#define HENRIBOURASSA_OUT_VF1_MASK 0x00000040 +#define HENRIBOURASSA_OUT_VF2_MASK 0x00000080 +#define HENRIBOURASSA_OUT_VF3_MASK 0x00000100 +#define HENRIBOURASSA_OUT_VF4_MASK 0x00000200 +#define HENRIBOURASSA_OUT_VF5_MASK 0x00000400 +#define HENRIBOURASSA_OUT_WP1_MASK 0x00000800 +#define HENRIBOURASSA_OUT_WP2_MASK 0x00001000 +#define HENRIBOURASSA_OUT_WP3_MASK 0x00002000 +#define HENRIBOURASSA_OUT_WP4_MASK 0x00004000 +#define HENRIBOURASSA_OUT_WP5_MASK 0x00008000 +#define HENRIBOURASSA_OUT_WP6_MASK 0x00010000 +#define HENRIBOURASSA_OUT_DPE_MASK 0x00020000 +#define HENRIBOURASSA_OUT_DPI_MASK 0x00040000 +#define HENRIBOURASSA_OUT_V00_MASK 0x00080000 +#define HENRIBOURASSA_OUT_DPG_MASK 0x00100000 +#define HENRIBOURASSA_OUT_DFR_MASK 0x00200000 +#define HENRIBOURASSA_OUT_RF_MASK 0x00400000 +#define HENRIBOURASSA_OUT_RF2_MASK 0x00800000 +#define HENRIBOURASSA_OUT_VEL_MASK 0x01000000 +#define HENRIBOURASSA_OUT_VEL2_MASK 0x02000000 +#define HENRIBOURASSA_OUT_DPI2_MASK 0x04000000 +#define HENRIBOURASSA_OUT_DPE2_MASK 0x08000000 +#define HENRIBOURASSA_OUT_V002_MASK 0x10000000 +#define HENRIBOURASSA_OUT_PEQ1_MASK 0x20000000 +#define HENRIBOURASSA_OUT_PEQ2_MASK 0x40000000 +#define HENRIBOURASSA_OUT_WATCHDOG_MASK 0x80000000 + +#define HENRIBOURASSA_SDF_ACQUISITION_CHANNEL 0 + +class CHenriBourassaStation : public CStation +{ +public: + + CHenriBourassaStation(); + + + +private: + + virtual unsigned int BuildStationCDVList(); +}; + +#endif // HENRIBOURASSA_H + diff --git a/sources/Stations/HonoreBeaugrand.cpp b/sources/Stations/HonoreBeaugrand.cpp new file mode 100644 index 0000000..5bfdc05 --- /dev/null +++ b/sources/Stations/HonoreBeaugrand.cpp @@ -0,0 +1,156 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "HonoreBeaugrand.h" +#include + +CHonoreBeaugrandStation::CHonoreBeaugrandStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = HONOREBEAUGRAND_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = HONOREBEAUGRAND_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = HONOREBEAUGRAND_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = HONOREBEAUGRAND_STATION_KEY; + + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = HONOREBEAUGRAND_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = HONOREBEAUGRAND_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = HONOREBEAUGRAND_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = HONOREBEAUGRAND_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = HONOREBEAUGRAND_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = HONOREBEAUGRAND_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = HONOREBEAUGRAND_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = HONOREBEAUGRAND_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = HONOREBEAUGRAND_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = HONOREBEAUGRAND_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = HONOREBEAUGRAND_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = HONOREBEAUGRAND_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = HONOREBEAUGRAND_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = HONOREBEAUGRAND_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = HONOREBEAUGRAND_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = HONOREBEAUGRAND_IN_CDV_11A_MASK; + mStationInputMasks.InputCDVZT1Mask = HONOREBEAUGRAND_IN_CDV_11B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = HONOREBEAUGRAND_IN_CDV_12BC_MASK; + mStationInputMasks.InputCDVZT2Mask = HONOREBEAUGRAND_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = HONOREBEAUGRAND_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = HONOREBEAUGRAND_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = HONOREBEAUGRAND_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = HONOREBEAUGRAND_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = HONOREBEAUGRAND_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = HONOREBEAUGRAND_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = HONOREBEAUGRAND_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = HONOREBEAUGRAND_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = HONOREBEAUGRAND_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = HONOREBEAUGRAND_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = HONOREBEAUGRAND_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = HONOREBEAUGRAND_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = HONOREBEAUGRAND_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = HONOREBEAUGRAND_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = HONOREBEAUGRAND_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = HONOREBEAUGRAND_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = HONOREBEAUGRAND_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = HONOREBEAUGRAND_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = HONOREBEAUGRAND_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = HONOREBEAUGRAND_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = HONOREBEAUGRAND_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = HONOREBEAUGRAND_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = HONOREBEAUGRAND_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = HONOREBEAUGRAND_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = HONOREBEAUGRAND_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = HONOREBEAUGRAND_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = HONOREBEAUGRAND_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = HONOREBEAUGRAND_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = HONOREBEAUGRAND_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = HONOREBEAUGRAND_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = HONOREBEAUGRAND_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = HONOREBEAUGRAND_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = HONOREBEAUGRAND_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mTextualStationName = "Honoré Beaugrand"; + mTextualShortName = "HBGR"; +} + + +unsigned int CHonoreBeaugrandStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT2_ITI_MASK,HONOREBEAUGRAND_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT2_ITI_MASK,HONOREBEAUGRAND_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT2_ITI_MASK,HONOREBEAUGRAND_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT2_ITI_MASK,HONOREBEAUGRAND_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A (ZT2)",1,3); + mZT2CDV = NewCDV; + mZT2ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT1_ITI_MASK,HONOREBEAUGRAND_IN_CDV_12BC_MASK,CDV_NORMAL_TYPE,"12BC",1,4); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT1_ITI_MASK,HONOREBEAUGRAND_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mZT1SubsequentCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT1_ITI_MASK,HONOREBEAUGRAND_IN_CDV_11B_MASK,CDV_NORMAL_TYPE,"11B (ZT1)",1,6); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT1_ITI_MASK,HONOREBEAUGRAND_IN_CDV_11A_MASK,CDV_NORMAL_TYPE,"11A",1,7); + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(HONOREBEAUGRAND_IN_ZT1_ITI_MASK,HONOREBEAUGRAND_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B",1,8); + mCDVList.append(NewCDV); + + return RET_OK; +} diff --git a/sources/Stations/HonoreBeaugrand.h b/sources/Stations/HonoreBeaugrand.h new file mode 100644 index 0000000..ccce9cb --- /dev/null +++ b/sources/Stations/HonoreBeaugrand.h @@ -0,0 +1,118 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef HONOREBEAUGRAND_H +#define HONOREBEAUGRAND_H +#include "Station.h" + +#define HONOREBEAUGRAND_STATION_KEY 0x0008000 +#define HONOREBEAUGRAND_NB_EXTERNAL_INPUT_430_MODULES 1 +#define HONOREBEAUGRAND_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define HONOREBEAUGRAND_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define HONOREBEAUGRAND_ZT1_S1_MASK 0x00000001 +#define HONOREBEAUGRAND_ZT1_S2_MASK 0x00000002 +#define HONOREBEAUGRAND_ZT1_PI_MASK 0x00000004 +#define HONOREBEAUGRAND_ZT1_PE_MASK 0x00000008 +#define HONOREBEAUGRAND_ZT1_FN_MASK 0x00000010 +#define HONOREBEAUGRAND_ZT2_S1_MASK 0x00000020 +#define HONOREBEAUGRAND_ZT2_PI_MASK 0x00000040 +#define HONOREBEAUGRAND_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for HONOREBEAUGRAND +#define HONOREBEAUGRAND_IN_CDV_12A_MASK 0x00000001 +#define HONOREBEAUGRAND_IN_CDV_12BC_MASK 0x00000002 +#define HONOREBEAUGRAND_IN_CDV_11B_MASK 0x00000004 +#define HONOREBEAUGRAND_IN_CDV_11A_MASK 0x00000008 +#define HONOREBEAUGRAND_IN_CDV_10B_MASK 0x00000010 +#define HONOREBEAUGRAND_IN_CDV_13A_MASK 0x00000020 +#define HONOREBEAUGRAND_IN_CDV_14A_MASK 0x00000040 +#define HONOREBEAUGRAND_IN_CDV_13B_MASK 0x00000080 +#define HONOREBEAUGRAND_IN_CDV_14B_MASK 0x00000100 +#define HONOREBEAUGRAND_IN_ZT1_ITI_MASK 0x00000200 +#define HONOREBEAUGRAND_IN_ZT2_ITI_MASK 0x00000400 +#define HONOREBEAUGRAND_IN_ZT1_AN_MASK 0x00000800 +#define HONOREBEAUGRAND_IN_ZT2_AN_MASK 0x00001000 +#define HONOREBEAUGRAND_IN_ZT1_ARF_MASK 0x00002000 +#define HONOREBEAUGRAND_IN_ZT2_ARF_MASK 0x00004000 +#define HONOREBEAUGRAND_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for HONOREBEAUGRAND +#define HONOREBEAUGRAND_OUT_VP1_MASK 0x00000001 +#define HONOREBEAUGRAND_OUT_VP2_MASK 0x00000002 +#define HONOREBEAUGRAND_OUT_VP3_MASK 0x00000004 +#define HONOREBEAUGRAND_OUT_VP4_MASK 0x00000008 +#define HONOREBEAUGRAND_OUT_VP5_MASK 0x00000010 +#define HONOREBEAUGRAND_OUT_VP6_MASK 0x00000020 +#define HONOREBEAUGRAND_OUT_VF1_MASK 0x00000040 +#define HONOREBEAUGRAND_OUT_VF2_MASK 0x00000080 +#define HONOREBEAUGRAND_OUT_VF3_MASK 0x00000100 +#define HONOREBEAUGRAND_OUT_VF4_MASK 0x00000200 +#define HONOREBEAUGRAND_OUT_VF5_MASK 0x00000400 +#define HONOREBEAUGRAND_OUT_WP1_MASK 0x00000800 +#define HONOREBEAUGRAND_OUT_WP2_MASK 0x00001000 +#define HONOREBEAUGRAND_OUT_WP3_MASK 0x00002000 +#define HONOREBEAUGRAND_OUT_WP4_MASK 0x00004000 +#define HONOREBEAUGRAND_OUT_WP5_MASK 0x00008000 +#define HONOREBEAUGRAND_OUT_WP6_MASK 0x00010000 +#define HONOREBEAUGRAND_OUT_DPE_MASK 0x00020000 +#define HONOREBEAUGRAND_OUT_DPI_MASK 0x00040000 +#define HONOREBEAUGRAND_OUT_V00_MASK 0x00080000 +#define HONOREBEAUGRAND_OUT_DPG_MASK 0x00100000 +#define HONOREBEAUGRAND_OUT_DFR_MASK 0x00200000 +#define HONOREBEAUGRAND_OUT_RF_MASK 0x00400000 +#define HONOREBEAUGRAND_OUT_RF2_MASK 0x00800000 +#define HONOREBEAUGRAND_OUT_VEL_MASK 0x01000000 +#define HONOREBEAUGRAND_OUT_VEL2_MASK 0x02000000 +#define HONOREBEAUGRAND_OUT_DPI2_MASK 0x04000000 +#define HONOREBEAUGRAND_OUT_DPE2_MASK 0x08000000 +#define HONOREBEAUGRAND_OUT_V002_MASK 0x10000000 +#define HONOREBEAUGRAND_OUT_PEQ1_MASK 0x20000000 +#define HONOREBEAUGRAND_OUT_PEQ2_MASK 0x40000000 +#define HONOREBEAUGRAND_OUT_WATCHDOG_MASK 0x80000000 + +#define HONOREBEAUGRAND_SDF_ACQUISITION_CHANNEL 0 + +class CHonoreBeaugrandStation : public CStation +{ +public: + + CHonoreBeaugrandStation(); + + + +private: + + virtual unsigned int BuildStationCDVList(); +}; + +#endif // HONOREBEAUGRAND_H + diff --git a/sources/Stations/Longueuil.cpp b/sources/Stations/Longueuil.cpp new file mode 100644 index 0000000..4775cfe --- /dev/null +++ b/sources/Stations/Longueuil.cpp @@ -0,0 +1,164 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Longueuil.h" +#include + +CLongueuilStation::CLongueuilStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = LONGUEUIL_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = LONGUEUIL_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = LONGUEUIL_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = LONGUEUIL_STATION_KEY; + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = LONGUEUIL_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = LONGUEUIL_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = LONGUEUIL_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = LONGUEUIL_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = LONGUEUIL_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = LONGUEUIL_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = LONGUEUIL_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = LONGUEUIL_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = LONGUEUIL_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = LONGUEUIL_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = LONGUEUIL_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = LONGUEUIL_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = LONGUEUIL_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = LONGUEUIL_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = LONGUEUIL_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = LONGUEUIL_IN_CDV_10B_MASK; + mStationInputMasks.InputCDVZT1Mask = LONGUEUIL_IN_CDV_11_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = LONGUEUIL_IN_CDV_12B_MASK; + mStationInputMasks.InputCDVZT2Mask = LONGUEUIL_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = LONGUEUIL_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = LONGUEUIL_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = LONGUEUIL_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = LONGUEUIL_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = LONGUEUIL_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = LONGUEUIL_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = LONGUEUIL_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = LONGUEUIL_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = LONGUEUIL_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = LONGUEUIL_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = LONGUEUIL_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = LONGUEUIL_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = LONGUEUIL_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = LONGUEUIL_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = LONGUEUIL_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = LONGUEUIL_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = LONGUEUIL_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = LONGUEUIL_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = LONGUEUIL_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = LONGUEUIL_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = LONGUEUIL_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = LONGUEUIL_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = LONGUEUIL_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = LONGUEUIL_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = LONGUEUIL_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = LONGUEUIL_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = LONGUEUIL_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = LONGUEUIL_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = LONGUEUIL_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = LONGUEUIL_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = LONGUEUIL_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = LONGUEUIL_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = LONGUEIL_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mTextualStationName = "Longueuil"; + mTextualShortName = "LONG"; +} + +unsigned int CLongueuilStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT2_ITI_MASK,LONGUEUIL_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT2_ITI_MASK,LONGUEUIL_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT2_ITI_MASK,LONGUEUIL_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT2_ITI_MASK,LONGUEUIL_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A (ZT2)",1,3); + mZT2CDV = NewCDV; + mZT2ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT1_ITI_MASK,LONGUEUIL_IN_CDV_12B_MASK,CDV_NORMAL_TYPE,"12B",1,4); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT1_ITI_MASK,LONGUEUIL_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mZT1SubsequentCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT1_ITI_MASK,LONGUEUIL_IN_CDV_11_MASK,CDV_NORMAL_TYPE,"11 (ZT1)",1,6); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(LONGUEUIL_IN_ZT1_ITI_MASK,LONGUEUIL_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B",1,7); + mCDVList.append(NewCDV); + mCDV10B = NewCDV; + + NewCDV = new CCDV(LONGUEUIL_IN_ZT1_ITI_MASK,LONGUEUIL_IN_CDV_10A_MASK,CDV_NORMAL_TYPE,"10A",1,8); + mCDVList.append(NewCDV); + mZT1ApproachCDV = NewCDV; //The approach CDV is the n-3 because CDV 10B and 11 are merged as the ZT1 cdv. + + return RET_OK; +} + +bool CLongueuilStation::IsZT1CDVOccupied() +{ + if(mZT1CDV->IsOccupied() || mCDV10B->IsOccupied()) + { + return true; + } + + return false; +} diff --git a/sources/Stations/Longueuil.h b/sources/Stations/Longueuil.h new file mode 100644 index 0000000..4f5fc27 --- /dev/null +++ b/sources/Stations/Longueuil.h @@ -0,0 +1,119 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef LONGUEUIL_H +#define LONGUEUIL_H +#include "Station.h" + +#define LONGUEUIL_STATION_KEY 0x0030000 +#define LONGUEUIL_NB_EXTERNAL_INPUT_430_MODULES 1 +#define LONGUEUIL_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define LONGUEUIL_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define LONGUEUIL_ZT1_S1_MASK 0x00000001 +#define LONGUEUIL_ZT1_S2_MASK 0x00000002 +#define LONGUEUIL_ZT1_PI_MASK 0x00000004 +#define LONGUEUIL_ZT1_PE_MASK 0x00000008 +#define LONGUEUIL_ZT1_FN_MASK 0x00000010 +#define LONGUEUIL_ZT2_S1_MASK 0x00000020 +#define LONGUEUIL_ZT2_PI_MASK 0x00000040 +#define LONGUEUIL_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for LONGUEUIL +#define LONGUEUIL_IN_CDV_12A_MASK 0x00000001 +#define LONGUEUIL_IN_CDV_12B_MASK 0x00000002 +#define LONGUEUIL_IN_CDV_11_MASK 0x00000004 +#define LONGUEUIL_IN_CDV_10B_MASK 0x00000008 +#define LONGUEUIL_IN_CDV_10A_MASK 0x00000010 +#define LONGUEUIL_IN_CDV_13A_MASK 0x00000020 +#define LONGUEUIL_IN_CDV_14A_MASK 0x00000040 +#define LONGUEUIL_IN_CDV_13B_MASK 0x00000080 +#define LONGUEUIL_IN_CDV_14B_MASK 0x00000100 +#define LONGUEUIL_IN_ZT1_ITI_MASK 0x00000200 +#define LONGUEUIL_IN_ZT2_ITI_MASK 0x00000400 +#define LONGUEUIL_IN_ZT1_AN_MASK 0x00000800 +#define LONGUEUIL_IN_ZT2_AN_MASK 0x00001000 +#define LONGUEUIL_IN_ZT1_ARF_MASK 0x00002000 +#define LONGUEUIL_IN_ZT2_ARF_MASK 0x00004000 +#define LONGUEUIL_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for LONGUEUIL +#define LONGUEUIL_OUT_VP1_MASK 0x00000001 +#define LONGUEUIL_OUT_VP2_MASK 0x00000002 +#define LONGUEUIL_OUT_VP3_MASK 0x00000004 +#define LONGUEUIL_OUT_VP4_MASK 0x00000008 +#define LONGUEUIL_OUT_VP5_MASK 0x00000010 +#define LONGUEUIL_OUT_VP6_MASK 0x00000020 +#define LONGUEUIL_OUT_VF1_MASK 0x00000040 +#define LONGUEUIL_OUT_VF2_MASK 0x00000080 +#define LONGUEUIL_OUT_VF3_MASK 0x00000100 +#define LONGUEUIL_OUT_VF4_MASK 0x00000200 +#define LONGUEUIL_OUT_VF5_MASK 0x00000400 +#define LONGUEUIL_OUT_WP1_MASK 0x00000800 +#define LONGUEUIL_OUT_WP2_MASK 0x00001000 +#define LONGUEUIL_OUT_WP3_MASK 0x00002000 +#define LONGUEUIL_OUT_WP4_MASK 0x00004000 +#define LONGUEUIL_OUT_WP5_MASK 0x00008000 +#define LONGUEUIL_OUT_WP6_MASK 0x00010000 +#define LONGUEUIL_OUT_DPE_MASK 0x00020000 +#define LONGUEUIL_OUT_DPI_MASK 0x00040000 +#define LONGUEUIL_OUT_V00_MASK 0x00080000 +#define LONGUEUIL_OUT_DPG_MASK 0x00100000 +#define LONGUEUIL_OUT_DFR_MASK 0x00200000 +#define LONGUEUIL_OUT_RF_MASK 0x00400000 +#define LONGUEUIL_OUT_RF2_MASK 0x00800000 +#define LONGUEUIL_OUT_VEL_MASK 0x01000000 +#define LONGUEUIL_OUT_VEL2_MASK 0x02000000 +#define LONGUEUIL_OUT_DPI2_MASK 0x04000000 +#define LONGUEUIL_OUT_DPE2_MASK 0x08000000 +#define LONGUEUIL_OUT_V002_MASK 0x10000000 +#define LONGUEUIL_OUT_PEQ1_MASK 0x20000000 +#define LONGUEUIL_OUT_PEQ2_MASK 0x40000000 +#define LONGUEUIL_OUT_WATCHDOG_MASK 0x80000000 + +#define LONGUEIL_SDF_ACQUISITION_CHANNEL 0 + +class CLongueuilStation : public CStation +{ +public: + + CLongueuilStation(); + virtual bool IsZT1CDVOccupied(); + + + +private: + virtual unsigned int BuildStationCDVList(); + CCDV *mCDV10B; +}; + +#endif // LONGUEUIL_H + diff --git a/sources/Stations/Montmorency.cpp b/sources/Stations/Montmorency.cpp new file mode 100644 index 0000000..0a3e1d9 --- /dev/null +++ b/sources/Stations/Montmorency.cpp @@ -0,0 +1,219 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Montmorency.h" +#include +#include "SwitchCDV.h" + +CMontmorencyStation::CMontmorencyStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = MONTMORENCY_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = MONTMORENCY_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = MONTMORENCY_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = MONTMORENCY_STATION_KEY; + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = MONTMORENCY_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = MONTMORENCY_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = MONTMORENCY_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = MONTMORENCY_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = MONTMORENCY_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = MONTMORENCY_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = MONTMORENCY_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = MONTMORENCY_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = MONTMORENCY_IN_ZT1_10_12_ITI_MASK; + mStationInputMasks.InputZT1_AltITIMask = MONTMORENCY_IN_ZT1_10_22_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = MONTMORENCY_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = MONTMORENCY_IN_10_12_AN1_MASK; + mStationInputMasks.InputZT2ANMask = MONTMORENCY_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = MONTMORENCY_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = MONTMORENCY_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = MONTMORENCY_IN_STATION_ID_MASK; + + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = MONTMORENCY_IN_CDV_11A_MASK; + mStationInputMasks.InputCDVZT1Mask = MONTMORENCY_IN_CDV_11B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = MONTMORENCY_IN_CDV_12BC_MASK; + mStationInputMasks.InputCDVZT2Mask = MONTMORENCY_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = MONTMORENCY_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = MONTMORENCY_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = MONTMORENCY_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = MONTMORENCY_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = MONTMORENCY_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = MONTMORENCY_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = MONTMORENCY_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = MONTMORENCY_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = MONTMORENCY_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = MONTMORENCY_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = MONTMORENCY_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = MONTMORENCY_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = MONTMORENCY_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = MONTMORENCY_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = MONTMORENCY_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = MONTMORENCY_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = MONTMORENCY_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = MONTMORENCY_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = MONTMORENCY_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = MONTMORENCY_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = MONTMORENCY_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = MONTMORENCY_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = MONTMORENCY_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = MONTMORENCY_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = MONTMORENCY_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = MONTMORENCY_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = MONTMORENCY_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = MONTMORENCY_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = MONTMORENCY_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = MONTMORENCY_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = MONTMORENCY_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = MONTMORENCY_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = MONTMORENCY_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mCurZT1Itinerary = MONTMORENCY_ZT1_NO_ITINERARY; + mTextualStationName = "Montmorency"; + mTextualShortName = "MMO"; +} + +unsigned int CMontmorencyStation::UpdateStationMasks(unsigned int ExtInputData) +{ + mStationInputMasks.InputZT1_StdITIMask = MONTMORENCY_IN_ZT1_10_12_ITI_MASK; + if((MONTMORENCY_IN_ZT1_10_12_ITI_MASK & ExtInputData) != 0) + { + if(mCurZT1Itinerary != MONTMORENCY_ZT1_10_12_ITINERARY) + { //Assign masks relative to 10/12 itinerary + mStationInputMasks.InputZT1ITIMask = MONTMORENCY_IN_ZT1_10_12_ITI_MASK; + mStationInputMasks.InputZT1ANMask = MONTMORENCY_IN_10_12_AN1_MASK; + mCurZT1Itinerary = MONTMORENCY_ZT1_10_12_ITINERARY; + mZT1AlarmAutoAcquireCDV = m10_12AlarmAutoAcquireCDV; + mZT1SubsequentCDV = m10_12SubsequentCDV; + qDebug("Itinéraire 10/12 configuré"); + } + + } + else if((MONTMORENCY_IN_ZT1_10_22_ITI_MASK & ExtInputData) != 0) + { + if(mCurZT1Itinerary != MONTMORENCY_ZT1_10_22_ITINERARY) + { //Assign masks relative to 10/22 itinerary + mStationInputMasks.InputZT1ITIMask = MONTMORENCY_IN_ZT1_10_22_ITI_MASK; + mStationInputMasks.InputZT1ANMask = MONTMORENCY_IN_10_22_AN1_MASK; + mCurZT1Itinerary = MONTMORENCY_ZT1_10_22_ITINERARY; + mZT1AlarmAutoAcquireCDV = m10_22AlarmAutoAcquireCDV; + mZT1SubsequentCDV = m10_22SubsequentCDV; + qDebug("Itinéraire 10/22 configuré"); + } + } + else + { + mCurZT1Itinerary = MONTMORENCY_ZT1_NO_ITINERARY; + } + + return RET_OK; +} + +unsigned int CMontmorencyStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT2_ITI_MASK,MONTMORENCY_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT2_ITI_MASK,MONTMORENCY_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT2_ITI_MASK,MONTMORENCY_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT2_ITI_MASK,MONTMORENCY_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A ZT2",1,3); + mZT2CDV = NewCDV; + mZT2ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT1_10_12_ITI_MASK,MONTMORENCY_IN_CDV_12BC_MASK,CDV_NORMAL_TYPE,"12BC",1,4); + mCDVList.append(NewCDV); + m10_12AlarmAutoAcquireCDV = NewCDV; //Memorize it... + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT1_10_12_ITI_MASK,MONTMORENCY_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT1_10_12_ITI_MASK,MONTMORENCY_IN_CDV_11B_MASK,CDV_NORMAL_TYPE,"11B",1,6); + mCDVList.append(NewCDV); + + CSwitchCDV *NewSwitchCDV = new CSwitchCDV(MONTMORENCY_IN_ZT1_10_12_ITI_MASK,MONTMORENCY_IN_ZT1_10_22_ITI_MASK,MONTMORENCY_IN_CDV_11A_MASK,CDV_SWITCH_TYPE,"11A",1,7); + mCDVList.append((CCDV*)NewSwitchCDV); + mZT1SubsequentCDV = (CCDV*)NewSwitchCDV; + m10_12SubsequentCDV = NewSwitchCDV; + + NewCDV = new CCDV(MONTMORENCY_IN_ZT1_10_12_ITI_MASK | MONTMORENCY_IN_ZT1_10_22_ITI_MASK,MONTMORENCY_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B ZT1",1,8); + mZT1CDV = NewCDV; + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT1_10_22_ITI_MASK,MONTMORENCY_IN_CDV_22BC_MASK,CDV_NORMAL_TYPE,"22BC",2,4); + mCDVList.append(NewCDV); + m10_22AlarmAutoAcquireCDV = NewCDV; //Memorize it. + + + NewCDV = new CCDV(MONTMORENCY_IN_ZT1_10_22_ITI_MASK,MONTMORENCY_IN_CDV_22A_MASK,CDV_NORMAL_TYPE,"22A",2,5); + + mCDVList.append(NewCDV); + + +// NewSwitchCDV = new CSwitchCDV(0,MONTMORENCY_IN_ZT1_10_22_ITI_MASK,MONTMORENCY_IN_CDV_21BC_MASK,CDV_SWITCH_TYPE,"21BC",2,6); +// mCDVList.append((CCDV*)NewSwitchCDV); + + NewCDV = new CCDV(MONTMORENCY_IN_ZT1_10_22_ITI_MASK,MONTMORENCY_IN_CDV_21BC_MASK,CDV_NORMAL_TYPE,"21B",2,6); + mCDVList.append(NewCDV); + m10_22SubsequentCDV = NewCDV; + + + + return RET_OK; +} + +GenericInputMasks_t *CMontmorencyStation::GetInputMasks(void) +{ + return &mStationInputMasks; +} diff --git a/sources/Stations/Montmorency.h b/sources/Stations/Montmorency.h new file mode 100644 index 0000000..10de06b --- /dev/null +++ b/sources/Stations/Montmorency.h @@ -0,0 +1,133 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef MONTMORENCY_H +#define MONTMORENCY_H +#include "Station.h" + +#define MONTMORENCY_STATION_KEY 0x0048000 +#define MONTMORENCY_NB_EXTERNAL_INPUT_430_MODULES 1 +#define MONTMORENCY_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define MONTMORENCY_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define MONTMORENCY_ZT1_S1_MASK 0x00000001 +#define MONTMORENCY_ZT1_S2_MASK 0x00000002 +#define MONTMORENCY_ZT1_PI_MASK 0x00000004 +#define MONTMORENCY_ZT1_PE_MASK 0x00000008 +#define MONTMORENCY_ZT1_FN_MASK 0x00000010 +#define MONTMORENCY_ZT2_S1_MASK 0x00000020 +#define MONTMORENCY_ZT2_PI_MASK 0x00000040 +#define MONTMORENCY_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for MONTMORENCY +#define MONTMORENCY_IN_CDV_12A_MASK 0x00000001 +#define MONTMORENCY_IN_CDV_12BC_MASK 0x00000002 +#define MONTMORENCY_IN_CDV_11B_MASK 0x00000004 +#define MONTMORENCY_IN_CDV_11A_MASK 0x00000008 +#define MONTMORENCY_IN_CDV_10B_MASK 0x00000010 +#define MONTMORENCY_IN_CDV_13A_MASK 0x00000020 +#define MONTMORENCY_IN_CDV_14A_MASK 0x00000040 +#define MONTMORENCY_IN_CDV_13B_MASK 0x00000080 +#define MONTMORENCY_IN_CDV_14B_MASK 0x00000100 +#define MONTMORENCY_IN_ZT1_10_12_ITI_MASK 0x00000200 +#define MONTMORENCY_IN_ZT2_ITI_MASK 0x00000400 +#define MONTMORENCY_IN_10_12_AN1_MASK 0x00000800 +#define MONTMORENCY_IN_ZT2_AN_MASK 0x00001000 +#define MONTMORENCY_IN_ZT1_ARF_MASK 0x00002000 +#define MONTMORENCY_IN_ZT2_ARF_MASK 0x00004000 +#define MONTMORENCY_IN_STATION_ID_MASK 0x00078000 +#define MONTMORENCY_IN_CDV_21BC_MASK 0x00080000 +#define MONTMORENCY_IN_CDV_22A_MASK 0x00100000 +#define MONTMORENCY_IN_CDV_22BC_MASK 0x00200000 +#define MONTMORENCY_IN_10_22_AN1_MASK 0x00400000 +#define MONTMORENCY_IN_ZT1_10_22_ITI_MASK 0x00800000 + +//External (ethernet) output module masks for MONTMORENCY +#define MONTMORENCY_OUT_VP1_MASK 0x00000001 +#define MONTMORENCY_OUT_VP2_MASK 0x00000002 +#define MONTMORENCY_OUT_VP3_MASK 0x00000004 +#define MONTMORENCY_OUT_VP4_MASK 0x00000008 +#define MONTMORENCY_OUT_VP5_MASK 0x00000010 +#define MONTMORENCY_OUT_VP6_MASK 0x00000020 +#define MONTMORENCY_OUT_VF1_MASK 0x00000040 +#define MONTMORENCY_OUT_VF2_MASK 0x00000080 +#define MONTMORENCY_OUT_VF3_MASK 0x00000100 +#define MONTMORENCY_OUT_VF4_MASK 0x00000200 +#define MONTMORENCY_OUT_VF5_MASK 0x00000400 +#define MONTMORENCY_OUT_WP1_MASK 0x00000800 +#define MONTMORENCY_OUT_WP2_MASK 0x00001000 +#define MONTMORENCY_OUT_WP3_MASK 0x00002000 +#define MONTMORENCY_OUT_WP4_MASK 0x00004000 +#define MONTMORENCY_OUT_WP5_MASK 0x00008000 +#define MONTMORENCY_OUT_WP6_MASK 0x00010000 +#define MONTMORENCY_OUT_DPE_MASK 0x00020000 +#define MONTMORENCY_OUT_DPI_MASK 0x00040000 +#define MONTMORENCY_OUT_V00_MASK 0x00080000 +#define MONTMORENCY_OUT_DPG_MASK 0x00100000 +#define MONTMORENCY_OUT_DFR_MASK 0x00200000 +#define MONTMORENCY_OUT_RF_MASK 0x00400000 +#define MONTMORENCY_OUT_RF2_MASK 0x00800000 +#define MONTMORENCY_OUT_VEL_MASK 0x01000000 +#define MONTMORENCY_OUT_VEL2_MASK 0x02000000 +#define MONTMORENCY_OUT_DPI2_MASK 0x04000000 +#define MONTMORENCY_OUT_DPE2_MASK 0x08000000 +#define MONTMORENCY_OUT_V002_MASK 0x10000000 +#define MONTMORENCY_OUT_PEQ1_MASK 0x20000000 +#define MONTMORENCY_OUT_PEQ2_MASK 0x40000000 +#define MONTMORENCY_OUT_WATCHDOG_MASK 0x80000000 + +#define MONTMORENCY_SDF_ACQUISITION_CHANNEL 0 + +class CMontmorencyStation : public CStation +{ +public: + + CMontmorencyStation(); + virtual GenericInputMasks_t *GetInputMasks(void); + virtual unsigned int UpdateStationMasks(unsigned int ExtInputData); + + +private: + virtual unsigned int BuildStationCDVList(); + int mCurZT1Itinerary; + CCDV *m10_12AlarmAutoAcquireCDV, *m10_22AlarmAutoAcquireCDV; + CCDV *m10_12SubsequentCDV, *m10_22SubsequentCDV; + + enum eMontmorencyZT1Itineraries + { + MONTMORENCY_ZT1_10_12_ITINERARY, + MONTMORENCY_ZT1_10_22_ITINERARY, + MONTMORENCY_ZT1_NO_ITINERARY + }; +}; + +#endif // MONTMORENCY_H + diff --git a/sources/Stations/Montmorency1012.cpp b/sources/Stations/Montmorency1012.cpp new file mode 100644 index 0000000..a635823 --- /dev/null +++ b/sources/Stations/Montmorency1012.cpp @@ -0,0 +1,161 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Montmorency1012.h" +#include +#include "SwitchCDV.h" + +CMontmorency1012Station::CMontmorency1012Station() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = MONTMORENCY1012_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = MONTMORENCY1012_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = MONTMORENCY1012_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = MONTMORENCY1012_STATION_KEY; + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = MONTMORENCY1012_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = MONTMORENCY1012_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = MONTMORENCY1012_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = MONTMORENCY1012_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = MONTMORENCY1012_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = MONTMORENCY1012_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = MONTMORENCY1012_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = MONTMORENCY1012_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = MONTMORENCY1012_IN_ZT1_ITI_MASK; +// mStationInputMasks.InputZT1ITIMask = MONTMORENCY1012_IN_ZT1_10_22_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = MONTMORENCY1012_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = MONTMORENCY1012_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = MONTMORENCY1012_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = MONTMORENCY1012_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = MONTMORENCY1012_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = MONTMORENCY1012_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = MONTMORENCY1012_IN_CDV_10B_MASK; + mStationInputMasks.InputCDVZT1Mask = MONTMORENCY1012_IN_CDV_10B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = MONTMORENCY1012_IN_CDV_12BC_MASK; + mStationInputMasks.InputCDVZT2Mask = MONTMORENCY1012_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = MONTMORENCY1012_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = MONTMORENCY1012_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = MONTMORENCY1012_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = MONTMORENCY1012_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = MONTMORENCY1012_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = MONTMORENCY1012_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = MONTMORENCY1012_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = MONTMORENCY1012_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = MONTMORENCY1012_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = MONTMORENCY1012_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = MONTMORENCY1012_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = MONTMORENCY1012_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = MONTMORENCY1012_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = MONTMORENCY1012_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = MONTMORENCY1012_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = MONTMORENCY1012_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = MONTMORENCY1012_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = MONTMORENCY1012_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = MONTMORENCY1012_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = MONTMORENCY1012_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = MONTMORENCY1012_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = MONTMORENCY1012_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = MONTMORENCY1012_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = MONTMORENCY1012_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = MONTMORENCY1012_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = MONTMORENCY1012_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = MONTMORENCY1012_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = MONTMORENCY1012_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = MONTMORENCY1012_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = MONTMORENCY1012_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = MONTMORENCY1012_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = MONTMORENCY1012_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = MONTMORENCY1012_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mTextualStationName = "Montmorency (10/12)"; + mTextualShortName = "MMO"; +} + +unsigned int CMontmorency1012Station::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT2_ITI_MASK,MONTMORENCY1012_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT2_ITI_MASK,MONTMORENCY1012_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT2_ITI_MASK,MONTMORENCY1012_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT2_ITI_MASK,MONTMORENCY1012_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A ZT2",1,3); + mZT2CDV = NewCDV; + mZT2ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT1_ITI_MASK,MONTMORENCY1012_IN_CDV_12BC_MASK,CDV_NORMAL_TYPE,"12BC",1,4); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT1_ITI_MASK,MONTMORENCY1012_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT1_ITI_MASK,MONTMORENCY1012_IN_CDV_11B_MASK,CDV_NORMAL_TYPE,"11B",1,6); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT1_ITI_MASK,MONTMORENCY1012_IN_CDV_11A_MASK,CDV_NORMAL_TYPE,"11A",1,7); + mCDVList.append(NewCDV); + mZT1SubsequentCDV = NewCDV; + + NewCDV = new CCDV(MONTMORENCY1012_IN_ZT1_ITI_MASK,MONTMORENCY1012_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B ZT1",1,8); + mZT1CDV = NewCDV; + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + return RET_OK; +} + +//bool CMontmorency1012Station::IsZT1ApproachCDVOccupied() +//{ +// //Puisqu'il n'y a pas de CDV d'approche ZT1 à Montmorency, on doit simuler un train sur ce dernier. +// return true; +//} diff --git a/sources/Stations/Montmorency1012.h b/sources/Stations/Montmorency1012.h new file mode 100644 index 0000000..3ca873f --- /dev/null +++ b/sources/Stations/Montmorency1012.h @@ -0,0 +1,116 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef MONTMORENCY1012_H +#define MONTMORENCY1012_H +#include "Station.h" + +#define MONTMORENCY1012_STATION_KEY 0x0048000 +#define MONTMORENCY1012_NB_EXTERNAL_INPUT_430_MODULES 1 +#define MONTMORENCY1012_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define MONTMORENCY1012_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define MONTMORENCY1012_ZT1_S1_MASK 0x00000001 +#define MONTMORENCY1012_ZT1_S2_MASK 0x00000002 +#define MONTMORENCY1012_ZT1_PI_MASK 0x00000004 +#define MONTMORENCY1012_ZT1_PE_MASK 0x00000008 +#define MONTMORENCY1012_ZT1_FN_MASK 0x00000010 +#define MONTMORENCY1012_ZT2_S1_MASK 0x00000020 +#define MONTMORENCY1012_ZT2_PI_MASK 0x00000040 +#define MONTMORENCY1012_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for MONTMORENCY +#define MONTMORENCY1012_IN_CDV_12A_MASK 0x00000001 +#define MONTMORENCY1012_IN_CDV_12BC_MASK 0x00000002 +#define MONTMORENCY1012_IN_CDV_11B_MASK 0x00000004 +#define MONTMORENCY1012_IN_CDV_11A_MASK 0x00000008 +#define MONTMORENCY1012_IN_CDV_10B_MASK 0x00000010 +#define MONTMORENCY1012_IN_CDV_13A_MASK 0x00000020 +#define MONTMORENCY1012_IN_CDV_14A_MASK 0x00000040 +#define MONTMORENCY1012_IN_CDV_13B_MASK 0x00000080 +#define MONTMORENCY1012_IN_CDV_14B_MASK 0x00000100 +#define MONTMORENCY1012_IN_ZT1_ITI_MASK 0x00000200 +#define MONTMORENCY1012_IN_ZT2_ITI_MASK 0x00000400 +#define MONTMORENCY1012_IN_ZT1_AN_MASK 0x00000800 +#define MONTMORENCY1012_IN_ZT2_AN_MASK 0x00001000 +#define MONTMORENCY1012_IN_ZT1_ARF_MASK 0x00002000 +#define MONTMORENCY1012_IN_ZT2_ARF_MASK 0x00004000 +#define MONTMORENCY1012_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for MONTMORENCY +#define MONTMORENCY1012_OUT_VP1_MASK 0x00000001 +#define MONTMORENCY1012_OUT_VP2_MASK 0x00000002 +#define MONTMORENCY1012_OUT_VP3_MASK 0x00000004 +#define MONTMORENCY1012_OUT_VP4_MASK 0x00000008 +#define MONTMORENCY1012_OUT_VP5_MASK 0x00000010 +#define MONTMORENCY1012_OUT_VP6_MASK 0x00000020 +#define MONTMORENCY1012_OUT_VF1_MASK 0x00000040 +#define MONTMORENCY1012_OUT_VF2_MASK 0x00000080 +#define MONTMORENCY1012_OUT_VF3_MASK 0x00000100 +#define MONTMORENCY1012_OUT_VF4_MASK 0x00000200 +#define MONTMORENCY1012_OUT_VF5_MASK 0x00000400 +#define MONTMORENCY1012_OUT_WP1_MASK 0x00000800 +#define MONTMORENCY1012_OUT_WP2_MASK 0x00001000 +#define MONTMORENCY1012_OUT_WP3_MASK 0x00002000 +#define MONTMORENCY1012_OUT_WP4_MASK 0x00004000 +#define MONTMORENCY1012_OUT_WP5_MASK 0x00008000 +#define MONTMORENCY1012_OUT_WP6_MASK 0x00010000 +#define MONTMORENCY1012_OUT_DPE_MASK 0x00020000 +#define MONTMORENCY1012_OUT_DPI_MASK 0x00040000 +#define MONTMORENCY1012_OUT_V00_MASK 0x00080000 +#define MONTMORENCY1012_OUT_DPG_MASK 0x00100000 +#define MONTMORENCY1012_OUT_DFR_MASK 0x00200000 +#define MONTMORENCY1012_OUT_RF_MASK 0x00400000 +#define MONTMORENCY1012_OUT_RF2_MASK 0x00800000 +#define MONTMORENCY1012_OUT_VEL_MASK 0x01000000 +#define MONTMORENCY1012_OUT_VEL2_MASK 0x02000000 +#define MONTMORENCY1012_OUT_DPI2_MASK 0x04000000 +#define MONTMORENCY1012_OUT_DPE2_MASK 0x08000000 +#define MONTMORENCY1012_OUT_V002_MASK 0x10000000 +#define MONTMORENCY1012_OUT_PEQ1_MASK 0x20000000 +#define MONTMORENCY1012_OUT_PEQ2_MASK 0x40000000 +#define MONTMORENCY1012_OUT_WATCHDOG_MASK 0x80000000 + +#define MONTMORENCY1012_SDF_ACQUISITION_CHANNEL 0 + +class CMontmorency1012Station : public CStation +{ +public: + + CMontmorency1012Station(); + // bool IsZT1ApproachCDVOccupied(); + +private: + virtual unsigned int BuildStationCDVList(); +}; + +#endif // MONTMORENCY_H + diff --git a/sources/Stations/Montmorency1022.cpp b/sources/Stations/Montmorency1022.cpp new file mode 100644 index 0000000..5c55a8f --- /dev/null +++ b/sources/Stations/Montmorency1022.cpp @@ -0,0 +1,142 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Montmorency1022.h" +#include +#include "SwitchCDV.h" + +CMontmorency1022Station::CMontmorency1022Station() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = MONTMORENCY1022_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = MONTMORENCY1022_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = MONTMORENCY1022_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = MONTMORENCY1022_STATION_KEY; + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = MONTMORENCY1022_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = MONTMORENCY1022_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = MONTMORENCY1022_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = MONTMORENCY1022_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = MONTMORENCY1022_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = MONTMORENCY1022_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = MONTMORENCY1022_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = MONTMORENCY1022_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = MONTMORENCY1022_IN_ZT1_ITI_MASK; +// mStationInputMasks.InputZT1ITIMask = MONTMORENCY1022_IN_ZT1_10_22_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = MONTMORENCY1022_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = MONTMORENCY1022_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = MONTMORENCY1022_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = MONTMORENCY1022_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = MONTMORENCY1022_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = MONTMORENCY1022_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = MONTMORENCY1022_IN_CDV_10B_MASK; + mStationInputMasks.InputCDVZT1Mask = MONTMORENCY1022_IN_CDV_10B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = 0; + mStationInputMasks.InputCDVZT2Mask = 0; + + //Output masks + mStationOutputMasks.OutputVP1Mask = MONTMORENCY1022_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = MONTMORENCY1022_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = MONTMORENCY1022_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = MONTMORENCY1022_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = MONTMORENCY1022_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = MONTMORENCY1022_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = MONTMORENCY1022_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = MONTMORENCY1022_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = MONTMORENCY1022_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = MONTMORENCY1022_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = MONTMORENCY1022_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = MONTMORENCY1022_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = MONTMORENCY1022_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = MONTMORENCY1022_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = MONTMORENCY1022_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = MONTMORENCY1022_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = MONTMORENCY1022_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = MONTMORENCY1022_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = MONTMORENCY1022_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = MONTMORENCY1022_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = MONTMORENCY1022_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = MONTMORENCY1022_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = MONTMORENCY1022_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = MONTMORENCY1022_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = MONTMORENCY1022_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = MONTMORENCY1022_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = MONTMORENCY1022_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = MONTMORENCY1022_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = MONTMORENCY1022_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = MONTMORENCY1022_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = MONTMORENCY1022_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = MONTMORENCY1022_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = MONTMORENCY1022_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = false; + mTextualStationName = "Montmorency (10/22)"; + mTextualShortName = "MMO2"; +} + +unsigned int CMontmorency1022Station::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(MONTMORENCY1022_IN_ZT1_ITI_MASK,MONTMORENCY1022_IN_CDV_11A_MASK,CDV_NORMAL_TYPE,"11A",1,5); + mCDVList.append(NewCDV); + mZT1SubsequentCDV = NewCDV; + + NewCDV = new CCDV(MONTMORENCY1022_IN_ZT1_ITI_MASK,MONTMORENCY1022_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B ZT1",1,6); + mZT1CDV = NewCDV; + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(MONTMORENCY1022_IN_ZT1_ITI_MASK,MONTMORENCY1022_IN_CDV_22BC_MASK,CDV_NORMAL_TYPE,"22BC",2,2); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + mZT1AlarmAutoAcquireCDV = NewCDV; + + NewCDV = new CCDV(MONTMORENCY1022_IN_ZT1_ITI_MASK,MONTMORENCY1022_IN_CDV_22A_MASK,CDV_NORMAL_TYPE,"22A",2,3); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + + NewCDV = new CCDV(MONTMORENCY1022_IN_ZT1_ITI_MASK,MONTMORENCY1022_IN_CDV_21AB_MASK,CDV_NORMAL_TYPE,"21AB",2,4); + mCDVList.append(NewCDV); + + + return RET_OK; +} diff --git a/sources/Stations/Montmorency1022.h b/sources/Stations/Montmorency1022.h new file mode 100644 index 0000000..1f795fd --- /dev/null +++ b/sources/Stations/Montmorency1022.h @@ -0,0 +1,115 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef MONTMORENCY1022_H +#define MONTMORENCY1022_H +#include "Station.h" + +#define MONTMORENCY1022_STATION_KEY 0x0050000 +#define MONTMORENCY1022_NB_EXTERNAL_INPUT_430_MODULES 1 +#define MONTMORENCY1022_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define MONTMORENCY1022_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define MONTMORENCY1022_ZT1_S1_MASK 0x00000001 +#define MONTMORENCY1022_ZT1_S2_MASK 0x00000002 +#define MONTMORENCY1022_ZT1_PI_MASK 0x00000004 +#define MONTMORENCY1022_ZT1_PE_MASK 0x00000008 +#define MONTMORENCY1022_ZT1_FN_MASK 0x00000010 +#define MONTMORENCY1022_ZT2_S1_MASK 0x00000020 +#define MONTMORENCY1022_ZT2_PI_MASK 0x00000040 +#define MONTMORENCY1022_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for MONTMORENCY +#define MONTMORENCY1022_IN_CDV_22A_MASK 0x00000001 +#define MONTMORENCY1022_IN_CDV_22BC_MASK 0x00000002 +#define MONTMORENCY1022_IN_CDV_21AB_MASK 0x00000004 +#define MONTMORENCY1022_IN_CDV_11A_MASK 0x00000008 +#define MONTMORENCY1022_IN_CDV_10B_MASK 0x00000010 +//#define MONTMORENCY1022_IN_CDV_21BC_MASK 0x00000020 +//#define MONTMORENCY1022_IN_CDV_14A_MASK 0x00000040 +//#define MONTMORENCY1022_IN_CDV_13B_MASK 0x00000080 +//#define MONTMORENCY1022_IN_CDV_14B_MASK 0x00000100 +#define MONTMORENCY1022_IN_ZT1_ITI_MASK 0x00000200 +#define MONTMORENCY1022_IN_ZT2_ITI_MASK 0x00000400 +#define MONTMORENCY1022_IN_ZT1_AN_MASK 0x00000800 +#define MONTMORENCY1022_IN_ZT2_AN_MASK 0x00001000 +#define MONTMORENCY1022_IN_ZT1_ARF_MASK 0x00002000 +#define MONTMORENCY1022_IN_ZT2_ARF_MASK 0x00004000 +#define MONTMORENCY1022_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for MONTMORENCY +#define MONTMORENCY1022_OUT_VP1_MASK 0x00000001 +#define MONTMORENCY1022_OUT_VP2_MASK 0x00000002 +#define MONTMORENCY1022_OUT_VP3_MASK 0x00000004 +#define MONTMORENCY1022_OUT_VP4_MASK 0x00000008 +#define MONTMORENCY1022_OUT_VP5_MASK 0x00000010 +#define MONTMORENCY1022_OUT_VP6_MASK 0x00000020 +#define MONTMORENCY1022_OUT_VF1_MASK 0x00000040 +#define MONTMORENCY1022_OUT_VF2_MASK 0x00000080 +#define MONTMORENCY1022_OUT_VF3_MASK 0x00000100 +#define MONTMORENCY1022_OUT_VF4_MASK 0x00000200 +#define MONTMORENCY1022_OUT_VF5_MASK 0x00000400 +#define MONTMORENCY1022_OUT_WP1_MASK 0x00000800 +#define MONTMORENCY1022_OUT_WP2_MASK 0x00001000 +#define MONTMORENCY1022_OUT_WP3_MASK 0x00002000 +#define MONTMORENCY1022_OUT_WP4_MASK 0x00004000 +#define MONTMORENCY1022_OUT_WP5_MASK 0x00008000 +#define MONTMORENCY1022_OUT_WP6_MASK 0x00010000 +#define MONTMORENCY1022_OUT_DPE_MASK 0x00020000 +#define MONTMORENCY1022_OUT_DPI_MASK 0x00040000 +#define MONTMORENCY1022_OUT_V00_MASK 0x00080000 +#define MONTMORENCY1022_OUT_DPG_MASK 0x00100000 +#define MONTMORENCY1022_OUT_DFR_MASK 0x00200000 +#define MONTMORENCY1022_OUT_RF_MASK 0x00400000 +#define MONTMORENCY1022_OUT_RF2_MASK 0x00800000 +#define MONTMORENCY1022_OUT_VEL_MASK 0x01000000 +#define MONTMORENCY1022_OUT_VEL2_MASK 0x02000000 +#define MONTMORENCY1022_OUT_DPI2_MASK 0x04000000 +#define MONTMORENCY1022_OUT_DPE2_MASK 0x08000000 +#define MONTMORENCY1022_OUT_V002_MASK 0x10000000 +#define MONTMORENCY1022_OUT_PEQ1_MASK 0x20000000 +#define MONTMORENCY1022_OUT_PEQ2_MASK 0x40000000 +#define MONTMORENCY1022_OUT_WATCHDOG_MASK 0x80000000 + +#define MONTMORENCY1022_SDF_ACQUISITION_CHANNEL 0 + +class CMontmorency1022Station : public CStation +{ +public: + + CMontmorency1022Station(); + +private: + virtual unsigned int BuildStationCDVList(); +}; + +#endif // MONTMORENCY_H + diff --git a/sources/Stations/SaintMichel.cpp b/sources/Stations/SaintMichel.cpp new file mode 100644 index 0000000..d2836f3 --- /dev/null +++ b/sources/Stations/SaintMichel.cpp @@ -0,0 +1,153 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SaintMichel.h" +#include + +CSaintMichelStation::CSaintMichelStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = SAINTMICHEL_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = SAINTMICHEL_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = SAINTMICHEL_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = SAINTMICHEL_STATION_KEY; + + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = SAINTMICHEL_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = SAINTMICHEL_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = SAINTMICHEL_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = SAINTMICHEL_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = SAINTMICHEL_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = SAINTMICHEL_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = SAINTMICHEL_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = SAINTMICHEL_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = SAINTMICHEL_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = SAINTMICHEL_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = SAINTMICHEL_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = SAINTMICHEL_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = SAINTMICHEL_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = SAINTMICHEL_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = SAINTMICHEL_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = SAINTMICHEL_IN_CDV_11A_MASK; + mStationInputMasks.InputCDVZT1Mask = SAINTMICHEL_IN_CDV_11B_MASK; + mStationInputMasks.InputCDVZT2ApproachMask = SAINTMICHEL_IN_CDV_12B_MASK; + mStationInputMasks.InputCDVZT2Mask = SAINTMICHEL_IN_CDV_13A_MASK; + + //Output masks + mStationOutputMasks.OutputVP1Mask = SAINTMICHEL_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = SAINTMICHEL_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = SAINTMICHEL_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = SAINTMICHEL_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = SAINTMICHEL_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = SAINTMICHEL_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = SAINTMICHEL_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = SAINTMICHEL_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = SAINTMICHEL_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = SAINTMICHEL_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = SAINTMICHEL_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = SAINTMICHEL_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = SAINTMICHEL_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = SAINTMICHEL_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = SAINTMICHEL_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = SAINTMICHEL_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = SAINTMICHEL_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = SAINTMICHEL_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = SAINTMICHEL_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = SAINTMICHEL_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = SAINTMICHEL_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = SAINTMICHEL_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = SAINTMICHEL_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = SAINTMICHEL_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = SAINTMICHEL_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = SAINTMICHEL_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = SAINTMICHEL_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = SAINTMICHEL_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = SAINTMICHEL_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = SAINTMICHEL_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = SAINTMICHEL_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = SAINTMICHEL_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = SAINTMICHEL_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = true; + mTextualStationName = "Saint-Michel"; + mTextualShortName = "SMIC"; +} + +unsigned int CSaintMichelStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT2_ITI_MASK,SAINTMICHEL_IN_CDV_14B_MASK,CDV_NORMAL_TYPE,"14B",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT2_ITI_MASK,SAINTMICHEL_IN_CDV_14A_MASK,CDV_NORMAL_TYPE,"14A",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT2_ITI_MASK,SAINTMICHEL_IN_CDV_13B_MASK,CDV_NORMAL_TYPE,"13B",1,2); + mZT2AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT2_ITI_MASK,SAINTMICHEL_IN_CDV_13A_MASK,CDV_NORMAL_TYPE,"13A (ZT2)",1,3); + mZT2CDV =NewCDV; + mZT2ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT1_ITI_MASK,SAINTMICHEL_IN_CDV_12B_MASK,CDV_NORMAL_TYPE,"12B",1,4); + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT1_ITI_MASK,SAINTMICHEL_IN_CDV_12A_MASK,CDV_NORMAL_TYPE,"12A",1,5); + mZT1AlarmAutoAcquireCDV = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT1_ITI_MASK,SAINTMICHEL_IN_CDV_11B_MASK,CDV_NORMAL_TYPE,"11B (ZT1)",1,6); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT1_ITI_MASK,SAINTMICHEL_IN_CDV_11A_MASK,CDV_NORMAL_TYPE,"11A",1,7); + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SAINTMICHEL_IN_ZT1_ITI_MASK,SAINTMICHEL_IN_CDV_10B_MASK,CDV_NORMAL_TYPE,"10B",1,8); + mCDVList.append(NewCDV); + + return RET_OK; +} diff --git a/sources/Stations/SaintMichel.h b/sources/Stations/SaintMichel.h new file mode 100644 index 0000000..bfd4709 --- /dev/null +++ b/sources/Stations/SaintMichel.h @@ -0,0 +1,117 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SAINTMICHEL_H +#define SAINTMICHEL_H +#include "Station.h" + +#define SAINTMICHEL_STATION_KEY 0x0038000 +#define SAINTMICHEL_NB_EXTERNAL_INPUT_430_MODULES 1 +#define SAINTMICHEL_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define SAINTMICHEL_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define SAINTMICHEL_ZT1_S1_MASK 0x00000001 +#define SAINTMICHEL_ZT1_S2_MASK 0x00000002 +#define SAINTMICHEL_ZT1_PI_MASK 0x00000004 +#define SAINTMICHEL_ZT1_PE_MASK 0x00000008 +#define SAINTMICHEL_ZT1_FN_MASK 0x00000010 +#define SAINTMICHEL_ZT2_S1_MASK 0x00000020 +#define SAINTMICHEL_ZT2_PI_MASK 0x00000040 +#define SAINTMICHEL_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for SAINTMICHEL +#define SAINTMICHEL_IN_CDV_12A_MASK 0x00000001 +#define SAINTMICHEL_IN_CDV_12B_MASK 0x00000002 +#define SAINTMICHEL_IN_CDV_11B_MASK 0x00000004 +#define SAINTMICHEL_IN_CDV_11A_MASK 0x00000008 +#define SAINTMICHEL_IN_CDV_10B_MASK 0x00000010 +#define SAINTMICHEL_IN_CDV_13A_MASK 0x00000020 +#define SAINTMICHEL_IN_CDV_14A_MASK 0x00000040 +#define SAINTMICHEL_IN_CDV_13B_MASK 0x00000080 +#define SAINTMICHEL_IN_CDV_14B_MASK 0x00000100 +#define SAINTMICHEL_IN_ZT1_ITI_MASK 0x00000200 +#define SAINTMICHEL_IN_ZT2_ITI_MASK 0x00000400 +#define SAINTMICHEL_IN_ZT1_AN_MASK 0x00000800 +#define SAINTMICHEL_IN_ZT2_AN_MASK 0x00001000 +#define SAINTMICHEL_IN_ZT1_ARF_MASK 0x00002000 +#define SAINTMICHEL_IN_ZT2_ARF_MASK 0x00004000 +#define SAINTMICHEL_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for SAINTMICHEL +#define SAINTMICHEL_OUT_VP1_MASK 0x00000001 +#define SAINTMICHEL_OUT_VP2_MASK 0x00000002 +#define SAINTMICHEL_OUT_VP3_MASK 0x00000004 +#define SAINTMICHEL_OUT_VP4_MASK 0x00000008 +#define SAINTMICHEL_OUT_VP5_MASK 0x00000010 +#define SAINTMICHEL_OUT_VP6_MASK 0x00000020 +#define SAINTMICHEL_OUT_VF1_MASK 0x00000040 +#define SAINTMICHEL_OUT_VF2_MASK 0x00000080 +#define SAINTMICHEL_OUT_VF3_MASK 0x00000100 +#define SAINTMICHEL_OUT_VF4_MASK 0x00000200 +#define SAINTMICHEL_OUT_VF5_MASK 0x00000400 +#define SAINTMICHEL_OUT_WP1_MASK 0x00000800 +#define SAINTMICHEL_OUT_WP2_MASK 0x00001000 +#define SAINTMICHEL_OUT_WP3_MASK 0x00002000 +#define SAINTMICHEL_OUT_WP4_MASK 0x00004000 +#define SAINTMICHEL_OUT_WP5_MASK 0x00008000 +#define SAINTMICHEL_OUT_WP6_MASK 0x00010000 +#define SAINTMICHEL_OUT_DPE_MASK 0x00020000 +#define SAINTMICHEL_OUT_DPI_MASK 0x00040000 +#define SAINTMICHEL_OUT_V00_MASK 0x00080000 +#define SAINTMICHEL_OUT_DPG_MASK 0x00100000 +#define SAINTMICHEL_OUT_DFR_MASK 0x00200000 +#define SAINTMICHEL_OUT_RF_MASK 0x00400000 +#define SAINTMICHEL_OUT_RF2_MASK 0x00800000 +#define SAINTMICHEL_OUT_VEL_MASK 0x01000000 +#define SAINTMICHEL_OUT_VEL2_MASK 0x02000000 +#define SAINTMICHEL_OUT_DPI2_MASK 0x04000000 +#define SAINTMICHEL_OUT_DPE2_MASK 0x08000000 +#define SAINTMICHEL_OUT_V002_MASK 0x10000000 +#define SAINTMICHEL_OUT_PEQ1_MASK 0x20000000 +#define SAINTMICHEL_OUT_PEQ2_MASK 0x40000000 +#define SAINTMICHEL_OUT_WATCHDOG_MASK 0x80000000 + +#define SAINTMICHEL_SDF_ACQUISITION_CHANNEL 0 +class CSaintMichelStation : public CStation +{ +public: + + CSaintMichelStation(); + + + +private: + + virtual unsigned int BuildStationCDVList(); +}; + +#endif // SAINTMICHEL_H + diff --git a/sources/Stations/Snowdon.cpp b/sources/Stations/Snowdon.cpp new file mode 100644 index 0000000..b43414d --- /dev/null +++ b/sources/Stations/Snowdon.cpp @@ -0,0 +1,175 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe instantiable dérivée de la classe de base CStation. Les paramètres + physiques de la station sont définis et initialisés ici. Ils sont ensuite + accédés de manière générique à travers la classe CStation. + Les paramètres dépend du câblage de l'armoire ZT et de la configuration + particulière des CDVs de la station. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Snowdon.h" +#include + +CSnowdonStation::CSnowdonStation() +{ + //All the inherited variables from base class must be initialized here + //according to the physical implementation in the station. + mNbExtInputModules430 = SNOWDON_NB_EXTERNAL_INPUT_430_MODULES; + mNbExtOutputModules440 = SNOWDON_NB_EXTERNAL_OUTPUT_440_MODULES; + mNbExtMixedModules470 = SNOWDON_NB_EXTERNAL_MIXED_470_MODULES; + mStationPhysicalKey = SNOWDON_STATION_KEY; + //Initialize mask structures + // + + mStationInputMasks.InputZT1S1Mask = SNOWDON_ZT1_S1_MASK; + mStationInputMasks.InputZT1S2Mask = SNOWDON_ZT1_S2_MASK; + mStationInputMasks.InputZT1PIMask = SNOWDON_ZT1_PI_MASK; + mStationInputMasks.InputZT1PEMask = SNOWDON_ZT1_PE_MASK; + mStationInputMasks.InputZT1FNMask = SNOWDON_ZT1_FN_MASK; + mStationInputMasks.InputZT2S1Mask = SNOWDON_ZT2_S1_MASK; + mStationInputMasks.InputZT2PIMask = SNOWDON_ZT2_PI_MASK; + mStationInputMasks.InputZT2PEMask = SNOWDON_ZT2_PE_MASK; + + //External (ethernet) input module masks + mStationInputMasks.InputZT1ITIMask = SNOWDON_IN_ZT1_ITI_MASK; + mStationInputMasks.InputZT2ITIMask = SNOWDON_IN_ZT2_ITI_MASK; + mStationInputMasks.InputZT1ANMask = SNOWDON_IN_ZT1_AN_MASK; + mStationInputMasks.InputZT2ANMask = SNOWDON_IN_ZT2_AN_MASK; + mStationInputMasks.InputZT1ARFMask = SNOWDON_IN_ZT1_ARF_MASK; + mStationInputMasks.InputZT2ARFMask = SNOWDON_IN_ZT2_ARF_MASK; + mStationInputMasks.InputStationIDMask = SNOWDON_IN_STATION_ID_MASK; + + //Logic input masks + mStationInputMasks.InputCDVZT1ApproachMask = SNOWDON_IN_CDV_22C_MASK; + mStationInputMasks.InputCDVZT1Mask = SNOWDON_IN_CDV_22B_MASK; + + //No ZT2 at Snowdon... + mStationInputMasks.InputCDVZT2ApproachMask = 0; + mStationInputMasks.InputCDVZT2Mask = 0; + + //Output masks + mStationOutputMasks.OutputVP1Mask = SNOWDON_OUT_VP1_MASK; + mStationOutputMasks.OutputVP2Mask = SNOWDON_OUT_VP2_MASK; + mStationOutputMasks.OutputVP3Mask = SNOWDON_OUT_VP3_MASK; + mStationOutputMasks.OutputVP4Mask = SNOWDON_OUT_VP4_MASK; + mStationOutputMasks.OutputVP5Mask = SNOWDON_OUT_VP5_MASK; + mStationOutputMasks.OutputVP6Mask = SNOWDON_OUT_VP6_MASK; + mStationOutputMasks.OutputVF1Mask = SNOWDON_OUT_VF1_MASK; + mStationOutputMasks.OutputVF2Mask = SNOWDON_OUT_VF2_MASK; + mStationOutputMasks.OutputVF3Mask = SNOWDON_OUT_VF3_MASK; + mStationOutputMasks.OutputVF4Mask = SNOWDON_OUT_VF4_MASK; + mStationOutputMasks.OutputVF5Mask = SNOWDON_OUT_VF5_MASK; + mStationOutputMasks.OutputWP1Mask = SNOWDON_OUT_WP1_MASK; + mStationOutputMasks.OutputWP2Mask = SNOWDON_OUT_WP2_MASK; + mStationOutputMasks.OutputWP3Mask = SNOWDON_OUT_WP3_MASK; + mStationOutputMasks.OutputWP4Mask = SNOWDON_OUT_WP4_MASK; + mStationOutputMasks.OutputWP5Mask = SNOWDON_OUT_WP5_MASK; + mStationOutputMasks.OutputWP6Mask = SNOWDON_OUT_WP6_MASK; + mStationOutputMasks.OutputDPEMask = SNOWDON_OUT_DPE_MASK; + mStationOutputMasks.OutputDPIMask = SNOWDON_OUT_DPI_MASK; + mStationOutputMasks.OutputV00Mask = SNOWDON_OUT_V00_MASK; + mStationOutputMasks.OutputDPGMask = SNOWDON_OUT_DPG_MASK; + mStationOutputMasks.OutputDFRMask = SNOWDON_OUT_DFR_MASK; + mStationOutputMasks.OutputRFMask = SNOWDON_OUT_RF_MASK; + mStationOutputMasks.OutputRF2Mask = SNOWDON_OUT_RF2_MASK; + mStationOutputMasks.OutputVELMask = SNOWDON_OUT_VEL_MASK; + mStationOutputMasks.OutputVEL2Mask = SNOWDON_OUT_VEL2_MASK; + mStationOutputMasks.OutputDPI2Mask = SNOWDON_OUT_DPI2_MASK; + mStationOutputMasks.OutputDPE2Mask = SNOWDON_OUT_DPE2_MASK; + mStationOutputMasks.OutputV002Mask = SNOWDON_OUT_V002_MASK; + mStationOutputMasks.OutputPEQ1Mask = SNOWDON_OUT_PEQ1_MASK; + mStationOutputMasks.OutputPEQ2Mask = SNOWDON_OUT_PEQ2_MASK; + mStationOutputMasks.OutputWatchdogMask = SNOWDON_OUT_WATCHDOG_MASK; + + mAnalogAcqChannels.SDFAcquisitionChannel = SNOWDON_SDF_ACQUISITION_CHANNEL; + + mStationHasZT2 = false; + mTextualStationName = "Snowdon"; + mTextualShortName = "SNW5"; +} + +unsigned int CSnowdonStation::BuildStationCDVList() +{ + CCDV *NewCDV; + mCDVList.empty(); + + NewCDV = new CCDV(0,SNOWDON_IN_CDV_20A_MASK,CDV_NORMAL_TYPE,"20A",1,0); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(0,SNOWDON_IN_CDV_20B_MASK,CDV_NORMAL_TYPE,"20B",1,1); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(0,SNOWDON_IN_CDV_20C_MASK,CDV_NORMAL_TYPE,"20C",1,2); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(0,SNOWDON_IN_CDV_21_MASK,CDV_NORMAL_TYPE,"21",1,3); + NewCDV->SetInputMask(SNOWDON_IN_CDV_21_MASK); + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SNOWDON_IN_ZT1_ITI_MASK,SNOWDON_IN_CDV_22A_MASK,CDV_NORMAL_TYPE,"22A",1,4); + mZT1AlarmAutoAcquireCDV = NewCDV; + mCDV22A = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SNOWDON_IN_ZT1_ITI_MASK,SNOWDON_IN_CDV_22B_MASK,CDV_NORMAL_TYPE,"22B (ZT1)",1,5); + mZT1CDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SNOWDON_IN_ZT1_ITI_MASK,SNOWDON_IN_CDV_22C_MASK,CDV_NORMAL_TYPE,"22C",1,6); + mCDV22C = NewCDV; + mCDVList.append(NewCDV); + NewCDV->SetCDVDeck(true); + + NewCDV = new CCDV(SNOWDON_IN_ZT1_ITI_MASK,SNOWDON_IN_CDV_23_MASK,CDV_NORMAL_TYPE,"23",1,7); + mZT1ApproachCDV = NewCDV; + mCDVList.append(NewCDV); + + NewCDV = new CCDV(SNOWDON_IN_ZT1_ITI_MASK,SNOWDON_IN_CDV_24A_MASK,CDV_NORMAL_TYPE,"24A",1,8); + mCDVList.append(NewCDV); + + return RET_OK; +} + +bool CSnowdonStation::IsZT1AnalysisFinished() +{ + //At Snowdon, we must stop the ZT1 analysis when the CDV 22A is occupied or when ZT1 CDV (22B | 22C) is free. + if(mCDV22A->IsOccupied() || !IsZT1CDVOccupied()) + { + return true; + } + + return false; +} + +bool CSnowdonStation::IsZT1CDVOccupied() +{ + if(mZT1CDV->IsOccupied() || mCDV22C->IsOccupied()) //Combine CDV 22B and 22C as the ZT1 CDV because equipment is too close from the deck + { + return true; + } + + return false; +} + diff --git a/sources/Stations/Snowdon.h b/sources/Stations/Snowdon.h new file mode 100644 index 0000000..54f5fdd --- /dev/null +++ b/sources/Stations/Snowdon.h @@ -0,0 +1,138 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121220 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SNOWDON_H +#define SNOWDON_H +#include "Station.h" + +#define SNOWDON_STATION_KEY 0x0040000 +#define SNOWDON_NB_EXTERNAL_INPUT_430_MODULES 1 +#define SNOWDON_NB_EXTERNAL_OUTPUT_440_MODULES 1 +#define SNOWDON_NB_EXTERNAL_MIXED_470_MODULES 0 + +//Since it's necessary to execute a very fast acquisition and analysis +//of magnetic sensors through the PCI I/O adapter, we will use masks +//instead of bitfields for those sensors. This will accelerate +//treatment by avoiding the use of a memcpy(). +#define SNOWDON_ZT1_S1_MASK 0x00000001 +#define SNOWDON_ZT1_S2_MASK 0x00000002 +#define SNOWDON_ZT1_PI_MASK 0x00000004 +#define SNOWDON_ZT1_PE_MASK 0x00000008 +#define SNOWDON_ZT1_FN_MASK 0x00000010 +#define SNOWDON_ZT2_S1_MASK 0x00000020 +#define SNOWDON_ZT2_PI_MASK 0x00000040 +#define SNOWDON_ZT2_PE_MASK 0x00000080 + +//External (ethernet) input module masks for SNOWDON +//#define SNOWDON_IN_CDV_22B_MASK 0x00000001 +//#define SNOWDON_IN_CDV_22A_MASK 0x00000002 +//#define SNOWDON_IN_CDV_22C_MASK 0x00000004 +//#define SNOWDON_IN_CDV_23_MASK 0x00000008 +//#define SNOWDON_IN_CDV_24A_MASK 0x00000010 +//#define SNOWDON_IN_CDV_21_MASK 0x00000020 +//#define SNOWDON_IN_CDV_20B_MASK 0x00000040 +//#define SNOWDON_IN_CDV_20C_MASK 0x00000080 +//#define SNOWDON_IN_CDV_20A_MASK 0x00000100 +//#define SNOWDON_IN_ZT1_ITI_MASK 0x00000200 +//#define SNOWDON_IN_ZT2_ITI_MASK 0x00000400 +//#define SNOWDON_IN_ZT1_AN_MASK 0x00000800 +//#define SNOWDON_IN_ZT2_AN_MASK 0x00001000 +//#define SNOWDON_IN_ZT1_ARF_MASK 0x00002000 +//#define SNOWDON_IN_ZT2_ARF_MASK 0x00004000 +//#define SNOWDON_IN_STATION_ID_MASK 0x00078000 + +#define SNOWDON_IN_CDV_22B_MASK 0x00000004 //2.1 +#define SNOWDON_IN_CDV_22A_MASK 0x00000001 //1.2 +#define SNOWDON_IN_CDV_22C_MASK 0x00000008 //2.2 +#define SNOWDON_IN_CDV_23_MASK 0x00000010 //3.1 +#define SNOWDON_IN_CDV_24A_MASK 0x00000040 //10.1 +#define SNOWDON_IN_CDV_21_MASK 0x00000020 //9.2 +#define SNOWDON_IN_CDV_20B_MASK 0x00000100 //13.2 +#define SNOWDON_IN_CDV_20C_MASK 0x00000002 //1.1 +#define SNOWDON_IN_CDV_20A_MASK 0x00000080 //13.1 +#define SNOWDON_IN_ZT1_ITI_MASK 0x00000200 +#define SNOWDON_IN_ZT2_ITI_MASK 0x00000400 +#define SNOWDON_IN_ZT1_AN_MASK 0x00000800 +#define SNOWDON_IN_ZT2_AN_MASK 0x00001000 +#define SNOWDON_IN_ZT1_ARF_MASK 0x00002000 +#define SNOWDON_IN_ZT2_ARF_MASK 0x00004000 +#define SNOWDON_IN_STATION_ID_MASK 0x00078000 + +//External (ethernet) output module masks for SNOWDON +#define SNOWDON_OUT_VP1_MASK 0x00000001 +#define SNOWDON_OUT_VP2_MASK 0x00000002 +#define SNOWDON_OUT_VP3_MASK 0x00000004 +#define SNOWDON_OUT_VP4_MASK 0x00000008 +#define SNOWDON_OUT_VP5_MASK 0x00000010 +#define SNOWDON_OUT_VP6_MASK 0x00000020 +#define SNOWDON_OUT_VF1_MASK 0x00000040 +#define SNOWDON_OUT_VF2_MASK 0x00000080 +#define SNOWDON_OUT_VF3_MASK 0x00000100 +#define SNOWDON_OUT_VF4_MASK 0x00000200 +#define SNOWDON_OUT_VF5_MASK 0x00000400 +#define SNOWDON_OUT_WP1_MASK 0x00000800 +#define SNOWDON_OUT_WP2_MASK 0x00001000 +#define SNOWDON_OUT_WP3_MASK 0x00002000 +#define SNOWDON_OUT_WP4_MASK 0x00004000 +#define SNOWDON_OUT_WP5_MASK 0x00008000 +#define SNOWDON_OUT_WP6_MASK 0x00010000 +#define SNOWDON_OUT_DPE_MASK 0x00020000 +#define SNOWDON_OUT_DPI_MASK 0x00040000 +#define SNOWDON_OUT_V00_MASK 0x00080000 +#define SNOWDON_OUT_DPG_MASK 0x00100000 +#define SNOWDON_OUT_DFR_MASK 0x00200000 +#define SNOWDON_OUT_RF_MASK 0x00400000 +#define SNOWDON_OUT_RF2_MASK 0x00800000 +#define SNOWDON_OUT_VEL_MASK 0x01000000 +#define SNOWDON_OUT_VEL2_MASK 0x02000000 +#define SNOWDON_OUT_DPI2_MASK 0x04000000 +#define SNOWDON_OUT_DPE2_MASK 0x08000000 +#define SNOWDON_OUT_V002_MASK 0x10000000 +#define SNOWDON_OUT_PEQ1_MASK 0x20000000 +#define SNOWDON_OUT_PEQ2_MASK 0x40000000 +#define SNOWDON_OUT_WATCHDOG_MASK 0x80000000 + +#define SNOWDON_SDF_ACQUISITION_CHANNEL 0 + +class CSnowdonStation : public CStation +{ +public: + + CSnowdonStation(); + + virtual bool IsZT1AnalysisFinished(); + virtual bool IsZT1CDVOccupied(); + CCDV *mCDV22C, *mCDV22A; + + + +private: + virtual unsigned int BuildStationCDVList(); +}; + +#endif // SNOWDON_H + diff --git a/sources/SwitchCDV.cpp b/sources/SwitchCDV.cpp new file mode 100644 index 0000000..5cab917 --- /dev/null +++ b/sources/SwitchCDV.cpp @@ -0,0 +1,97 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Objet CDV d'Aiguillage. Contient différents paramètres d'un CDV ainsi que son état actuel. + Utilisé pour l'interface graphique mais aussi par le state machine pour qui l'état + de certains CDV est utile. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "SwitchCDV.h" + +//TEST + +CSwitchCDV::CSwitchCDV() +{ + mCDVType = CDV_SWITCH_TYPE; + mCDVInputMask = 0; + mCDVITIMask = 0; + mNormalItiMask = 0; + mReversedItiMask = 0; + mIsOccupied = false; + mIsItiCommanded = false; + mCDVState = CDV_STATE_FREE; + mCurSwitchPosition = SWITCH_CDV_NORMAL_POSITION; + +} + +CSwitchCDV::CSwitchCDV(unsigned int CDVNormalITIMask, unsigned int CDVReversedITIMask, unsigned int CDVInputMask, unsigned int CDVType, QString CDVLabel, unsigned int CDVWay, unsigned int CDVGraphicalPosition) + :CCDV(0,CDVInputMask,CDVType,CDVLabel,CDVWay,CDVGraphicalPosition) +{ + mNormalItiMask = CDVNormalITIMask; + mReversedItiMask = CDVReversedITIMask; + mCDVType = CDV_SWITCH_TYPE; + mCurSwitchPosition = SWITCH_CDV_NORMAL_POSITION; +} + +unsigned int CSwitchCDV::ComputeCDVState(unsigned int InputsBuf, unsigned int ZT1ItiMask, unsigned int ZT2ItiMask) +{ + mIsOccupied = false; + mIsItiCommanded = false; + mCDVState = CDV_STATE_FREE; + mCurSwitchPosition = SWITCH_CDV_NORMAL_POSITION; + + if( (((ZT1ItiMask & InputsBuf) != 0) && (ZT1ItiMask == mNormalItiMask)) || //If there is a ZT1 itinerary commanded AND this CDV is part of itinerary + (((ZT2ItiMask & InputsBuf) != 0) && ((ZT2ItiMask & mNormalItiMask) != 0)) ) //OR if there is a ZT2 itinerary commanded AND this CDV is part of itinerary + { + mIsItiCommanded = true; + mCDVState = CDV_STATE_ITI_CMD; + mCurSwitchPosition = SWITCH_CDV_NORMAL_POSITION; + } + + if( (((ZT1ItiMask & InputsBuf) != 0) && (ZT1ItiMask == mReversedItiMask)) || //If there is a ZT1 itinerary commanded AND this CDV is part of itinerary + (((ZT2ItiMask & InputsBuf) != 0) && ((ZT2ItiMask & mReversedItiMask) != 0)) ) //OR if there is a ZT2 itinerary commanded AND this CDV is part of itinerary + { + mIsItiCommanded = true; + mCDVState = CDV_STATE_ITI_CMD; + mCurSwitchPosition = SWITCH_CDV_REVERSE_POSITION; + } + + + if((mCDVInputMask & InputsBuf) == 0) //Check if CDV is occupied + { + mIsOccupied = true; + mCDVState = CDV_STATE_OCCUPIED; + } + return RET_OK; +} + +void CSwitchCDV::SetNormalItiMask(unsigned int Mask) +{ + mNormalItiMask = Mask; +} + +void CSwitchCDV::SetReverseItiMask(unsigned int Mask) +{ + mReversedItiMask = Mask; +} diff --git a/sources/SwitchCDV.h b/sources/SwitchCDV.h new file mode 100644 index 0000000..d25e453 --- /dev/null +++ b/sources/SwitchCDV.h @@ -0,0 +1,55 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130603 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef SWITCHCDV_H +#define SWITCHCDV_H + +#include "GlobalDefine.h" +#include "CDV.h" +#include "CDVItem.h" +#include "ZTData.h" + +class CSwitchCDV : public CCDV +{ +public: + CSwitchCDV(); + CSwitchCDV(unsigned int CDVNormalITIMask, unsigned int CDVReversedITIMask, unsigned int CDVInputMask, unsigned int CDVType, QString CDVLabel, unsigned int CDVWay, unsigned int CDVGraphicalPosition); + + virtual unsigned int ComputeCDVState(unsigned int InputsBuf,unsigned int ZT1ItiMask, unsigned int ZT2ItiMask); + unsigned int GetSwitchState(){return mCurSwitchPosition;} + void SetNormalItiMask(unsigned int Mask); + void SetReverseItiMask(unsigned int Mask); + + +private: + unsigned int mNormalItiMask, mReversedItiMask; + unsigned int mCurSwitchPosition; + + +}; + +#endif // SWITCHCDV_H diff --git a/sources/TCPProtocol.cpp b/sources/TCPProtocol.cpp new file mode 100644 index 0000000..8a4a1eb --- /dev/null +++ b/sources/TCPProtocol.cpp @@ -0,0 +1,419 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2015 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe qui contient toute la logique du protocole de communication par réseau + entre la Zone Test et le logiciel d'analyse. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "TCPProtocol.h" +#include +#include +#include + +CTCPProtocol::CTCPProtocol() +{ +} + // +unsigned int CTCPProtocol::AnalyzeNewData(QByteArray data) +{ + QDataStream stream(data); + stream.device()->seek(0); + + switch(mProtocolRxState) + { + case TCP_PROTOCOL_GET_HEADER_STATE: + { + quint32 header = 0; + qint32 msg = 0; + + stream >> header; + + if(header != TCP_PROTOCOL_HEADER) + { + return RET_ERROR; + } + + stream >> msg; + stream >> mCurTransactionDataSize; + + mCurTransactionMsg = (eTCPMessage)msg; + + if(mCurTransactionDataSize != 0) + { + mCurTransactionData = stream.device()->readAll(); + if(mCurTransactionData.size() < mCurTransactionDataSize) + { + mProtocolRxState = TCP_PROTOCOL_GET_DATA_STATE; + } + else if(mCurTransactionData.size() > mCurTransactionDataSize) + { + //error + qDebug("Rx data > Transaction data. Aborting transaction"); + ResetRxStateMachine(); + } + else + { + DecodeTCPMessage(); + ResetRxStateMachine(); + } + } + else + { + DecodeTCPMessage(); + ResetRxStateMachine(); + } + + break; + } + case TCP_PROTOCOL_GET_MSG_STATE: + { + break; + } + case TCP_PROTOCOL_GET_DATASIZE_STATE: + { + break; + } + case TCP_PROTOCOL_GET_DATA_STATE: + { + mCurTransactionData.append(data); + if(mCurTransactionData.size() == mCurTransactionDataSize) + { + //All data received + DecodeTCPMessage(); + ResetRxStateMachine(); + } + else if(mCurTransactionData.size() > mCurTransactionDataSize) + { + //error + qDebug("Rx data > Transaction data. Aborting transaction"); + ResetRxStateMachine(); + } + else + { + qDebug() << "Chunk received. New data size = " << mCurTransactionData.size(); + } + break; + } + } + + return RET_OK; +} + +QByteArray CTCPProtocol::GetHeartbeatPacket() +{ + QByteArray request; + QDataStream stream(&request,QIODevice::WriteOnly); + stream.device()->seek(0); + + request.clear(); + stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_HEARTBEAT_RESPONSE << (qint64)0; ; + //no data... + + // TCPTxRequest(request); + + + return request; +} + +QByteArray CTCPProtocol::GetStationNamePacket(QString StationName) +{ + QByteArray request; + QDataStream stream(&request,QIODevice::WriteOnly); + stream.device()->seek(0); + + + request.clear(); + stream << TCP_PROTOCOL_HEADER; + stream << (qint32)TCP_MSG_STATION_NAME_RESPONSE; + stream << (qint64)StationName.size(); + request.append(StationName); + + //no data... + + // TCPTxRequest(request); + return request; +} + +QByteArray CTCPProtocol::GetZTStatusPacket(CTCPZTStatus *Status) +{ + QByteArray request; + request.clear(); + QByteArray data; + data.clear(); + + QDataStream datastream(&data,QIODevice::WriteOnly); + datastream.device()->seek(0); + datastream << *Status; + + QDataStream requeststream(&request,QIODevice::WriteOnly); + requeststream.device()->seek(0); + + requeststream << TCP_PROTOCOL_HEADER + << (qint32)TCP_MSG_ZT_STATUS_RESPONSE + << (qint64)data.size(); + + request.append(data); + + // TCPTxRequest(request); + + return request; +} + +QByteArray CTCPProtocol::GetZTLogPacket(QString *ZTLog) +{ + QByteArray request; + request.clear(); + QByteArray data; + data.clear(); + + data = ZTLog->toUtf8(); + + QDataStream requeststream(&request,QIODevice::WriteOnly); + requeststream.device()->seek(0); + + requeststream << TCP_PROTOCOL_HEADER + << (qint32)TCP_MSG_ZTLOG_DOWNLOAD_RESPONSE + << (qint64)data.size(); + + request.append(data); + return request; +} + +QByteArray CTCPProtocol::GetTrainLogsDownloadAckPacket(qint32 FileCount) +{ + QByteArray request; + request.clear(); + + QDataStream requeststream(&request,QIODevice::WriteOnly); + requeststream.device()->seek(0); + + requeststream << TCP_PROTOCOL_HEADER + << (qint32)TCP_MSG_TRAINSLOGS_DOWNLOAD_ACK + << (qint64)sizeof(FileCount) + << FileCount; + + return request; +} + +QByteArray *CTCPProtocol::GetTrainLogDataPacket(const QByteArray &FileData) +{ + QByteArray *request = new QByteArray; + request->clear(); + + QDataStream requeststream(request,QIODevice::WriteOnly); + requeststream.device()->seek(0); + + requeststream << TCP_PROTOCOL_HEADER + << (qint32)TCP_MSG_TRAINLOG_FILE_DATA + << (qint64)FileData.size(); + + request->append(FileData); + + return request; //MUST BE DELETED BY CALLER !!!! +} + +QByteArray CTCPProtocol::GetTrainLogsDownloadFinishedPacket() +{ + QByteArray request; + QDataStream stream(&request,QIODevice::WriteOnly); + stream.device()->seek(0); + + request.clear(); + stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_TRAINLOGS_DOWNLOAD_FINISHED << (qint64)0; ; + + return request; +} + +QByteArray CTCPProtocol::GetDeleteZTLogsAckPacket(qint32 Acknowledge) +{ + QByteArray request; + QDataStream stream(&request,QIODevice::WriteOnly); + stream.device()->seek(0); + + request.clear(); + stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_DELETE_ZTLOG_ACK << (qint64)4 << Acknowledge; + + return request; +} + +QByteArray CTCPProtocol::GetSetZTFunctionsConfigAckPacket(qint32 Ack) +{ + QByteArray request; + QDataStream stream(&request,QIODevice::WriteOnly); + stream.device()->seek(0); + + request.clear(); + stream << TCP_PROTOCOL_HEADER << (qint32)TCP_MSG_SET_ZT_FUNCTIONS_ACK << (qint64)4 << Ack; + + return request; +} + + +void CTCPProtocol::TCPTxRequest(QByteArray request) +{ + Q_UNUSED(request) + qDebug("No reimplementation of TXRequest in TCPProtocol.c. Request not sent..."); +} + +void CTCPProtocol::ResetRxStateMachine() +{ + mCurTransactionData.clear(); + mCurTransactionDataSize = 0; + mCurTransactionMsg = TCP_MSG_UNKNOWN; + mProtocolRxState = TCP_PROTOCOL_GET_HEADER_STATE; + +} + +int CTCPProtocol::DecodeTCPMessage() +{ + switch(mCurTransactionMsg) + { + case TCP_MSG_HEARTBEAT_REQUEST: + { + TCPHeartbeatRequest(); + break; + } + case TCP_MSG_STATION_NAME_REQUEST: + { + TCPStationNameRequest(); + break; + } + case TCP_MSG_ZT_STATUS_REQUEST: + { + TCPStatusRequest(); + break; + } + case TCP_MSG_ZTLOG_DOWNLOAD_REQUEST: + { + TCPZTLogDownloadRequest(); + break; + } + case TCP_MSG_TRAINLOGS_DOWNLOAD_REQUEST: + { + TCPTrainLogsDownloadRequest(); + break; + } + case TCP_MSG_TRAINLOG_FILE_DATA_ACK: + { + qint32 ack = TCP_PROTOCOL_INVALID_ACK; + QDataStream strm(mCurTransactionData); + strm.device()->seek(0); + strm >> ack; + + TCPTrainLogFileDataAck((eTCPProtocolAcknowledge)ack); + + break; + } + case TCP_MSG_DELETE_ZTLOG_REQUEST: + { + TCPDeleteZTLogRequest(); + break; + } + case TCP_MSG_SET_ZT_FUNCTIONS: + { + TCPSetZTFunctionsConfigRequest(mCurTransactionData); + break; + } + + case TCP_MSG_SET_ZT_FUNCTIONS_ACK: + case TCP_MSG_DELETE_ZTLOG_ACK: + case TCP_MSG_ZT_STATUS_RESPONSE: + case TCP_MSG_HEARTBEAT_RESPONSE: + case TCP_MSG_STATION_NAME_RESPONSE: + case TCP_MSG_ZTLOG_DOWNLOAD_RESPONSE: + case TCP_MSG_TRAINSLOGS_DOWNLOAD_ACK: + case TCP_MSG_TRAINLOG_FILE_DATA: + case TCP_MSG_TRAINLOGS_DOWNLOAD_FINISHED: + case TCP_MSG_UNKNOWN: + { + qDebug() << "Received invalid msg:" << mCurTransactionMsg; + break; + } + } + + return RET_OK; +} + +QDataStream &operator<<(QDataStream &out, const CTCPZTStatus &source) +{ + out << source.mZT1Status + << source.mZT2Status + << source.mNbPass + << source.mNbTrigs + << source.mZTStartDateTime + << source.mActualDateTime + << source.mPGTreshold + << source.mModeMaintenanceON + << source.mCalibModeON + << source.mFNTKActive + << source.mFNAnalysisActive + << source.mPGTKActive + << source.mPGAnalysisActive + << source.mPP1TKActive + << source.mPP1AnalysisActive + << source.mPP2TKActive + << source.mPP2AnalysisActive + << source.mZT1TKActive + << source.mZT1AnalysisActive + << source.mZT2TKActive + << source.mZT2AnalysisActive + << source.mUSBKeyConnected; + + return out; +} +QDataStream &operator>>(QDataStream &in, CTCPZTFunctionsStatus &dest) +{ + in >> dest.mFNTKActive + >> dest.mFNAnalysisActive + >> dest.mPGTKActive + >> dest.mPGAnalysisActive + >> dest.mPP1TKActive + >> dest.mPP1AnalysisActive + >> dest.mPP2TKActive + >> dest.mPP2AnalysisActive + >> dest.mZT1TKActive + >> dest.mZT1AnalysisActive + >> dest.mZT2TKActive + >> dest.mZT2AnalysisActive; + + return in; +} + +QDataStream &operator<<(QDataStream &out, const CTCPZTFunctionsStatus &source) +{ + out << source.mFNTKActive + << source.mFNAnalysisActive + << source.mPGTKActive + << source.mPGAnalysisActive + << source.mPP1TKActive + << source.mPP1AnalysisActive + << source.mPP2TKActive + << source.mPP2AnalysisActive + << source.mZT1TKActive + << source.mZT1AnalysisActive + << source.mZT2TKActive + << source.mZT2AnalysisActive; + + return out; +} diff --git a/sources/TCPProtocol.h b/sources/TCPProtocol.h new file mode 100644 index 0000000..0b061e2 --- /dev/null +++ b/sources/TCPProtocol.h @@ -0,0 +1,149 @@ +#ifndef TCPPROTOCOL_H +#define TCPPROTOCOL_H + +#include "GlobalDefine.h" +#include +#include + +#define TCP_PROTOCOL_HEADER (quint32)0xDEADCAFE + +class CTCPZTStatus +{ +public: + quint32 mZT1Status; // + quint32 mZT2Status; + quint32 mNbPass; + quint32 mNbTrigs; + + QDateTime mZTStartDateTime; + QDateTime mActualDateTime; + + qint32 mPGTreshold; + + bool mModeMaintenanceON; + bool mCalibModeON; + + bool mFNTKActive; + bool mFNAnalysisActive; + bool mPGTKActive; + bool mPGAnalysisActive; + bool mPP1TKActive; + bool mPP1AnalysisActive; + bool mPP2TKActive; + bool mPP2AnalysisActive; + bool mZT1TKActive; + bool mZT1AnalysisActive; + bool mZT2TKActive; + bool mZT2AnalysisActive; + + bool mUSBKeyConnected; +}; + +QDataStream &operator<<(QDataStream &out, const CTCPZTStatus &source); +//QDataStream &operator>>(QDataStream &in, CTCPZTStatus &dest); + +class CTCPProtocol +{ + public: + + typedef enum + { + TCP_MSG_HEARTBEAT_REQUEST, + TCP_MSG_HEARTBEAT_RESPONSE, + TCP_MSG_STATION_NAME_REQUEST, + TCP_MSG_STATION_NAME_RESPONSE, + TCP_MSG_ZT_STATUS_REQUEST, + TCP_MSG_ZT_STATUS_RESPONSE, + TCP_MSG_ZTLOG_DOWNLOAD_REQUEST, + TCP_MSG_ZTLOG_DOWNLOAD_RESPONSE, + + TCP_MSG_TRAINLOGS_DOWNLOAD_REQUEST, + TCP_MSG_TRAINSLOGS_DOWNLOAD_ACK, + TCP_MSG_TRAINLOG_FILE_DATA, + TCP_MSG_TRAINLOG_FILE_DATA_ACK, + TCP_MSG_TRAINLOGS_DOWNLOAD_FINISHED, + TCP_MSG_DELETE_ZTLOG_REQUEST, + TCP_MSG_DELETE_ZTLOG_ACK, + TCP_MSG_SET_ZT_FUNCTIONS, + TCP_MSG_SET_ZT_FUNCTIONS_ACK, + + TCP_MSG_UNKNOWN + }eTCPMessage; + + typedef enum + { + TCP_PROTOCOL_GET_HEADER_STATE, + TCP_PROTOCOL_GET_MSG_STATE, + TCP_PROTOCOL_GET_DATASIZE_STATE, + TCP_PROTOCOL_GET_DATA_STATE + }eTCPProtocolState; + + typedef enum + { + TCP_PROTOCOL_NACK, + TCP_PROTOCOL_ACK, + TCP_PROTOCOL_NACK_ABORT, + TCP_PROTOCOL_INVALID_ACK + }eTCPProtocolAcknowledge; + + CTCPProtocol(); + + virtual void TCPTxRequest(QByteArray request) = 0; + + unsigned int AnalyzeNewData(QByteArray data); + + QByteArray GetHeartbeatPacket(); + QByteArray GetStationNamePacket(QString StationName); + QByteArray GetZTStatusPacket(CTCPZTStatus *Status); + QByteArray GetZTLogPacket(QString *ZTLog); + QByteArray GetTrainLogsDownloadAckPacket(qint32 FileCount); + QByteArray *GetTrainLogDataPacket(const QByteArray &FileData); //MUST BE DELETED BY CALLER + QByteArray GetTrainLogsDownloadFinishedPacket(); + QByteArray GetDeleteZTLogsAckPacket(qint32 Acknowledge); + QByteArray GetSetZTFunctionsConfigAckPacket(qint32 Ack); + + + virtual void TCPHeartbeatRequest() = 0; + virtual void TCPStationNameRequest() = 0; + virtual void TCPStatusRequest() = 0; + virtual void TCPZTLogDownloadRequest() = 0; + virtual void TCPTrainLogsDownloadRequest() = 0; + virtual void TCPTrainLogFileDataAck(eTCPProtocolAcknowledge Acknowledge) = 0; + virtual void TCPDeleteZTLogRequest() = 0; + virtual void TCPSetZTFunctionsConfigRequest(QByteArray &Data) = 0; + + + + + +private: + eTCPProtocolState mProtocolRxState; + eTCPMessage mCurTransactionMsg; + qint64 mCurTransactionDataSize; + QByteArray mCurTransactionData; + + void ResetRxStateMachine(); + int DecodeTCPMessage(); + +}; +class CTCPZTFunctionsStatus +{ +public: + bool mFNTKActive; + bool mFNAnalysisActive; + bool mPGTKActive; + bool mPGAnalysisActive; + bool mPP1TKActive; + bool mPP1AnalysisActive; + bool mPP2TKActive; + bool mPP2AnalysisActive; + bool mZT1TKActive; + bool mZT1AnalysisActive; + bool mZT2TKActive; + bool mZT2AnalysisActive; +}; +QDataStream &operator>>(QDataStream &in, CTCPZTFunctionsStatus &dest); +QDataStream &operator<<(QDataStream &out, const CTCPZTFunctionsStatus &source); + + +#endif // TCPPROTOCOL_H diff --git a/sources/TKGenerator.cpp b/sources/TKGenerator.cpp new file mode 100644 index 0000000..62da299 --- /dev/null +++ b/sources/TKGenerator.cpp @@ -0,0 +1,724 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe qui contient la logique et la machine à états pour l'émission des + alarmes (TK) au PCC via le module de sorties externes. Lorsqu'une nouvelle + détection arrive via la fonction ProcessDetectionsTK(), la classe vérifie + si la fonction est désactivée et ajoute la TK dans une liste. Une machine + à état s'occupe d'émettre les TK en fonction des entrées d'annulation AN1 ou + AN2 ou lors de l'acquitement automatique. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "TKGenerator.h" +#include "EngLog.h" +#include "ZTLog.h" +#include +#include "ZTData.h" +#include +#include "TKTransportInterface.h" + +CTKGenerator::CTKGenerator(CTKTransportInterface *IF) +{ +// mOutputMasks = 0; +// mOutputModule = 0; + + mTKInterface = IF; + +// mMaintenanceMode = false; +// mForceZT1Clear = false; +// mForceZT2Clear = false; + + +// //mClearZT1AlarmMask = mClearZT2AlarmMask = 0; +// mAN1State = mZT1CDVState = mAN2State = mZT2CDVState = false; + +// mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; +// mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; + + // mZT1TKBuffer.clear(); +// mZT1TKDataList.clear(); + // mZT2TKBuffer.clear(); + // mZT2TKDataList.clear(); +// mZT1CurTKIndex = 0; +// mZT2CurTKIndex = 0; + +// mZT1TKStateMachineTimer = new QTimer(); +// mZT1TKStateMachineTimer->setSingleShot(false); +// connect(mZT1TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT1SM())); + +// mZT2TKStateMachineTimer = new QTimer(); +// mZT2TKStateMachineTimer->setSingleShot(false); +// connect(mZT2TKStateMachineTimer,SIGNAL(timeout()),this,SLOT(ExecZT2SM())); + + ResetAlarmCount(); +} + +CTKGenerator::~CTKGenerator() +{ +// delete mZT1TKStateMachineTimer; +// delete mZT2TKStateMachineTimer; +} + +//void CTKGenerator::BindPointers(GenericOutputMasks_t *OutputMasks, COutputModule *OutputModule) +//{ +// mOutputMasks = OutputMasks; +// mOutputModule = OutputModule; + + + +// mClearZT1AlarmMask = mOutputMasks->OutputVP1Mask | mOutputMasks->OutputVP2Mask | mOutputMasks->OutputVP3Mask | mOutputMasks->OutputVP4Mask |\ +// mOutputMasks->OutputVP5Mask | mOutputMasks->OutputVP6Mask | mOutputMasks->OutputVF1Mask | mOutputMasks->OutputVF2Mask |\ +// mOutputMasks->OutputVF3Mask | mOutputMasks->OutputVF4Mask | mOutputMasks->OutputVF5Mask | mOutputMasks->OutputDPEMask |\ +// mOutputMasks->OutputDPIMask | mOutputMasks->OutputV00Mask | mOutputMasks->OutputDPGMask | mOutputMasks->OutputDFRMask |\ +// mOutputMasks->OutputPEQ1Mask; + +// mClearZT2AlarmMask = mOutputMasks->OutputWP1Mask | mOutputMasks->OutputWP2Mask | mOutputMasks->OutputWP3Mask | mOutputMasks->OutputWP4Mask |\ +// mOutputMasks->OutputWP5Mask | mOutputMasks->OutputWP6Mask | mOutputMasks->OutputDPI2Mask | mOutputMasks->OutputDPE2Mask |\ +// mOutputMasks->OutputV002Mask | mOutputMasks->OutputPEQ2Mask; +//} + +//void CTKGenerator::BindTransportInterface(CTKTransportInterface *IF) +//{ +// // mTKInterface = IF; +//} + +bool CTKGenerator::UpdateDetectionConfig(CZTDetectionFunctionConfig *Config) +{ + //if(mZT2TKGeneratorState != TK_GENERATOR_ZT2_STANDBY_STATE || mZT1TKGeneratorState != TK_GENERATOR_ZT1_STANDBY_STATE) //JFM Modbus + if(mTKInterface->IsZT2TKProcessing() || mTKInterface->IsZT1TKProcessing()) //JFM Modbus + { + return false; + } + + mZTDetectionConfig = Config; + return true; +} + +unsigned int CTKGenerator::ProcessDetectionsTK(CZTDetectionData *NewDetection) +{ + + // quint32 TKFlags = 0; + // quint32 Rank = NewDetection->mRank;// DetectionsList->at(i)->mRank; + quint32 DetectionID = NewDetection->mDetectionID; //DetectionsList->at(i)->mDetectionID; + + CZTDetectionData DetectionData; + DetectionData.mDetectionID = NewDetection->mDetectionID;; + DetectionData.mRank = NewDetection->mRank; + + switch(DetectionID) + { + case DETECTION_MAGNETIC_SENSOR_COUNT: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive) + { + if(mAlarmCount[DETECTION_MAGNETIC_SENSOR_COUNT] < TK_GENERATOR_MAX_V00X) + { + //mZT1TKDataList.append(DetectionData); + mTKInterface->AddNewZT1Detection(DetectionData); + mAlarmCount[DETECTION_MAGNETIC_SENSOR_COUNT]++; + } + } + break; + } + case DETECTION_FN_DETECTION: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_FN].TKActive) + { + if(mAlarmCount[DETECTION_FN_DETECTION] < TK_GENERATOR_MAX_ALARMS) + { + //mZT1TKDataList.append(DetectionData); + mTKInterface->AddNewZT1Detection(DetectionData); + mAlarmCount[DETECTION_FN_DETECTION]++; + } + } + break; + } + case DETECTION_PG_DETECTION: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_PG].TKActive) + { + if(mAlarmCount[DETECTION_PG_DETECTION] < TK_GENERATOR_MAX_ALARMS) + { + //mZT1TKDataList.append(DetectionData); + mTKInterface->AddNewZT1Detection(DetectionData); + mAlarmCount[DETECTION_PG_DETECTION]++; + } + } + break; + } + case DETECTION_PPI_DETECTION: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_PP].TKActive) + { + if(mAlarmCount[DETECTION_PPI_DETECTION] < TK_GENERATOR_MAX_ALARMS) + { + //mZT1TKDataList.append(DetectionData); + mTKInterface->AddNewZT1Detection(DetectionData); + mAlarmCount[DETECTION_PPI_DETECTION]++; + } + } + break; + } + case DETECTION_PPE_DETECTION: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_PP].TKActive) + { + if(mAlarmCount[DETECTION_PPE_DETECTION] < TK_GENERATOR_MAX_ALARMS) + { + //mZT1TKDataList.append(DetectionData); + mTKInterface->AddNewZT1Detection(DetectionData); + mAlarmCount[DETECTION_PPE_DETECTION]++; + } + } + break; + } + case DETECTION_PEQ1_DETECTION: + { + + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive) + { + if(mAlarmCount[DETECTION_PEQ1_DETECTION] < TK_GENERATOR_MAX_PEQ) + { + //mZT1TKDataList.append(DetectionData); + mTKInterface->AddNewZT1Detection(DetectionData); + mAlarmCount[DETECTION_PEQ1_DETECTION]++; + } + } + break; + } + case DETECTION_PEQ2_DETECTION: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive) + { + if(mAlarmCount[DETECTION_PEQ2_DETECTION] < TK_GENERATOR_MAX_PEQ) + { + // mZT2TKDataList.append(DetectionData); + mTKInterface->AddNewZT2Detection(DetectionData); + mAlarmCount[DETECTION_PEQ2_DETECTION]++; + } + } + break; + } + case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive) + { + if(mAlarmCount[DETECTION_ZT2_MAGNETIC_SENSOR_COUNT] < TK_GENERATOR_MAX_V00X) + { + //mZT2TKDataList.append(DetectionData); + mTKInterface->AddNewZT2Detection(DetectionData); + mAlarmCount[DETECTION_ZT2_MAGNETIC_SENSOR_COUNT]++; + } + } + break; + } + case DETECTION_ZT2_PPI_DETECTION: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive) + { + if(mAlarmCount[DETECTION_ZT2_PPI_DETECTION] < TK_GENERATOR_MAX_ALARMS) + { + //mZT2TKDataList.append(DetectionData); + mTKInterface->AddNewZT2Detection(DetectionData); + mAlarmCount[DETECTION_ZT2_PPI_DETECTION]++; + } + } + break; + } + case DETECTION_ZT2_PPE_DETECTION: + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive) + { + if(mAlarmCount[DETECTION_ZT2_PPE_DETECTION] < TK_GENERATOR_MAX_ALARMS) + { + //mZT2TKDataList.append(DetectionData); + mTKInterface->AddNewZT2Detection(DetectionData); + mAlarmCount[DETECTION_ZT2_PPE_DETECTION]++; + } + } + break; + } + } + + return RET_OK; +} + +//unsigned int CTKGenerator::BeginTKEmission() +//{ +// return mTKInterface->BeginTKEmission(); + +//// if(mTKInterface->IsTKProcessing()) +//// return RET_ERROR; + + + + +//// if(mZT1TKDataList.size() > 0) //JFM Modbus +//// { +//// if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive == false) +//// { +//// mZT1TKDataList.clear(); +//// } +//// else if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE) +//// { +//// mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_TK_STATE; +//// mTKInterface->ClearTK(ZT1_TYPE_ID); //JFM Modbus +//// mZT1TKStateMachineTimer->start(0); +//// } +//// } + + +//// if(mZT2TKDataList.size() > 0) //JFM Modbus +//// { +//// if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive == false) +//// { +//// mZT2TKDataList.clear(); +//// } +//// else if(mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE) +//// { +//// mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_TK_STATE; +//// mTKInterface->ClearTK(ZT2_TYPE_ID); //JFM Modbus +//// mZT2TKStateMachineTimer->start(0); +//// } +//// } +//// return RET_OK; +//} + +//unsigned int CTKGenerator::SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState) +//{ + +// return mTKInterface->SetInputStates(AN1State,ZT1CDVState,AN2State,ZT2CDVState); +//// mAN1State = AN1State; +//// mZT1CDVState = ZT1CDVState; +//// mAN2State = AN2State; +//// mZT2CDVState = ZT2CDVState; + +//// return RET_OK; +//} + + + + + + + +//void CTKGenerator::ExecZT1SM() +//{ +// switch(mZT1TKGeneratorState) +// { +// case TK_ZT1_GENERATOR_SHOW_TK_STATE: +// { +//// if(mZT1CurTKIndex >= mZT1TKBuffer.size()) //JFM Modbus +// if(mZT1CurTKIndex >= mZT1TKDataList.size()) +// { +// mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; +// } +// else +// { +//// mOutputModule->SetOutputFlags(mZT1TKBuffer.at(mZT1CurTKIndex++)); +// mTKInterface->SendTKToCC(mZT1TKDataList.at(mZT1CurTKIndex++)); //JFM Modbus +// mZT1TKGeneratorState = TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE; + +// CZTLog::instance()->AddLogString("Émission d'une TK ZT1 au PCC",true); +// LogTK(mZT1TKDataList.at(mZT1CurTKIndex-1)); + + +// if(mMaintenanceMode) +// { +// emit TKOutputStatesChanged(true,false); +// } +// } + +// break; +// } +// case TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE: +// { +// if(mAN1State == true || (mMaintenanceMode == true && mForceZT1Clear == true)) +// { +// //clear the TK bits +// //mOutputModule->ClearOutputFlags(mClearZT1AlarmMask); +// mTKInterface->ClearTK(ZT1_TYPE_ID); //JFM Modbus +// mZT1RefTimer.start(); +// mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_ZERO_STATE; + +// if(mMaintenanceMode == true) +// { +// if(mForceZT1Clear == true) +// { +// mForceZT1Clear = false; +// CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT1",true); +// } +// else +// { +// CZTLog::instance()->AddLogString("Acquitement AN1 détectée",true); +// } + +// emit TKOutputStatesChanged(false,false); + +// } +// else +// { +// CZTLog::instance()->AddLogString("Acquitement AN1 détectée",true); +// } +// } +// else if(mZT1CDVState == false && mMaintenanceMode == false) +// { +// //Enter the auto acquitment TK generation mode... +// //A TK is already output, make shure it's there long enough. +// CZTLog::instance()->AddLogString("Libération du CDV de quai ZT1. Début de l'acquitement automatique",true); +// mZT1RefTimer.start(); +// mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; +// } + +// break; +// } +// case TK_ZT1_GENERATOR_SHOW_ZERO_STATE: +// { +// if(mZT1RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) +// { +// mZT1TKGeneratorState = TK_ZT1_GENERATOR_SHOW_TK_STATE; +// } +// break; +// } +// case TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE: +// { +// //if(mZT1CurTKIndex >= mZT1TKBuffer.size()) +// if(mZT1CurTKIndex >= mZT1TKDataList.size()) //JF Modbus +// { +// mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; +// } +// else +// { +//// mOutputModule->SetOutputFlags(mZT1TKBuffer.at(mZT1CurTKIndex++)); +// mTKInterface->SendTKToCC(mZT1TKDataList.at(mZT1CurTKIndex++)); //JFM Modbus +// mZT1RefTimer.start(); +// mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; +// CZTLog::instance()->AddLogString("Émission d'une TK ZT1 au PCC",true); +// LogTK(mZT1TKDataList.at(mZT1CurTKIndex-1)); +// } +// break; +// } +// case TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE: +// { +// if(mZT1RefTimer.elapsed() >= TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT) +// { +// //mOutputModule->ClearOutputFlags(mClearZT1AlarmMask); +// mTKInterface->ClearTK(ZT1_TYPE_ID); //JFM Modbus +// mZT1RefTimer.start(); +// mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE; +// CZTLog::instance()->AddLogString("Acquitement automatique TK ZT1",true); +// } +// break; +// } +// case TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE: +// { +// if(mZT1RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) +// { +// //emit next TK +// mZT1TKGeneratorState = TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE; +// } +// break; +// } + +// case TK_GENERATOR_ZT1_STANDBY_STATE: +// { +// // mZT1TKBuffer.clear(); +// mZT1TKDataList.clear(); +// mZT1CurTKIndex = 0; +// mZT1TKStateMachineTimer->stop(); +// ResetAlarmCount(); + +// //In maintenance mode, it is possible to have ZT2 events at the same time +// //than ZT1. So if any ZT2 events are waiting in the qeue, send them... +// if(mMaintenanceMode) +// { +//// if(mZT2TKBuffer.size() > 0) +// if(mZT2TKDataList.size() > 0) //JFM Modbus +// { +// BeginTKEmission(); +// } +// } + +// break; +// } +// } +//} + +//void CTKGenerator::ExecZT2SM() +//{ +// switch(mZT2TKGeneratorState) +// { +// case TK_ZT2_GENERATOR_SHOW_TK_STATE: +// { +//// if(mZT2CurTKIndex >= mZT2TKBuffer.size()) +// if(mZT2CurTKIndex >= mZT2TKDataList.size()) //JFM Modbus +// { +// mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; +// } +// else +// { +//// mOutputModule->SetOutputFlags(mZT2TKBuffer.at(mZT2CurTKIndex++)); +// mTKInterface->SendTKToCC(mZT2TKDataList.at(mZT2CurTKIndex++));//JFM Modbus +// mZT2TKGeneratorState = TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE; +// CZTLog::instance()->AddLogString("Émission d'une TK ZT2 au PCC",true); +// LogTK(mZT2TKDataList.at(mZT2CurTKIndex-1)); +// if(mMaintenanceMode) +// { +// emit TKOutputStatesChanged(false,true); +// } +// } +// break; +// } +// case TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE: +// { +// if(mAN2State == true || (mMaintenanceMode == true && mForceZT2Clear == true)) +// { +// //clear the TK bits +// //mOutputModule->ClearOutputFlags(mClearZT2AlarmMask); +// mTKInterface->ClearTK(ZT2_TYPE_ID); //JFM Modbus +// mZT2RefTimer.start(); +// mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_ZERO_STATE; +// if(mMaintenanceMode == true) +// { +// if(mForceZT2Clear == true) +// { +// mForceZT2Clear = false; +// CZTLog::instance()->AddLogString("Acquitement manuel de la TK ZT2",true); +// } +// else +// { +// CZTLog::instance()->AddLogString("Acquitement AN2 détectée",true); +// } + +// emit TKOutputStatesChanged(false,false); +// } +// else +// { +// CZTLog::instance()->AddLogString("Acquitement AN2 détectée",true); +// } +// } +// else if(mZT2CDVState == false && mMaintenanceMode == false) +// { +// //Enter the auto acquitment TK generation mode... +// //A TK is already output, make shure it's there long enough. +// CZTLog::instance()->AddLogString("Libération du CDV ZT2. Début de l'acquitement automatique",true); +// mZT2RefTimer.start(); +// mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; +// } +// break; +// } +// case TK_ZT2_GENERATOR_SHOW_ZERO_STATE: +// { +// if(mZT2RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) +// { +// mZT2TKGeneratorState = TK_ZT2_GENERATOR_SHOW_TK_STATE; +// } +// break; +// } +// case TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE: +// { +// //if(mZT2CurTKIndex >= mZT2TKBuffer.size()) +// if(mZT2CurTKIndex >= mZT2TKDataList.size()) //JFM Modbus +// { +// mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; +// } +// else +// { +// //mOutputModule->SetOutputFlags(mZT2TKBuffer.at(mZT2CurTKIndex++)); +// mTKInterface->SendTKToCC(mZT2TKDataList.at(mZT2CurTKIndex++)); //JFM Modbus +// mZT2RefTimer.start(); +// mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE; +// CZTLog::instance()->AddLogString("Émission d'une TK ZT2 au PCC",true); +// //LogTK(mZT2TKBuffer.at(mZT2CurTKIndex-1)); +// LogTK(mZT2TKDataList.at(mZT2CurTKIndex-1)); +// } +// break; +// } +// case TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE: +// { +// if(mZT2RefTimer.elapsed() >= TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT) +// { +// //mOutputModule->ClearOutputFlags(mClearZT2AlarmMask); +// mTKInterface->ClearTK(ZT2_TYPE_ID); //JFM Modbus +// mZT2RefTimer.start(); +// mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE; +// CZTLog::instance()->AddLogString("Acquitement automatique ZT2",true); +// } +// break; +// } +// case TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE: +// { +// if(mZT2RefTimer.elapsed() >= TK_GENERATOR_SHOW_ZERO_TIMEOUT) +// { +// //emit next TK +// mZT2TKGeneratorState = TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE; +// } +// break; +// } + +// case TK_GENERATOR_ZT2_STANDBY_STATE: +// { +//// mZT2TKBuffer.clear(); //JFM Modbus +// mZT2TKDataList.clear(); +// mZT2CurTKIndex = 0; +// mZT2TKStateMachineTimer->stop(); +// ResetAlarmCount(); + +// //In maintenance mode, it is possible to have ZT2 events at the same time +// //than ZT1. So if any ZT1 events are waiting in the qeue, send them... +// if(mMaintenanceMode) +// { +// //if(mZT1TKBuffer.size() > 0) +// if(mZT1TKDataList.size() > 0) //JFM Modbus +// { +// BeginTKEmission(); +// } +// } + +// break; +// } +// } +//} + +void CTKGenerator::ResetAlarmCount() +{ + for(int i = 0; i < DETECTION_MAX_DETECTION_ID; i++) + { + mAlarmCount[i] = 0; + } +} + +//unsigned int CTKGenerator::CancelAllTK() +//{ +// mTKInterface->ClearTK(ZT1_TYPE_ID); //JFM Modbus +// mTKInterface->ClearTK(ZT2_TYPE_ID); + +// mZT1TKGeneratorState = TK_GENERATOR_ZT1_STANDBY_STATE; +// mZT2TKGeneratorState = TK_GENERATOR_ZT2_STANDBY_STATE; + +//// mZT1TKBuffer.clear(); +// mZT1TKDataList.clear(); +//// mZT2TKBuffer.clear(); +// mZT2TKDataList.clear(); + + +// //exec the SM once +// mZT1TKStateMachineTimer->start(); +// mZT2TKStateMachineTimer->start(); +// ResetAlarmCount(); + +// return RET_OK; +//} + +//unsigned int CTKGenerator::CancelMaintenanceCurrentTK() +//{ + +// if(mZT1TKGeneratorState == TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE) +// { +// mForceZT1Clear = true; +// return RET_OK; +// } +// else if(mZT2TKGeneratorState == TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE) +// { +// mForceZT2Clear = true; +// return RET_OK; +// } +// return RET_ERROR; +//} + + +//unsigned int CTKGenerator::ExitMaintenance() +//{ + +// mMaintenanceMode = false; +// mForceZT1Clear = false; +// mForceZT2Clear = false; +// CancelAllTK(); + +// return RET_OK; +//} + +//unsigned int CTKGenerator::EnterMaintenance() +//{ + +// return mTKInterface->E +// if(mTKInterface->IsTKProcessing()) +// { +// return RET_ERROR; +// } + + +// mMaintenanceMode = true; +// mForceZT1Clear = false; +// mForceZT2Clear = false; + +// return RET_OK; +//} + +//bool CTKGenerator::IsTKProcessing() +//{ +// if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE && +// mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE) +// { +// return false; +// } + +// return true; +//} + +//bool CTKGenerator::IsZT1TKProcessing() +//{ +// if(mZT1TKGeneratorState == TK_GENERATOR_ZT1_STANDBY_STATE) +// { +// return false; +// } + +// return true; +//} + +//bool CTKGenerator::IsZT2TKProcessing() +//{ +// if(mZT2TKGeneratorState == TK_GENERATOR_ZT2_STANDBY_STATE) +// { +// return false; +// } + +// return true; +//} + +void CTKGenerator::LogTK(CZTDetectionData DetectionData) +{ + QString str = "TK envoyée: "; + QTextStream stream(&str); + stream.setCodec("UTF-8"); + + stream << QString::fromUtf8(CZTData::GetErrorString(DetectionData.mDetectionID)); + stream << " | Rang: " << DetectionData.mRank; + CZTLog::instance()->AddLogString(str,true); +} + +CZTDetectionFunctionConfig *CTKGenerator::GetDetectionConfig() +{ + return mZTDetectionConfig; +} diff --git a/sources/TKGenerator.h b/sources/TKGenerator.h new file mode 100644 index 0000000..5193813 --- /dev/null +++ b/sources/TKGenerator.h @@ -0,0 +1,121 @@ +#ifndef TKGENERATOR_H +#define TKGENERATOR_H + +#include "Station.h" +#include "ZTData.h" +#include +#include +#include +#include "ExtIOThread.h" + +#define TK_GENERATOR_SHOW_ZERO_TIMEOUT 1000 //the Low state time between two TKs +#define TK_GENERATOR_AUTOMATIC_SHOW_TK_TIMEOUT 2000 //the amount of time the TK must be emited in auto acquitment mode +#define TK_GENERATOR_MAX_ALARMS 4 +#define TK_GENERATOR_MAX_PEQ 1 +#define TK_GENERATOR_MAX_V00X 1 + +//enum eTKGeneratorStaes +//{ +// TK_ZT1_GENERATOR_SHOW_TK_STATE, +// TK_ZT1_GENERATOR_WAIT_FOR_AN1_STATE, +// TK_ZT1_GENERATOR_SHOW_ZERO_STATE, + +// TK_ZT1_GENERATOR_AUTO_SHOW_TK_AUTO_STATE, +// TK_ZT1_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE, +// TK_ZT1_GENERATOR_AUTO_SHOW_ZERO_STATE, + +// TK_ZT1_GENERATOR_FINISH_STATE, + +// TK_GENERATOR_ZT1_STANDBY_STATE, + +// TK_ZT2_GENERATOR_SHOW_TK_STATE, +// TK_ZT2_GENERATOR_WAIT_FOR_AN2_STATE, +// TK_ZT2_GENERATOR_SHOW_ZERO_STATE, + +// TK_ZT2_GENERATOR_AUTO_SHOW_TK_AUTO_STATE, +// TK_ZT2_GENERATOR_AUTO_WAIT_FOR_TIMEOUT_STATE, +// TK_ZT2_GENERATOR_AUTO_SHOW_ZERO_STATE, + +// TK_ZT2_GENERATOR_FINISH_STATE, + +// TK_GENERATOR_ZT2_STANDBY_STATE +//}; + +class CTKTransportInterface; + +class CTKGenerator : public QObject +{ + Q_OBJECT + public: + CTKGenerator(CTKTransportInterface *IF); + virtual ~CTKGenerator(); + + + CTKTransportInterface* mTKInterface; +// void BindPointers(GenericOutputMasks_t *OutputMasks, COutputModule *OutputModule); + //virtual void BindTransportInterface(CTKTransportInterface* IF) = 0; + unsigned int ProcessDetectionsTK(CZTDetectionData *NewDetection); + bool UpdateDetectionConfig(CZTDetectionFunctionConfig*); + void ResetAlarmCount(); + + virtual unsigned int CancelAllTK() = 0; + virtual unsigned int CancelMaintenanceCurrentTK() = 0; + virtual unsigned int ExitMaintenance() = 0; + virtual unsigned int EnterMaintenance() = 0; + virtual unsigned int SetInputStates(bool AN1State, bool ZT1CDVState, bool AN2State, bool ZT2CDVState) = 0; + virtual unsigned int BeginTKEmission() = 0; + + + void LogTK(CZTDetectionData DetectionData); + CZTDetectionFunctionConfig *GetDetectionConfig(); + + +// bool IsTKProcessing(); +// bool IsZT1TKProcessing(); +// bool IsZT2TKProcessing(); + +private: + + CZTDetectionFunctionConfig *mZTDetectionConfig; +// GenericOutputMasks_t *mOutputMasks; + + //COutputModule *mOutputModule; + + + // QList mZT1TKBuffer,mZT2TKBuffer; + // QList mZT1TKDataList,mZT2TKDataList; +// unsigned int mZT1TKGeneratorState,mZT2TKGeneratorState; +// int mZT1CurTKIndex,mZT2CurTKIndex; +// QTimer *mZT1TKStateMachineTimer; +// QTimer *mZT2TKStateMachineTimer; +// QElapsedTimer mZT1RefTimer,mZT2RefTimer; + + // CTKTransportInterface *mTKInterface; + +// bool mAN1State, mZT1CDVState,mAN2State,mZT2CDVState; +// bool mMaintenanceMode, mForceZT1Clear, mForceZT2Clear; + + //quint32 mClearZT1AlarmMask, mClearZT2AlarmMask; + +// quint32 IntegerToBCDZT1(quint32 Value); +// quint32 IntegerToBCDZT2(quint32 Value); +// quint32 IntegerToBCDFN(quint32 Value); + + int mAlarmCount[DETECTION_MAX_DETECTION_ID]; + + // void LogTK(quint32 Value); + + + +public slots: +// void ExecZT1SM(); +// void ExecZT2SM(); + +signals: + void TKOutputStatesChanged(bool ZT1TKActive,bool ZT2TKActive); + + + +}; + +#endif // TKGENERATOR_H diff --git a/sources/TKTransportInterface.cpp b/sources/TKTransportInterface.cpp new file mode 100644 index 0000000..99f5401 --- /dev/null +++ b/sources/TKTransportInterface.cpp @@ -0,0 +1,12 @@ +#include "TKTransportInterface.h" + +CTKTransportInterface::~CTKTransportInterface() +{ + +} + +CTKTransportInterface::CTKTransportInterface(): + CTKGenerator(this) +{ + +} diff --git a/sources/TKTransportInterface.h b/sources/TKTransportInterface.h new file mode 100644 index 0000000..19287a4 --- /dev/null +++ b/sources/TKTransportInterface.h @@ -0,0 +1,23 @@ +#ifndef TKTRANSPORTINTERFACE_H +#define TKTRANSPORTINTERFACE_H + + +#include "TKGenerator.h" +class CZTDetectionData; + + +class CTKTransportInterface : public CTKGenerator +{ +public: + + CTKTransportInterface(); + virtual ~CTKTransportInterface(); + + virtual bool IsTKProcessing() = 0; + virtual bool IsZT1TKProcessing() = 0; + virtual bool IsZT2TKProcessing() = 0; + virtual int AddNewZT1Detection(CZTDetectionData Detection) = 0; + virtual int AddNewZT2Detection(CZTDetectionData Detection) = 0; +}; + +#endif // TKTRANSPORTINTERFACE_H diff --git a/sources/TrainLogFileMgr.cpp b/sources/TrainLogFileMgr.cpp new file mode 100644 index 0000000..2b5baab --- /dev/null +++ b/sources/TrainLogFileMgr.cpp @@ -0,0 +1,811 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est responsable de la sauvegarde et de l'ouverture des fichiers + log de passage des trains. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "TrainLogFileMgr.h" +#include +#include +#include "LogMgr.h" + +CTrainLogFileMgr CTrainLogFileMgr::mSingleton; + +CTrainLogFileMgr::CTrainLogFileMgr() +{ +} + +//unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, CZT1Log *ZT1Log, QList *ZT1DetectionsLog,QString StationName) +unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, CZT1Log *ZT1Log, QVector *ZT1DetectionsLog,QString StationName) +{ + QFile* BinaryLogFile = new QFile(LogFilePathName); + if(BinaryLogFile) + { + if(BinaryLogFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered) == false) + { + qDebug("Could not create log file : %s",LogFilePathName.toLatin1().data()); + delete BinaryLogFile; + return RET_ERROR; + } + + + } + else + return RET_ERROR; + + QDataStream * OutputStream = new QDataStream(BinaryLogFile); + + quint32 MagicNbr = BASE_FILE_MAGICNBR+1; + + quint32 NbLogEntry = 0,NbDetections = 0; + quint32 LogType = ZT1_LOG_TYPE; + NbLogEntry = ZT1Log->mZT1LogData.size(); + NbDetections = ZT1DetectionsLog->size(); + quint32 TrainType = 0; + quint32 NbElements = 0; + quint64 ThreadDataStartTime = 0, ThreadDataEndTime = 0; + qreal MeanSpeed = 0; + QDateTime DateTime; + + + //Compute some stats + int SpeedSampleCount = 0; + bool TrainTypeFound = false; + unsigned int NbBogie = 0; + bool ThreadStartTimeFound = false, ThreadEndTimeFound = false; + + for(unsigned int i = 0; i < NbLogEntry; i++) + { + if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData != 0) + { + //get the train type + if(!TrainTypeFound) + { + if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainType != TRAIN_TYPE_UNKNOWN) + { + TrainType = ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainType; + TrainTypeFound = true; + } + } + + //Get the rank count for the train + if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mRank > NbBogie) + NbBogie = ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mBogie; + + //Find the time limits + if(ThreadStartTimeFound == false) + { + ThreadStartTimeFound = true; + ThreadDataStartTime = ZT1Log->mZT1LogData.at(i)->mTimestamp; + } + + //Compute the mean speed + if(ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainSpeed != 0) + { + MeanSpeed += ZT1Log->mZT1LogData.at(i)->mZT1ThreadData->mTrainSpeed; + SpeedSampleCount++; + } + } + else + { + //Find the time limits + if(ThreadStartTimeFound == true && ThreadEndTimeFound == false) + { + ThreadEndTimeFound = true; + ThreadDataEndTime = ZT1Log->mZT1LogData.at(i-1)->mTimestamp; + } + } + } + MeanSpeed /= SpeedSampleCount; + NbElements = NbBogie/6; + + DateTime = ZT1Log->mZT1LogData.first()->mDateTime; + + + + *OutputStream << MagicNbr << LogType << NbLogEntry << NbDetections; + *OutputStream << StationName; + + *OutputStream << ZT1Log->mZT1Flags; + + *OutputStream << TrainType << NbElements << ThreadDataStartTime << ThreadDataEndTime << MeanSpeed << DateTime; + + + //write detections + for(unsigned int i =0; i < NbDetections; i++) + { + *OutputStream << *ZT1DetectionsLog->at(i); + } + + //write train passage log + for(unsigned int i = 0; i < NbLogEntry; i++) + { + *OutputStream << *ZT1Log->mZT1LogData.at(i); + } + + //write analog data if present. + if(ZT1Log->mZT1Flags.mAnalogTracePresent == 1) + { + for(unsigned int i = 0; i < NbLogEntry; i++) + { + *OutputStream << ZT1Log->mZT1LogData.at(i)->mAnalogData; + } + } + + BinaryLogFile->close(); + delete BinaryLogFile; + delete OutputStream; + + + return RET_OK; + +} + +//unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName, QVector *ZT2Log, QVector *ZT2DetectionsLog, QString StationName) +unsigned int CTrainLogFileMgr::SaveTrainLog(QString LogFilePathName,CZT2Log *ZT2Log,QVector *ZT2DetectionsLog,QString StationName) +{ + QFile* BinaryLogFile = new QFile(LogFilePathName); + if(BinaryLogFile) + { + if(BinaryLogFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered) == false) + { + qDebug("Could not create log file : %s",LogFilePathName.toLatin1().data()); + delete BinaryLogFile; + return RET_ERROR; + } + + + } + else + return RET_ERROR; + + QDataStream * OutputStream = new QDataStream(BinaryLogFile); + + quint32 MagicNbr = BASE_FILE_MAGICNBR+1; + + quint32 NbLogEntry,NbDetections; + quint32 LogType = ZT2_LOG_TYPE; + NbLogEntry = ZT2Log->mZT2LogData.size(); + NbDetections = ZT2DetectionsLog->size(); + quint32 NbElements = 0; + QDateTime DateTime = ZT2Log->mZT2LogData.at(0)->mDateTime; + + + //Get some stats + for(int j = 0; j < ZT2Log->mZT2LogData.size(); j++) + { + if(ZT2Log->mZT2LogData.at(j)->mZT2ThreadData != 0) + { + //Get the rank count for the train + if(ZT2Log->mZT2LogData.at(j)->mZT2ThreadData->mRank > NbElements) + NbElements = ZT2Log->mZT2LogData.at(j)->mZT2ThreadData->mBogie; + } + } + + NbElements /= 6; //6 bogies per element + + + + *OutputStream << MagicNbr << LogType << NbLogEntry << NbDetections; + *OutputStream << StationName; + + *OutputStream << ZT2Log->mZT2Flags; + + *OutputStream << NbElements << DateTime; + + //write detections + for(unsigned int i =0; i < NbDetections; i++) + { + *OutputStream << *ZT2DetectionsLog->at(i); + } + + + //write train passage log + for(unsigned int i = 0; i < NbLogEntry; i++) + { + *OutputStream << *ZT2Log->mZT2LogData.at(i); + } + + BinaryLogFile->close(); + delete BinaryLogFile; + delete OutputStream; + + return RET_OK; +} + +//It is the responsibility of the caller to make shure TargetElement is empty +CLogElement* CTrainLogFileMgr::OpenTrainLog(QString LogFilePathName,unsigned int &Retvalue,CLogElement* TargetElement,bool LoadData) +{ +// if(!ZT1Log->isEmpty() || !ZT1DetectionsLog->isEmpty()) +// return RET_ERROR; + + QFile* BinaryLogFile = new QFile(LogFilePathName); + if(BinaryLogFile) + { + if(BinaryLogFile->open(QIODevice::ReadOnly | QIODevice::Unbuffered) == false) + { + Retvalue = RET_ERROR; + delete BinaryLogFile; + return 0; + } + + } + else + { + Retvalue = RET_ERROR; + return 0; + } + + QDataStream * InputStream = new QDataStream(BinaryLogFile); + + quint32 MagicNbr,NbLogEntry,NbDetections,LogType; + + *InputStream >> MagicNbr; + if(MagicNbr != BASE_FILE_MAGICNBR+1) + { + + CEngLog::instance()->AddLogString(QString().sprintf("Fichier de passage invalide (Magic number) %s",LogFilePathName.toAscii().data()),3); + BinaryLogFile->close(); + delete BinaryLogFile; + delete InputStream; + + Retvalue = RET_ERROR; + return 0; + } + + *InputStream >> LogType; + + if(LogType == ZT1_LOG_TYPE) + { + CZT1LogElement *PassageLog; + if(TargetElement == 0) + { + PassageLog = new CZT1LogElement(); + } + else + { + PassageLog = (CZT1LogElement*)TargetElement; //It is the responsibility of the caller to make shure TargetElement is empty + } + + PassageLog->mLogFileName = LogFilePathName; + + *InputStream >> NbLogEntry; + *InputStream >> NbDetections; + *InputStream >> PassageLog->mStationName; + *InputStream >> PassageLog->mFlags; + + *InputStream >> PassageLog->mTrainType; + *InputStream >> PassageLog->mNbElements; + *InputStream >> PassageLog->mThreadDataStartTime; + *InputStream >> PassageLog->mThreadDataEndTime; + *InputStream >> PassageLog->mMeanSpeed; + *InputStream >> PassageLog->mPassageDateTime; + + for(unsigned int i = 0; i < NbDetections; i++) + { + CZTDetectionData *NewDetection = new CZTDetectionData(); + *InputStream >> *NewDetection; + PassageLog->mZTDetections.append(NewDetection); + } + + if(LoadData == true) + { + for(unsigned int i = 0; i < NbLogEntry; i++) + { + CZT1LogData *NewLogChunk = new CZT1LogData(); + *InputStream >> *NewLogChunk; + PassageLog->mZTLogData.append(NewLogChunk); + } + + if(PassageLog->mFlags.mAnalogTracePresent == 1) + { + for(int i = 0; i < PassageLog->mZTLogData.size(); i++) + { + *InputStream >> PassageLog->mZTLogData.at(i)->mAnalogData; + } + } + } + + BinaryLogFile->close(); + delete BinaryLogFile; + delete InputStream; + + Retvalue = RET_OK; + return (CZT1LogElement*) PassageLog; + } + else if(LogType == ZT2_LOG_TYPE) + { + quint32 NbElements; + QDateTime DateTime; + + CZT2LogElement *PassageLog; + if(TargetElement == 0) + { + PassageLog = new CZT2LogElement(); + } + else + { + PassageLog = (CZT2LogElement*) TargetElement; //It is the responsibility of the caller to make shure TargetElement is empty + } + + *InputStream >> NbLogEntry; + *InputStream >> NbDetections; + *InputStream >> PassageLog->mStationName; + *InputStream >> PassageLog->mFlags; + *InputStream >> NbElements; + *InputStream >> DateTime; + + PassageLog->mNbElements = NbElements; + PassageLog->mLogFileName = LogFilePathName; + PassageLog->mPassageDateTime = DateTime; + + for(unsigned int i = 0; i < NbDetections; i++) + { + CZTDetectionData *NewDetection = new CZTDetectionData(); + *InputStream >> *NewDetection; + PassageLog->mZTDetections.append(NewDetection); + } + + if(LoadData == true) + { + for(unsigned int i = 0; i < NbLogEntry; i++) + { + CZT2LogData *NewLogChunk = new CZT2LogData(); + *InputStream >> *NewLogChunk; + PassageLog->mZTLogData.append(NewLogChunk); + } + } + + + + + BinaryLogFile->close(); + delete BinaryLogFile; + delete InputStream; + + Retvalue = RET_OK; + return PassageLog; + } + else + { + qDebug("Invalid log type in file %s",LogFilePathName.toLatin1().data()); + Retvalue = RET_ERROR; + return 0; + + + } +} + +//unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT1Log *ZT1Log, QList *ZT1DetectionsLog, QString StationName) +unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT1Log *ZT1Log, QVector *ZT1DetectionsLog, QString StationName) +{ + return SaveCSVFile(CSVFilePathName, &ZT1Log->mZT1LogData, &ZT1Log->mZT1Flags, ZT1DetectionsLog,StationName); +} + +//unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QList *ZT1Log, CZT1FlagsData *ZT1Flags, QList *ZT1DetectionsLog, QString StationName) +unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector *ZT1Log, CZT1FlagsData *ZT1Flags, QVector *ZT1DetectionsLog, QString StationName) +{ + QFile CSVFile(CSVFilePathName); + if(!CSVFile.open(QIODevice::QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate)) + return RET_ERROR; + + QTextStream CSVStream(&CSVFile); + + CSVStream << "Log de passage du train dans la ZT1\n"; + + CSVStream << QString::fromUtf8("Station : ") << StationName << "\n"; + CSVStream << QString::fromUtf8("Valeur seuil Pneu de guidage : ") << ZT1Flags->mPGTresholdValue << "\n"; + CSVStream << QString::fromUtf8("Valeur zérotage PG Extérieur : ") << ZT1Flags->mExtPGOffset << "\n"; + CSVStream << QString::fromUtf8("Valeur zérotage PG Intérieur : ") << ZT1Flags->mIntPGOffset << "\n"; + if(ZT1Flags->mPGCalibrationON == 1) + { + CSVStream << "Calibration PG en cours lors du passage: OUI\n"; + } + else + CSVStream << "Calibration PG en cours lors du passage: NON\n"; + + CSVStream << QString::fromUtf8("Nombre de déclenchements : ") << ZT1DetectionsLog->size() << "\n"; + + + + if(ZT1DetectionsLog->size() > 0) + { + for(int i = 0; i < ZT1DetectionsLog->size(); i++) + { + CSVStream << QString::fromUtf8("Déclenchement ") << i+1 << ": " << ZT1DetectionsLog->at(i)->mTimeStamp << " - " << QString::fromUtf8(CZTData::GetErrorString(ZT1DetectionsLog->at(i)->mDetectionID)) << " au rang " << ZT1DetectionsLog->at(i)->mRank << "\n"; + } + + + } + CSVStream << "\n"; + + CSVStream << "Date,Heure,Timestamp,CI,CDV Approche,CDV ZT1,S1,S2,FN,PPI,PPE,PG,Vitesse,Bogie,Rang,Sonde Ext, Sonde Int,Train\n"; + + for(int i = 0; i < ZT1Log->size(); i++) + { + CSVStream << ZT1Log->at(i)->mDateTime.toString("yyyy-MM-dd, hh:mm:ss:zzz") << ","; + CSVStream << ZT1Log->at(i)->mTimestamp << ","; + CSVStream << ZT1Log->at(i)->mCIZT1 << ","; + CSVStream << ZT1Log->at(i)->mCDVApproach_ZT1 << ","; + CSVStream << ZT1Log->at(i)->mCDVARM_ZT1 << ","; + if(ZT1Log->at(i)->mZT1ThreadData != 0) + { + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mS1 << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mS2 << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mFN << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPInt << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPExt << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPG << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mTrainSpeed << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mBogie << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mRank << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPGExtValue << ","; + CSVStream << ZT1Log->at(i)->mZT1ThreadData->mPGIntValue << ","; + CSVStream << CZTData::GetTrainTypeString(ZT1Log->at(i)->mZT1ThreadData->mTrainType) << "\n"; + } + else + { + CSVStream << "0,0,0,0,0,0,0,0,0,0,0,0"; + CSVStream <<"\n"; + } + } + + CSVFile.flush(); + CSVFile.close(); + + return RET_OK; +} + +unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT2Log *ZT2Log, QVector *ZT2DetectionsLog, QString StationName) +{ + return SaveCSVFile(CSVFilePathName, &ZT2Log->mZT2LogData, ZT2DetectionsLog, StationName); +} + +//unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, CZT2Log *ZT2Log, QVector *ZT2DetectionsLog, QString StationName) +unsigned int CTrainLogFileMgr::SaveCSVFile(QString CSVFilePathName, QVector *ZT2Log, QVector *ZT2DetectionsLog, QString StationName) +{ + QFile CSVFile(CSVFilePathName); + if(!CSVFile.open(QIODevice::QIODevice::WriteOnly|QIODevice::Text|QIODevice::Truncate)) + return RET_ERROR; + + QTextStream CSVStream(&CSVFile); + + CSVStream << "Log de passage du train dans la ZT2\n"; + CSVStream << QString::fromUtf8("Station : ") << StationName << "\n"; + + CSVStream << QString::fromUtf8("Nombre de déclenchements : ") << ZT2DetectionsLog->size() << "\n"; + + + if(ZT2DetectionsLog->size() > 0) + { + for(int i = 0; i < ZT2DetectionsLog->size(); i++) + { + CSVStream << QString::fromUtf8("Déclenchement ") << i+1 << ": " << ZT2DetectionsLog->at(i)->mTimeStamp << " - " << QString::fromUtf8(CZTData::GetErrorString(ZT2DetectionsLog->at(i)->mDetectionID)) << " au rang " << ZT2DetectionsLog->at(i)->mRank << "\n"; + } + + CSVStream << "\n"; + } + + CSVStream << "Date,Heure,Timestamp,CI,CDV ZT2,S1,PPI,PPE,Bogie,Rang\n"; + + for(int i = 0; i < ZT2Log->size(); i++) + { + CSVStream << ZT2Log->at(i)->mDateTime.toString("yyyy-MM-dd, hh:mm:ss:zzz") << ","; + CSVStream << ZT2Log->at(i)->mTimestamp << ","; + CSVStream << ZT2Log->at(i)->mCIZT2 << ","; + CSVStream << ZT2Log->at(i)->mCDVARM_ZT2 << ","; + if(ZT2Log->at(i)->mZT2ThreadData != 0) + { + CSVStream << ZT2Log->at(i)->mZT2ThreadData->mS1 << ","; + CSVStream << ZT2Log->at(i)->mZT2ThreadData->mPPInt << ","; + CSVStream << ZT2Log->at(i)->mZT2ThreadData->mPPExt << ","; + CSVStream << ZT2Log->at(i)->mZT2ThreadData->mBogie << ","; + CSVStream << ZT2Log->at(i)->mZT2ThreadData->mRank << ","; + } + else + { + CSVStream << "0,0,0,0,0"; + CSVStream <<"\n"; + } + } + + CSVFile.flush(); + CSVFile.close(); + + return RET_OK; +} + + + +//Cette fonction a été écrite pour des fins de tests et n'est PAS du tout robuste. +//utiliser avec précaution. +unsigned int CTrainLogFileMgr::SaveBINFromCSV(QString CSVFilePathName) +{ + QFile CSVFile(CSVFilePathName); + if(!CSVFile.open(QIODevice::ReadOnly|QIODevice::Text)) + return RET_ERROR; + + QTextStream CSVStream(&CSVFile); + + bool IsZT1 = true; + QString Line; + QStringList LineElements; + QString StationName; + Line.clear(); + LineElements.clear(); + + Line = CSVStream.readLine(); //Log de passage du train dans la ZT1 + if(Line.contains("ZT1") == true) + { + IsZT1 = true; + } + else if(Line.contains("ZT2") == true) + { + IsZT1 = false; + } + else + { + //invalid file + CSVFile.close(); + return RET_ERROR; + } + + Line = CSVStream.readLine(); //Station : Snowdon + LineElements = Line.split(":"); + if(LineElements.isEmpty()) + { + CSVFile.close(); + return RET_ERROR; + } + StationName = LineElements.at(1); + Line.clear(); + + if(IsZT1 == true) + { + CZT1Log *ZT1LOG = new CZT1Log(); + + Line = CSVStream.readLine(); //Valeur seuil Pneu de guidage : 15625 + LineElements = Line.split(":"); + if(LineElements.isEmpty()) + { + CSVFile.close(); + return RET_ERROR; + } + ZT1LOG->mZT1Flags.mPGTresholdValue = LineElements.at(1).toInt(); + Line.clear(); + + Line = CSVStream.readLine(); //Valeur zérotage PG Extérieur : 128457 + LineElements = Line.split(":"); + if(LineElements.isEmpty()) + { + CSVFile.close(); + return RET_ERROR; + } + ZT1LOG->mZT1Flags.mExtPGOffset = LineElements.at(1).toInt(); + Line.clear(); + + Line = CSVStream.readLine(); //Valeur zérotage PG Intérieur : 1300637 + LineElements = Line.split(":"); + if(LineElements.isEmpty()) + { + CSVFile.close(); + return RET_ERROR; + } + ZT1LOG->mZT1Flags.mIntPGOffset = LineElements.at(1).toInt(); + Line.clear(); + + Line = CSVStream.readLine(); //Calibration PG en cours lors du passage: NON + if(Line.contains("OUI") == true) + { + ZT1LOG->mZT1Flags.mPGCalibrationON = true; + } + else if(Line.contains("NON") == true) + { + ZT1LOG->mZT1Flags.mPGCalibrationON = false; + } + else + { + CSVFile.close(); + return RET_ERROR; + } + Line.clear(); + + int NbDetections; + Line = CSVStream.readLine(); //Nombre de déclenchements : 12 + LineElements = Line.split(":"); + if(LineElements.isEmpty()) + { + CSVFile.close(); + return RET_ERROR; + } + NbDetections = LineElements.at(1).toInt(); + Line.clear(); + + //Ignore detections... + for(int i = 0; i < NbDetections; i++) + { + Line = CSVStream.readLine(); + Line.clear(); + } + + //Skip the empty line after the detections. + Line = CSVStream.readLine(); + Line.clear(); + + //Skip the table header + Line = CSVStream.readLine(); + Line.clear(); + + quint32 LastS1 = 0, LastS2 = 0, LastFN = 0; + quint32 S1Count = 0; + quint32 S2Count = 0; + quint32 FNCount = 0; + while(CSVStream.atEnd() == false) + { + + Line.clear(); + LineElements.clear(); + + Line = CSVStream.readLine(); //Date Heure Timestamp CI CDV Approche CDV ZT1 S1 S2 FN PPI PPE PG Vitesse Bogie Rang Sonde Ext Sonde Int Train + LineElements = Line.split(","); + if(LineElements.count() != 18) + { + CSVFile.close(); + return RET_ERROR; + } + + QDate date = QDate::fromString(LineElements.at(0),"yyyy-MM-dd"); + if(date.isValid() == false) + { + CSVFile.close(); + return RET_ERROR; + } + + QTime time = QTime::fromString(LineElements.at(1).trimmed(),"hh:mm:ss:zzz"); + if(time.isValid() == false) + { + CSVFile.close(); + return RET_ERROR; + } + + qint64 timestamp = LineElements.at(2).toLongLong(); + + quint32 CIZT1 = LineElements.at(3).toUInt(); + + quint32 CDVApproach_ZT1 = LineElements.at(4).toUInt(); + + quint32 CDVARM_ZT1 = LineElements.at(5).toUInt(); + + CZT1LogData *LogData; + CZT1ThreadData *ThreadData; + if(LineElements.at(17) == "0") //Check if ThreadData is valid + { + //Thread data not valid... + LogData = new CZT1LogData(); + } + else + { + ThreadData = new CZT1ThreadData(); + LogData = new CZT1LogData(ThreadData); + + + quint32 S1 = LineElements.at(6).toUInt(); + quint32 S2 = LineElements.at(7).toUInt(); + quint32 FN = LineElements.at(8).toUInt(); + quint32 PInt = LineElements.at(9).toUInt(); + quint32 PExt = LineElements.at(10).toUInt(); + quint32 PG = LineElements.at(11).toUInt(); + qreal TrainSpeed = LineElements.at(12).toFloat(); + quint32 Bogie = LineElements.at(13).toUInt(); + quint32 Rank = LineElements.at(14).toUInt(); + qint32 PGIntValue = LineElements.at(15).toInt(); + qint32 PGExtValue = LineElements.at(16).toInt(); + + quint32 TrainType; + if(LineElements.at(17) == "Inconnu") + { + TrainType = TRAIN_TYPE_UNKNOWN; + } + else if(LineElements.at(17) == "MR63/73") + { + TrainType = TRAIN_TYPE_MR63_MR73; + } + else if(LineElements.at(17) == "MPM10") + { + TrainType = TRAIN_TYPE_MPM10; + } + else + { + CSVFile.close(); + return RET_ERROR; + } + + if(S1 == 1 && LastS1 == 0) + S1Count++; + + if(S2 == 1 && LastS2 == 0) + S2Count++; + + if(FN == 1 && LastFN == 0) + FNCount++; + + LastS1 = S1; + LastS2 = S2; + LastFN = FN; + + ThreadData->mTimeStamp = timestamp; //nanosecs + ThreadData->mDateTime.setDate(date); + ThreadData->mDateTime.setTime(time); + ThreadData->mS1 = S1; + ThreadData->mS2 = S2; + ThreadData->mFN = FN; + ThreadData->mPInt = PInt; + ThreadData->mPExt = PExt; + ThreadData->mPG = PG; + ThreadData->mTrainSpeed = TrainSpeed; + ThreadData->mBogie = Bogie; + ThreadData->mRank = Rank; + ThreadData->mPGIntValue = PGIntValue; + ThreadData->mPGExtValue = PGExtValue; + ThreadData->mS1Count = S1Count; + ThreadData->mS2Count = S2Count; + ThreadData->mFNCount = FNCount; + ThreadData->mTrainType = TrainType; + } + + LogData->mTimestamp = timestamp; + LogData->mCIZT1 = CIZT1; + LogData->mCDVApproach_ZT1 = CDVApproach_ZT1; + LogData->mCDVARM_ZT1 = CDVARM_ZT1; + LogData->mDateTime.setDate(date); + LogData->mDateTime.setTime(time); + + ZT1LOG->mZT1LogData.append(LogData); + } + + // QList Dummy; //JFM + QVector Dummy; + Dummy.clear(); + + SaveTrainLog(CSVFilePathName.replace("csv","bin"),ZT1LOG,&Dummy,StationName); + + for(int i = 0; i < ZT1LOG->mZT1LogData.size(); i++) + { + delete ZT1LOG->mZT1LogData.at(i); + } + ZT1LOG->mZT1LogData.clear(); + delete ZT1LOG; + + + + + } + else //ZT1 + { + } + + + return RET_OK; +} diff --git a/sources/TrainLogFileMgr.h b/sources/TrainLogFileMgr.h new file mode 100644 index 0000000..cb2c26d --- /dev/null +++ b/sources/TrainLogFileMgr.h @@ -0,0 +1,61 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef TRAINLOGFILEMGR_H +#define TRAINLOGFILEMGR_H + +#include "GlobalDefine.h" +#include "ZTData.h" + + + +class CLogElement; + +class CTrainLogFileMgr +{ +public: + + //CTrainLogFileMgr is a singleton class + static CTrainLogFileMgr* instance(){return &mSingleton;} + static CTrainLogFileMgr mSingleton; + + + CTrainLogFileMgr(); + unsigned int SaveTrainLog(QString LogFilePathName,CZT1Log *ZT1Log,QVector *ZT1DetectionsLog,QString StationName); + //unsigned int SaveTrainLog(QString LogFilePathName,QVector *ZT2Log,QVector *ZT2DetectionsLog,QString StationName); + unsigned int SaveTrainLog(QString LogFilePathName,CZT2Log *ZT2Log,QVector *ZT2DetectionsLog,QString StationName); + CLogElement *OpenTrainLog(QString LogFilePathName,unsigned int &RetValue,CLogElement *TargetElement = 0,bool LoadData = false); + unsigned int SaveCSVFile(QString CSVFilePathName,QVector *ZT1Log,CZT1FlagsData *ZT1Flags,QVector *ZT1DetectionsLog, QString StationName); + unsigned int SaveCSVFile(QString CSVFilePathName,CZT1Log *ZT1Log,QVector *ZT1DetectionsLog, QString StationName); + unsigned int SaveCSVFile(QString CSVFilePathName, QVector *ZT2Log, QVector *ZT2DetectionsLog, QString StationName); + unsigned int SaveCSVFile(QString CSVFilePathName,CZT2Log *ZT2Log,QVector *ZT2DetectionsLog, QString StationName); + + unsigned int SaveBINFromCSV(QString CSVFilePathName); +}; + +#endif // TRAINLOGFILEMGR_H + diff --git a/sources/USBDriveInterface.cpp b/sources/USBDriveInterface.cpp new file mode 100644 index 0000000..023da5d --- /dev/null +++ b/sources/USBDriveInterface.cpp @@ -0,0 +1,153 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe vérifie constamment la présence de la clef USB et permet d'obtenir + le répertoire visé par la clef. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "USBDriveInterface.h" +#ifndef WINDOWS_OS +#include +#endif +#include "EngLog.h" + +CUSBDriveInterface::CUSBDriveInterface() +{ + + mDriveDetected = false; + mDriveEmulationEnabled = false; + + mDrivePresenceUpdateTimer = new QTimer(); + mDrivePresenceUpdateTimer->setSingleShot(false); + mDrivePresenceUpdateTimer->setInterval(1000); + connect(mDrivePresenceUpdateTimer,SIGNAL(timeout()),this,SLOT(CheckDrivePresence())); + +} + +CUSBDriveInterface::~CUSBDriveInterface() +{ + mDrivePresenceUpdateTimer->stop(); + delete mDrivePresenceUpdateTimer; +} + +unsigned int CUSBDriveInterface::Start() +{ + mDrivePresenceUpdateTimer->start(); + return RET_OK; +} + +void CUSBDriveInterface::CheckDrivePresence() +{ + if(mDriveEmulationEnabled == true) + { + + } + else + { +#ifdef WINDOWS_OS + mDriveDetected = false; +#else + FILE* mtab = setmntent("/etc/mtab", "r"); + struct mntent* m; + struct mntent mnt; + char strings[4096]; + + //parse the mounted drives list + while ((m = getmntent_r(mtab, &mnt, strings, sizeof(strings)))) + { + if ((mnt.mnt_dir != NULL) /*&& (statfs(mnt.mnt_dir, &fs) == 0)*/) + { + QString type = (mnt.mnt_type); + + //filter the "vfat" drive type (usb flash drive is vfat) + if(type == "vfat") + { + + QString temp(mnt.mnt_dir); + if(temp.contains("/media/usb")) + { + if(mDriveDetected == false) + { + mDriveDetected = true; + mDrivePath = temp; + qDebug("Flash Detected: %s",mDrivePath.toAscii().data()); + CEngLog::instance()->AddLogString("Clef USB détectée"); + } + endmntent(mtab); + + return; + } + + } + } + } + + if(mDriveDetected == true) + { + mDriveDetected = false; + mDrivePath.clear(); + qDebug("Flash drive disconnected"); + CEngLog::instance()->AddLogString("Clef USB débranchée"); + } + endmntent(mtab); + +#endif + } +} + +QString CUSBDriveInterface::GetDrivePath() +{ + return mDrivePath; +} + +bool CUSBDriveInterface::IsDriveDetected() +{ + return mDriveDetected; +} + +unsigned int CUSBDriveInterface::EmulateDrivePresence(bool DrivePresent) +{ + if(mDriveEmulationEnabled == false) + return RET_ERROR; + + mDriveDetected = DrivePresent; + + return RET_OK; +} + +unsigned int CUSBDriveInterface::EnableDriveEmulation(bool Enabled) +{ + mDriveEmulationEnabled = Enabled; + + if(Enabled == true) + { + mDrivePath = "."; + } + else + { + mDriveDetected = false; + } + return RET_OK; + +} diff --git a/sources/USBDriveInterface.h b/sources/USBDriveInterface.h new file mode 100644 index 0000000..e142d1f --- /dev/null +++ b/sources/USBDriveInterface.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef USBDRIVEINTERFACE_H +#define USBDRIVEINTERFACE_H +#include "GlobalDefine.h" +#include +#include + +class CUSBDriveInterface : public QObject +{ + Q_OBJECT +public: + CUSBDriveInterface(); + ~CUSBDriveInterface(); + + bool IsDriveDetected(); + QString GetDrivePath(); + unsigned int Start(); + unsigned int EmulateDrivePresence(bool DrivePresent); + unsigned int EnableDriveEmulation(bool Enabled); + +private: + + QTimer *mDrivePresenceUpdateTimer; + bool mDriveDetected; + QString mDrivePath; + bool mDriveEmulationEnabled; + + +public slots: + void CheckDrivePresence(); +}; + +#endif // USBDRIVEINTERFACE_H diff --git a/sources/WatchdogCtrl.cpp b/sources/WatchdogCtrl.cpp new file mode 100644 index 0000000..c7d86c0 --- /dev/null +++ b/sources/WatchdogCtrl.cpp @@ -0,0 +1,112 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2015 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette clase contrôle le watchdog interne de Linux. Elle permet l'ouverture + ou l'arrêt du watchdog ainsi que son rafraîchissement. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 2015????JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "WatchdogCtrl.h" +#include +#include +#include +#include +#include + +CWatchdogCtrl::CWatchdogCtrl(bool UseWatchdog) +{ + fd = -1; + mUseWatchdog = UseWatchdog; +} + +CWatchdogCtrl::~CWatchdogCtrl() +{ + if(fd > -1) + { + StopWatchdog(); + } +} + +int CWatchdogCtrl::StartWatchdog() +{ + if(mUseWatchdog == false) + { + CEngLog::instance()->AddLogString(QString().sprintf("Watchdog CPU désactivé dans la ligne de commande"),1); + return RET_ERROR; + } + + if(fd > -1) + return RET_OK; + + QString PortPath = "/dev/watchdog"; + fd = open(PortPath.toLatin1().data(), O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); + if (fd < 0) + { + CEngLog::instance()->AddLogString(QString().sprintf("Erreur d'ouverture du watchdog")); + return RET_ERROR; + } + int interval = -1; + int BootMode = -1; + ioctl(fd, WDIOC_GETTIMEOUT, &interval); + ioctl(fd, WDIOC_GETBOOTSTATUS, &BootMode); + + + CEngLog::instance()->AddLogString(QString().sprintf("Ouverture du watchdog réussie: Timeout = %d, BootMode = %d",interval,BootMode)); + + return RET_OK; +} + +int CWatchdogCtrl::KickWatchdog() +{ + if(mUseWatchdog == false) + { + return RET_ERROR; + } + + if(fd < 0) + return RET_ERROR; + + if(ioctl(fd, WDIOC_KEEPALIVE, NULL) != 0) + { + // CEngLog::instance()->AddLogString(QString().sprintf("Impossible de kicker le watchdog!!!")); + return RET_ERROR; + } + return RET_OK; +} + +int CWatchdogCtrl::StopWatchdog() +{ + if(mUseWatchdog == false) + { + return RET_ERROR; + } + + if(fd < 0) + return RET_ERROR; + + write(fd,"V",1); //Write character 'V' to notify the watchdog that we want to close it... + close(fd); + fd = -1; + + return RET_OK; +} diff --git a/sources/WatchdogCtrl.h b/sources/WatchdogCtrl.h new file mode 100644 index 0000000..2c6b2f3 --- /dev/null +++ b/sources/WatchdogCtrl.h @@ -0,0 +1,28 @@ +#ifndef WATCHDOGCTRL_H +#define WATCHDOGCTRL_H + +#include "GlobalDefine.h" +#include +#include +#include +#include +#include +#include +#include + +class CWatchdogCtrl +{ +public: + CWatchdogCtrl(bool UseWatchdog = true); + ~CWatchdogCtrl(); + + int StartWatchdog(); + int KickWatchdog(); + int StopWatchdog(); + +private: + int fd; + bool mUseWatchdog; +}; + +#endif // WATCHDOGCTRL_H diff --git a/sources/ZT1AnalysisThread.cpp b/sources/ZT1AnalysisThread.cpp new file mode 100644 index 0000000..71ea794 --- /dev/null +++ b/sources/ZT1AnalysisThread.cpp @@ -0,0 +1,1051 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est un thread qui roule en parallèle au programme. Elle est + responsable de l'analyse en temps réel du passage d'un train. Elle fait la + lecture des entrées sur la carte PCI et détecte les déclenchements au fur + et à mesure qu'un train chemine sur la ZT1 + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#include "ZT1AnalysisThread.h" +#include "PCIIOMgr.h" +#include "AbstractLazerProbe.h" +#include +#include "ZTconfigmgr.h" +#include + + +CZT1AnalysisThread::CZT1AnalysisThread() +{ + mLastInputs = 0; + mLastPGIntValue = mLastPGExtValue = mLastSDFValue = 0; + mZT1TrainState = ZT1_WAIT_FOR_S1_STATE; + + mPGIntHandle = 0; + mPGExtHandle = 0; + mPCIInputsHandle = 0; + mSDFAnalogInterface = 0; + mExitLoop = false; + mZT1Analyzing = false; + mPGCalibration = false; + +} + +unsigned int CZT1AnalysisThread::Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks, CAbstractLazerProbe* PGExtHandle,CAbstractLazerProbe* PGIntHandle,QElapsedTimer *RefTimer,CAnalogInputModule *AnalogInterface) +{ + mPCIInputsHandle = PCIIOHandle; + mInputMasksPtr = InputMasks; + mPGIntHandle = PGIntHandle; + mPGExtHandle = PGExtHandle; + mReferenceTimer = RefTimer; + mSDFAnalogInterface = AnalogInterface; + + return RET_OK; +} + +void CZT1AnalysisThread::SetPGTreshold(qint32 PGTreshold) +{ + mMutex.lock(); + mPGTreshold = PGTreshold; + mMutex.unlock(); +} + +bool CZT1AnalysisThread::SetPGCalibration(bool CalibON) +{ + mMutex.lock(); + if(mZT1Analyzing) + { + mMutex.unlock(); + return false; + } + mPGCalibration = CalibON; + mMutex.unlock(); + + return true; +} + +void CZT1AnalysisThread::AnalyzeZT1Train() +{ + + // qDebug("ZT1 Thread started!"); + mExitLoop = false; + mZT1Analyzing = true; + mPEQDetectionLatch = false; + + + mZT1TrainState = ZT1_PRE_DETECTION_STATE; + unsigned int PCIInputs = 0; + bool Run = true; + QElapsedTimer TrainSpeedTimer1,TrainSpeedTimer2,AcquisitionTimer; + + AcquisitionTimer.start(); + + //inputs + unsigned int S1 = 0, S2 = 0, Pint = 0, Pext = 0, FN = 0; + qint32 PGint,PGExt; + int SDFAnalog = 0; + + + //Train analysis variables + float TrainSpeed = 0; + unsigned int Bogie = 0; + unsigned int Rank = 0; + unsigned int CountS1 = 0; + unsigned int CountS2 = 0; + unsigned int CountFN = 0; + unsigned int TrainType = TRAIN_TYPE_UNKNOWN; + mMutex.lock(); + qint32 PGValueTreshold = mPGTreshold; + bool PGCalibration = mPGCalibration; + mMutex.unlock(); + + mLastInputs = 0; + mLastSDFValue = 0; + + + bool FNDetected = false; + bool PPIDetected = false; + bool PPEDetected = false; + bool PGActive = false; + + bool LazerProbesTransitOnly = false; + + qint32 PGIOffset,PGEOffset; + qint32 Quadra; + qint32 PGICalibValue = 0, PGECalibValue = 0; + + PGValueTreshold *= PGValueTreshold; //use square value... + PGIOffset = mPGIntHandle->GetLastData(); + PGEOffset = mPGExtHandle->GetLastData(); + + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mIntPGOffset = PGIOffset; + emit NewZT1Flag(ZT1_INT_PG_OFFSET_FLAG_ID,Flag); + + Flag = new CZT1FlagsData(); //the state machine deletes the pointer, we must create a new one. + Flag->mExtPGOffset = PGEOffset; + emit NewZT1Flag(ZT1_EXT_PG_OFFSET_FLAG_ID,Flag); + + Flag = new CZT1FlagsData(); //the state machine deletes the pointer, we must create a new one. + Flag->mPGTresholdValue = PGValueTreshold; + emit NewZT1Flag(ZT1_PG_TRESHOLD_VALUE_FLAG_ID,Flag); + + while(Run == true) + { + { + AcquisitionTimer.start(); + + PCIInputs = mPCIInputsHandle->GetInputs(); + + PGint = mPGIntHandle->GetLastData(); + PGExt = mPGExtHandle->GetLastData(); + if(mSDFAnalogInterface != 0) + mSDFAnalogInterface->GetAnalogInput(0,&SDFAnalog); + + if(PCIInputs != mLastInputs) + { + LazerProbesTransitOnly = false; + } + else + { + LazerProbesTransitOnly = true; + } + + if(PCIInputs != mLastInputs || + PGint != mLastPGIntValue || + PGExt != mLastPGExtValue || + SDFAnalog != mLastSDFValue ) + { + //Extract useful flags + + S1 = ((PCIInputs & mInputMasksPtr->InputZT1S1Mask) != 0); + S2 = ((PCIInputs & mInputMasksPtr->InputZT1S2Mask) != 0); + Pint = ((PCIInputs & mInputMasksPtr->InputZT1PIMask) == 0); //PP are active low + Pext = ((PCIInputs & mInputMasksPtr->InputZT1PEMask) == 0); + FN = ((PCIInputs & mInputMasksPtr->InputZT1FNMask) == 0); //FN is active low + + switch(mZT1TrainState) + { + case ZT1_PRE_DETECTION_STATE: //Get in this state only once at the beginning. + { + //Pre-detection : Check if SDF is not active. + if(FN == 1 || Pint == 1 || Pext == 1) + { + RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + if(FN == 1) + { + emit AddLogString(QString("Panne équipement ZT1: Pré détection Frotteur négatif = 1")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_FN_PREDETECTION_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + if(Pint == 1) + { + emit AddLogString(QString("Panne équipement ZT1: Pré détection Pneu porteur intérieur = 1")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_PINT_PREDETECTION_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + if(Pext == 1) + { + emit AddLogString(QString("Panne équipement ZT1: Pré détection Pneu porteur extérieur = 1")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_PEXT_PREDETECTION_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + } + if(S1 == 1 || S2 == 1) + { + RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + if(S1 == 1) + { + emit AddLogString(QString("Panne équipement ZT1: Pré détection S1 = 1")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_MAG_SENSOR_S1_PREDETECTION_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + if(S2 == 1) + { + emit AddLogString(QString("Panne équipement ZT1: Pré détection S2 = 1")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_MAG_SENSOR_S2_PREDETECTION_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + } + if(mPGIntHandle->IsProbeAlive() == false) + { + RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + emit AddLogString(QString("Panne équipement ZT1: Pré détection Sonde lazer intérieure défectueuse")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_LAZER_SENSOR_INT_PREDETECTION_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + if(mPGExtHandle->IsProbeAlive() == false) + { + RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + emit AddLogString(QString("Panne équipement ZT1: Pré détection Sonde lazer extérieure défectueuse")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_LAZER_SENSOR_EXT_PREDETECTION_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + + mZT1TrainState = ZT1_WAIT_FOR_S1_STATE; + break; + } + case ZT1_WAIT_FOR_S1_STATE: //1 + { + FNDetected = false; + PPEDetected = false; + PPIDetected = false; + PGActive = false; + + if(FN == 1)// The SDF should not detect any FN at this step (no bogie on the ZT). + { + if(mPEQDetectionLatch == false) + { + // emit AddLogString(QString("Panne équipement ZT1: SDF à 1")); + CZT1FlagsData *Flag = new CZT1FlagsData(); + Flag->mPEQ1Type = PEQ1_FN_STUCK_LOW_TYPE; + emit NewZT1Flag(ZT1_PEQ_TYPE_FLAG_ID,Flag); + } + RegisterDetection(DETECTION_PEQ1_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + + if(S1 == 0 && S2 == 0) + { + break; + } + else if(S1 == 1 && S2 == 0) + { + Bogie++; + Rank++; + CountS1++; + if(PGCalibration) + { + PGICalibValue = PGIOffset; + PGECalibValue = PGEOffset; + } + + TrainSpeedTimer1.start(); + mZT1TrainState = ZT1_S1_ACTIVE_STATE; + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_S1_ACTIVE_STATE: //2 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + if(PGCalibration) + { + + qint32 Value = PGint - PGIOffset; + if(Value < PGICalibValue) + PGICalibValue = Value; + + Value = PGExt - PGEOffset; + if(Value < PGECalibValue) + PGECalibValue = Value; + } + else if(PGActive == false) + { + //Compute and verify if the PG is detected. + Quadra = ((PGint - PGIOffset) * (PGExt - PGEOffset)); + + if(Quadra > PGValueTreshold) + { + //The PG has been detected, stop sampling... + PGActive = true; + } + } + + if(S1 == 1 && S2 == 0) + { + break; + } + else if(S1 == 0 && S2 == 0) + { + if(PGCalibration) + { + CZTPGCalibrationData *Data = new CZTPGCalibrationData(); + Data->mTimestamp = mReferenceTimer->nsecsElapsed(); + Data->mPGExtValue = PGECalibValue; + Data->mPGIntValue = PGICalibValue; + + emit NewPGCalibrationData(Data); + PGICalibValue = PGIOffset; + PGECalibValue = PGEOffset; + } + else if(PGActive == false) //The PG has not been detected... + { + RegisterDetection(DETECTION_PG_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + PGActive = false; + + + if(TrainType == TRAIN_TYPE_UNKNOWN) //First bogie, the train type is unknown + { + mZT1TrainState = ZT1_S1_TRANSIT_STATE; //goto state 3 to determine train type... + } + else if(TrainType == TRAIN_TYPE_MR63_MR73) + { + mZT1TrainState = ZT1_S1_TANSIT_MR_STATE; //goto state 3_MR + } + else if(TrainType == TRAIN_TYPE_MPM10) + { + mZT1TrainState = ZT1_S1_TRANSIT_MPM_STATE; //goto state3_MPM + } + else + CEngLog::instance()->AddLogString("LOGIC ERROR IN ZT1AnalysysThread.CPP - ZT1_ACTIVE_STATE: invalid train type",1); + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_S1_TRANSIT_STATE: //3 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + + if(S1 == 0 && S2 == 0) + { + break; + } + else if(S1 == 1 && S2 == 0) + { + CountS1++; + TrainType = TRAIN_TYPE_MR63_MR73; + TrainSpeed = (MR_BOGIE_LENGTH / TrainSpeedTimer1.elapsed()) * 1000; // m/s + TrainSpeed *= 2.23694; // Mph + mZT1TrainState = ZT1_MR_S1_SECOND_PULSE_STATE; //goto state 4 + } + else if(S1 == 0 && S2 == 1) + { + CountS2++; + TrainType = TRAIN_TYPE_MPM10; + TrainSpeedTimer2.start(); + Rank++; + PPEDetected = false; + PPIDetected = false; + mZT1TrainState = ZT1_MPM10_S2_ACTIVE_STATE; //goto state 8 + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_S1_TANSIT_MR_STATE: //3_MR + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + + if(S1 == 0 && S2 == 0) + { + break; + } + else if(S1 == 1 && S2 == 0) + { + CountS1++; + TrainSpeed = (MR_BOGIE_LENGTH / TrainSpeedTimer1.elapsed()) * 1000; // m/s + TrainSpeed *= 2.23694; // Mph + mZT1TrainState = ZT1_MR_S1_SECOND_PULSE_STATE; //goto state 4 + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_S1_TRANSIT_MPM_STATE: //3_MPM + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + + if(S1 == 0 && S2 == 0) + { + break; + } + else if(S1 == 0 && S2 == 1) + { + CountS2++; + TrainSpeedTimer2.start(); + Rank++; + PPEDetected = false; + PPIDetected = false; + mZT1TrainState = ZT1_MPM10_S2_ACTIVE_STATE; //goto state 8 + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MR_S1_SECOND_PULSE_STATE: //4 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + + if(S2 == 0) + { + break; + } + else if(S2 == 1) + { + CountS2++; + TrainSpeedTimer2.start(); + Rank++; + PPEDetected = false; + PPIDetected = false; + mZT1TrainState = ZT1_MR_S2_ACTIVE_STATE; + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MR_S2_ACTIVE_STATE: //5 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + + if(S2 == 1) + { + break; + } + else if(S1 == 0 && S2 == 0) + { + mZT1TrainState = ZT1_MR_S2_TRANSIT_STATE; + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MR_S2_TRANSIT_STATE: //6 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + + if(S1 == 0 && S2 == 0) + { + break; + } + else if(S1 == 0 && S2 == 1) + { + CountS2++; + + TrainSpeed = (MR_BOGIE_LENGTH / TrainSpeedTimer2.elapsed()) * 1000; // m/s + TrainSpeed *= 2.23694; // Mph + mZT1TrainState = ZT1_MR_S2_SECOND_PULSE_STATE; + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MR_S2_SECOND_PULSE_STATE: //7 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + if(PGCalibration) + { + + qint32 Value = PGint - PGIOffset; + if(Value < PGICalibValue) + PGICalibValue = Value; + + Value = PGExt - PGEOffset; + if(Value < PGECalibValue) + PGECalibValue = Value; + } + else if(PGActive == false) + { + //Compute and verify if the PG is detected. + Quadra = ((PGint - PGIOffset) * (PGExt - PGEOffset)); + if(Quadra > PGValueTreshold) + { + //The PG has been detected, stop sampling... + PGActive = true; + } + } + + if(S1 == 0 && S2 == 1) + { + break; + } + else if(S1 == 0 && S2 == 0) + { + if(PGCalibration) + { + CZTPGCalibrationData *Data = new CZTPGCalibrationData(); + Data->mTimestamp = mReferenceTimer->nsecsElapsed(); + Data->mPGExtValue = PGECalibValue; + Data->mPGIntValue = PGICalibValue; + + emit NewPGCalibrationData(Data); + PGICalibValue = PGIOffset; + PGECalibValue = PGEOffset; + + } + else if(PGActive == false) //The PG has not been detected... + { + RegisterDetection(DETECTION_PG_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + PGActive = false; + + if(FNDetected == false) + { + RegisterDetection(DETECTION_FN_DETECTION,Bogie,mReferenceTimer->nsecsElapsed()); + } + else + { + CountFN++; + } + + mZT1TrainState = ZT1_WAIT_FOR_S1_STATE; //bogie is passed entirely, go back to state ZT1_WAIT_FOR_S1_STATE (state 1) + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MPM10_S2_ACTIVE_STATE: //8 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + + if(S1 == 0) + { + break; + } + else if(S1 == 1) + { + CountS1++; + TrainSpeed = (MPM_BOGIE_LENGTH / TrainSpeedTimer1.elapsed()) * 1000; // m/s + TrainSpeed *= 2.23694; // Mph + mZT1TrainState = ZT1_MPM10_S1_SECOND_PULSE_STATE; + // qDebug("Goto state 9"); + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MPM10_S1_SECOND_PULSE_STATE: //9 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + + if(FN == 1) + { + FNDetected = true; + } + + + if(S1 == 1) + { + break; + } + else if(S1 == 0 && S2 == 0) + { + mZT1TrainState = ZT1_MPM10_S1_S2_TRAINSIT_STATE; + } + else //S1 = 0 & S2 = 1 + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MPM10_S1_S2_TRAINSIT_STATE://10 + { + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + + } + + + if(S1 == 0 && S2 == 0) + { + break; + } + else if(S1 == 0 && S2 == 1) + { + CountS2++; + + TrainSpeed = (MPM_BOGIE_LENGTH / TrainSpeedTimer2.elapsed()) * 1000; // m/s + TrainSpeed *= 2.23694; // Mph + mZT1TrainState = ZT1_MPM10_S2_SECOND_PULSE_STATE; + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_MPM10_S2_SECOND_PULSE_STATE: //11 + { + + if(Pint == 1 && PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(Pext == 1 && PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + if(FN == 1) + { + FNDetected = true; + } + + if(PGCalibration) + { + + qint32 Value = PGint - PGIOffset; + if(Value < PGICalibValue) + PGICalibValue = Value; + + Value = PGExt - PGEOffset; + if(Value < PGECalibValue) + PGECalibValue = Value; + } + else if(PGActive == false) + { + //Compute and verify if the PG is detected. + Quadra = ((PGint - PGIOffset) * (PGExt - PGEOffset)); + if(Quadra > PGValueTreshold) + { + //The PG has been detected, stop sampling... + PGActive = true; + } + } + + if(S1 == 0 && S2 == 1) + { + break; + } + else if(S1 == 0 && S2 == 0) + { + if(PGCalibration) + { + CZTPGCalibrationData *Data = new CZTPGCalibrationData(); + Data->mTimestamp = mReferenceTimer->nsecsElapsed(); + Data->mPGExtValue = PGECalibValue; + Data->mPGIntValue = PGICalibValue; + + emit NewPGCalibrationData(Data); + PGICalibValue = PGIOffset; + PGECalibValue = PGEOffset; + + } + else if(PGActive == false) //The PG has not been detected... + { + RegisterDetection(DETECTION_PG_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + PGActive = false; + + if(FNDetected == false) + { + RegisterDetection(DETECTION_FN_DETECTION,Bogie,mReferenceTimer->nsecsElapsed()); + } + else + { + CountFN++; + } + + mZT1TrainState = ZT1_WAIT_FOR_S1_STATE; //bogie is passed entirely, go back to state ZT1_WAIT_FOR_S1_STATE (state 1) + } + else + { + RegisterDetection(DETECTION_MAGNETIC_SENSOR_COUNT,Rank,mReferenceTimer->nsecsElapsed()); + mZT1TrainState = ZT1_POST_ANALYSIS_MODE_STATE; + } + break; + } + case ZT1_POST_ANALYSIS_MODE_STATE: + { + //In this mode, there is no "Real Time" analysis. Data is stored and will be treated after + //the train has passed. + Bogie = 0; + CountFN = 0; + Rank = 0; + TrainSpeed = 0; + TrainType = TRAIN_TYPE_UNKNOWN; + CountS1 = 0; + CountS2 = 0; + + break; + } + + } //switch(mZT1TrainState) + + mLastInputs = PCIInputs; + mLastPGIntValue = PGint; + mLastPGExtValue = PGExt; + mLastSDFValue = SDFAnalog; + + CZT1ThreadData *Data = new CZT1ThreadData(); + Data->mTimeStamp = mReferenceTimer->nsecsElapsed(); + Data->mS1 = S1; + Data->mS2 = S2; + Data->mFN = FN; + Data->mPExt = Pext; + Data->mPInt = Pint; + Data->mPG = (PGActive == true); + Data->mPGIntValue = PGint; + Data->mPGExtValue = PGExt; + + Data->mBogie = Bogie; + Data->mFNCount = CountFN; + Data->mRank = Rank; + Data->mTrainSpeed = TrainSpeed; + Data->mTrainType = TrainType; + Data->mS1Count = CountS1; + Data->mS2Count = CountS2; + + emit ZT1DataUpdate(Data,LazerProbesTransitOnly,SDFAnalog); + + }//if(PCIInputs != mLastInputs) + + + mMutex.lock(); + if(mExitLoop == true) + Run = false; + mMutex.unlock(); + + }//if loop timeout expired + + }//while + + mZT1Analyzing = false; + +} + +void CZT1AnalysisThread::TerminateAnalysis() +{ + mMutex.lock(); + mExitLoop = true; + mMutex.unlock(); +} + +bool CZT1AnalysisThread::UpdateDetectionConfig(CZTDetectionFunctionConfig *NewConfig) +{ + //do not update in the middle of a train analysis. + bool Go; + mMutex.lock(); + Go = mZT1Analyzing; + mMutex.unlock(); + + if(Go == true) + return false; + + //No need for a Mutex here since the thread is + //not analyzing. + mDetectionConfig = *NewConfig; + + + return true; +} + +void CZT1AnalysisThread::RegisterDetection(unsigned int DetectionID, unsigned int Rank,qint64 TimeStamp) +{ + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive == false) + return; + + //Register an error only if the analysis is active + switch(DetectionID) + { + case DETECTION_MAGNETIC_SENSOR_COUNT: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive == false) + { + return; + } + break; + } + case DETECTION_PEQ1_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive == false) + { + return; + } + else + { + //If PEQ1 was already registered, ignore this occurence. + if(mPEQDetectionLatch == true) + { + return; + } + mPEQDetectionLatch = true; + } + break; + } + case DETECTION_FN_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive == false) + { + return; + } + break; + } + case DETECTION_PG_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive == false) + { + return; + } + break; + } + case DETECTION_PPI_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive == false) + { + return; + } + break; + } + case DETECTION_PPE_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive == false) + { + return; + } + break; + } + } + + CZTDetectionData *DetectData = new CZTDetectionData; + DetectData->mTimeStamp = TimeStamp; + DetectData->mRank = Rank; + DetectData->mDetectionID = DetectionID; + + emit DetectionTriggered(DetectData); + + +} + diff --git a/sources/ZT1AnalysisThread.h b/sources/ZT1AnalysisThread.h new file mode 100644 index 0000000..aa5ebc7 --- /dev/null +++ b/sources/ZT1AnalysisThread.h @@ -0,0 +1,122 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est un thread qui lit la carte PCI d'I/O sur laquelle sont + branchées les entrées à haute fréquence. La machine à états analyse le + passage du train et détecte les déclenchements (sondes, frotteur négatif, + pneu porteur). On utilise un thread car l'analyse doit se faire à très + haute fréquence sans être ralentie par l'interface graphique. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZT1ANALYSISTHREAD_H +#define ZT1ANALYSISTHREAD_H + +#define ZT1_ANALYSIS_LOOP_PERIOD 500000 //500 us + +#include +#include "GlobalDefine.h" +#include "Station.h" +#include +#include "ZTData.h" +#include "QElapsedTimer" +#include "AnalogInputModule.h" + +class CPCIIOMgr; +class CAbstractLazerProbe; + +class CZT1AnalysisThread : public QObject +{ + Q_OBJECT +public: + CZT1AnalysisThread(); + unsigned int Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks,CAbstractLazerProbe* PGExtHandle,CAbstractLazerProbe* PGIntHandle,QElapsedTimer *RefTimer,CAnalogInputModule *AnalogInterface); + void TerminateAnalysis(); //Fonction appelée pour terminer le thread + bool UpdateDetectionConfig(CZTDetectionFunctionConfig*); //Mise à jour des fonctions à inhiber + void SetPGTreshold(qint32 PGTreshold); //Mise à jour du seuil PG + bool SetPGCalibration(bool CalibON); //Démarrer ou arrêter la calibration PG. + +private: + enum eTrainState + { //Correspondance d'état dans la documentation + ZT1_PRE_DETECTION_STATE, + ZT1_WAIT_FOR_S1_STATE, //1 + ZT1_S1_ACTIVE_STATE, //2 + + ZT1_S1_TRANSIT_STATE, //3 + ZT1_S1_TANSIT_MR_STATE, //3_MR //After the train type is determined (1st bogie) we cannot change until the train is completely passed + ZT1_S1_TRANSIT_MPM_STATE, //3_MPM //so we need to have 1 seperate state for each type to detect counting errors after the 1st bogie + + ZT1_MR_S1_SECOND_PULSE_STATE, //4 + ZT1_MR_S2_ACTIVE_STATE, //5 + ZT1_MR_S2_TRANSIT_STATE, //6 + ZT1_MR_S2_SECOND_PULSE_STATE, //7 + + ZT1_MPM10_S2_ACTIVE_STATE, //8 + ZT1_MPM10_S1_SECOND_PULSE_STATE,//9 + ZT1_MPM10_S1_S2_TRAINSIT_STATE, //10 + ZT1_MPM10_S2_SECOND_PULSE_STATE,//11 + + ZT1_POST_ANALYSIS_MODE_STATE, //In this state, we do not analyze in real time, just accumulate data + + + ZT1_TRAIN_TRANSIT_FINISHED_STATE + + }; + + void RegisterDetection(unsigned int DetectionID, unsigned int Rank, qint64 TimeStamp); + + unsigned int mZT1TrainState; //état courant de la machine à état + unsigned int mLastInputs; //latch du dernier état des entrées discrètes + qint32 mLastPGIntValue, mLastPGExtValue; //latch du dernier état des sondes lazer + int mLastSDFValue; //latch de lecture du SDF + bool mExitLoop; //Flag qui indique si on doit terminer l'analyse + QMutex mMutex; //Un mutex pour partager les données entre les threads sans que ça plante + bool mZT1Analyzing; //Flag indiquant si le thread roule + qint32 mPGTreshold; //Valeur du seuil pneu de guidage + bool mPGCalibration; //Flag qui indique si on est présentement en calibration PG + bool mPEQDetectionLatch; //Flag nécessaire pour n'enregistrer le déclenchement PEQ1 qu'une seule fois. + + CPCIIOMgr *mPCIInputsHandle; //Pointeur vers le driver de la carte PCI d'entrées discrètes + GenericInputMasks_t *mInputMasksPtr; //Pointeur vers les masques d'entrées + CAbstractLazerProbe *mPGIntHandle, *mPGExtHandle; //pointeurs vers le driver des sondes lazer + CAnalogInputModule *mSDFAnalogInterface; //pointeur vers le driver du module d'acquisition analogique du SDF + + QElapsedTimer *mReferenceTimer; //pointeur vers le timer d'acquisition + + CZTDetectionFunctionConfig mDetectionConfig; //Flags qui indiquent quelles fonctions ne doivent pas êtres analysées (configuré dans l'écran Fonction Détections) + + +public slots: + void AnalyzeZT1Train(); //La boucle du thread + +signals: + + void ZT1DataUpdate(CZT1ThreadData*,bool, int); //Signal émis au state machine lorsqu'un nouvel échantillon est prêt (à chaque boucle) + void DetectionTriggered(CZTDetectionData* ); //Signal émis au state machine lorsqu'un déclenchement est détecté + void NewPGCalibrationData(CZTPGCalibrationData *); //Signal émis au state machine lorsqu'une donnée de calibration PG est prête + void NewZT1Flag(int,CZT1FlagsData*); //Signal émis au state machine lorsqu'une valeur de flag a changé. + void AddLogString(QString); //Signal émis pour insérer une ligne au ZTLog +}; + +#endif // ZT1ANALYSISTHREAD_H diff --git a/sources/ZT2AnalysisThread.cpp b/sources/ZT2AnalysisThread.cpp new file mode 100644 index 0000000..e92b8d9 --- /dev/null +++ b/sources/ZT2AnalysisThread.cpp @@ -0,0 +1,316 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est un thread qui roule en parallèle au programme. Elle est + responsable de l'analyse en temps réel du passage d'un train. Elle fait la + lecture des entrées sur la carte PCI et analyse les déclenchements au fur + et à mesure qu'un train chemine sur la ZT2 + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "GlobalDefine.h" +#include "ZT2AnalysisThread.h" +#include "PCIIOMgr.h" +#include "AbstractLazerProbe.h" +#include +#include "ZTconfigmgr.h" + +//const char * ErrorString[25] = {"Erreur de comptage S1-S2", +// "Déclenchement frotteur négatif", +// "Déclenchement pneu de guidage intérieur", +// "Déclenchement pneu de guidage extérieur", +// "Déclenchement pneu porteur intérieur", +// "Déclenchement pneu porteur extérieur", +// "Pré-détection frotteur négatif"}; + +CZT2AnalysisThread::CZT2AnalysisThread() +{ + mLastInputs = 0; + mZT2TrainState = ZT2_PRE_DETECTION_STATE; + + mPCIInputsHandle = 0; + mExitLoop = false; + mZT2Analyzing = false; +} + +unsigned int CZT2AnalysisThread::Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks,QElapsedTimer *RefTimer) +{ + mPCIInputsHandle = PCIIOHandle; + mInputMasksPtr = InputMasks; + mReferenceTimer = RefTimer; + + return RET_OK; +} + +void CZT2AnalysisThread::AnalyzeZT2Train() +{ + + qDebug("ZT2 Thread started!"); + mExitLoop = false; + mZT2Analyzing = true; + mPEQDetectionLatch = false; + + + mZT2TrainState = ZT2_PRE_DETECTION_STATE; + unsigned int PCIInputs = 0; + mLastInputs = 0; + bool Run = true; + + QElapsedTimer AcquisitionTimer; + AcquisitionTimer.start(); + + //inputs + unsigned int S1 = 0, Pint = 0, Pext = 0; + + //Train analysis variables + unsigned int Bogie = 0; + unsigned int Rank = 0; + unsigned int CountS1 = 0; + + + bool PPIDetected = false; + bool PPEDetected = false; + + + while(Run == true) + { + PCIInputs = mPCIInputsHandle->GetInputs(); + + if(PCIInputs != mLastInputs) + { + //Extract useful flags + + S1 = ((PCIInputs & mInputMasksPtr->InputZT2S1Mask) != 0); + Pint = ((PCIInputs & mInputMasksPtr->InputZT2PIMask) == 0); + Pext = ((PCIInputs & mInputMasksPtr->InputZT2PEMask) == 0); + + if(mZT2TrainState == ZT2_PRE_DETECTION_STATE) + { + + if(S1 != 0 || Pint != 0 || Pext != 0) + { + RegisterDetection(DETECTION_PEQ2_DETECTION,0,mReferenceTimer->nsecsElapsed()); + + if(S1 != 0) + { + emit AddLogString(QString("Panne équipement ZT2: Pré détection S1 = 1")); + } + if(Pint != 0) + { + emit AddLogString(QString("Panne équipement ZT2: Pré détection Pneu porteur intérieur = 1")); + } + if(Pext != 0) + { + emit AddLogString(QString("Panne équipement ZT2: Pré détection Pneu porteur extérieur = 1")); + } + } + mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; + } + + switch(mZT2TrainState) + { + case ZT2_PRE_DETECTION_STATE: + { + CEngLog::instance()->AddLogString("ZT2AnalysisThread::Logic error, in ZT2 Pre detection state and should not..."); + mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; + break; + } + case ZT2_WAIT_FOR_S1_STATE: + { + if(Pint != 0) + { + if(PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_ZT2_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + if(Pext != 0) + { + if(PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_ZT2_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + + if(S1 == 1) + { + Rank++; + CountS1++; + if(Rank %2 == 1) + Bogie++; + + PPIDetected = false; + PPEDetected = false; + + mZT2TrainState = ZT2_S1_ACTIVE_STATE; + } + break; + } + case ZT2_S1_ACTIVE_STATE: + { + if(Pint != 0) + { + if(PPIDetected == false) + { + PPIDetected = true; + RegisterDetection(DETECTION_ZT2_PPI_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + if(Pext != 0) + { + if(PPEDetected == false) + { + PPEDetected = true; + RegisterDetection(DETECTION_ZT2_PPE_DETECTION,Rank,mReferenceTimer->nsecsElapsed()); + } + } + + if(S1 == 0) + { + mZT2TrainState = ZT2_WAIT_FOR_S1_STATE; + } + break; + } + }//switch(mZT2TrainState) + + mLastInputs = PCIInputs; + + CZT2ThreadData *Data = new CZT2ThreadData(); + Data->mTimeStamp = mReferenceTimer->nsecsElapsed(); + // Data->mDateTime = QDateTime::currentDateTime(); + Data->mS1 = S1; + Data->mPPExt = Pext; + Data->mPPInt = Pint; + + Data->mBogie = Bogie; + Data->mRank = Rank; + Data->mS1Count = CountS1; + + + emit ZT2DataUpdate(Data); + + }//if(PCIInputs != mLastInputs) + + + mMutex.lock(); + if(mExitLoop == true) + Run = false; + mMutex.unlock(); + + }//while + + mZT2Analyzing = false; + +} + +void CZT2AnalysisThread::TerminateAnalysis() +{ + mMutex.lock(); + mExitLoop = true; + mMutex.unlock(); +} + +bool CZT2AnalysisThread::UpdateDetectionConfig(CZTDetectionFunctionConfig *NewConfig) +{ + //do not update in the middle of a train analysis. + bool Go; + mMutex.lock(); + Go = mZT2Analyzing; + mMutex.unlock(); + + if(Go == true) + return false; + + //No need for a Mutex here since the thread is + //not analyzing. + mDetectionConfig = *NewConfig; + + + return true; +} + +void CZT2AnalysisThread::RegisterDetection(unsigned int DetectionID, unsigned int Rank,qint64 TimeStamp) +{ + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == false) + return; + + + switch(DetectionID) + { + case DETECTION_PEQ2_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == false) + { + return; + } + break; + } + case DETECTION_ZT2_MAGNETIC_SENSOR_COUNT: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive == false) + { + return; + } + else + { + if(mPEQDetectionLatch == true) + { + return; + } + + mPEQDetectionLatch = true; + } + break; + } + case DETECTION_ZT2_PPI_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive == false) + { + return; + } + break; + } + case DETECTION_ZT2_PPE_DETECTION: + { + if(mDetectionConfig.mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive == false) + { + return; + } + break; + } + } + + + CZTDetectionData *DetectData = new CZTDetectionData; + DetectData->mTimeStamp = TimeStamp; + DetectData->mRank = Rank; + DetectData->mDetectionID = DetectionID; + + emit DetectionTriggered(DetectData); + + +// qDebug("%s -> Rang %d",CZTData::GetErrorString(DetectionID),Rank); +} + diff --git a/sources/ZT2AnalysisThread.h b/sources/ZT2AnalysisThread.h new file mode 100644 index 0000000..33901fb --- /dev/null +++ b/sources/ZT2AnalysisThread.h @@ -0,0 +1,94 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est un thread qui lit la carte PCI d'I/O sur laquelle sont + branchées les entrées à haute fréquence. La machine à états analyse le + passage du train et détecte les déclenchements (sondes, frotteur négatif, + pneu porteur). On utilise un thread car l'analyse doit se faire à très + haute fréquence sans être ralentie par l'interface graphique. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZT2ANALYSISTHREAD_H +#define ZT2ANALYSISTHREAD_H + +#define ZT2_ANALYSIS_LOOP_PERIOD 500000 //500 us + +#include +#include "GlobalDefine.h" +#include "Station.h" +#include +#include "ZTData.h" +#include "QElapsedTimer" + +class CPCIIOMgr; +//class CAbstractLazerProbe; + +class CZT2AnalysisThread : public QObject +{ + Q_OBJECT +public: + CZT2AnalysisThread(); + unsigned int Init(CPCIIOMgr *PCIIOHandle,GenericInputMasks_t *InputMasks,QElapsedTimer *RefTimer); + void TerminateAnalysis(); + bool UpdateDetectionConfig(CZTDetectionFunctionConfig*); + +private: + enum eTrainState + { + ZT2_PRE_DETECTION_STATE, + ZT2_WAIT_FOR_S1_STATE, + ZT2_S1_ACTIVE_STATE, + + ZT1_TRAIN_TRANSIT_FINISHED_STATE + + }; + + void RegisterDetection(unsigned int DetectionID, unsigned int Rank, qint64 TimeStamp); + + unsigned int mZT2TrainState; + unsigned int mLastInputs; + + bool mExitLoop; + QMutex mMutex; + bool mZT2Analyzing; + bool mPEQDetectionLatch; + + CPCIIOMgr *mPCIInputsHandle; + GenericInputMasks_t *mInputMasksPtr; + + QElapsedTimer *mReferenceTimer; + + CZTDetectionFunctionConfig mDetectionConfig; + + +public slots: + void AnalyzeZT2Train(); + +signals: + void ZT2DataUpdate(CZT2ThreadData* ); + void DetectionTriggered(CZTDetectionData* ); + void AddLogString(QString); //Signal émis pour insérer une ligne au ZTLog +}; + +#endif // ZT2ANALYSISTHREAD_H diff --git a/sources/ZTData.cpp b/sources/ZTData.cpp new file mode 100644 index 0000000..1894a40 --- /dev/null +++ b/sources/ZTData.cpp @@ -0,0 +1,367 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe fourre-tout qui contient les différentes structures données utilisées + un peu partout dans le programme. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZTData.h" + +const char * CZTData::TrainTypeString[] = {"Inconnu","MR63/73", "MPM10"}; +CZTData::CZTData() +{ +} + +const char * CZTData::ErrorString[] = {"Erreur de comptage S1-S2", + "Déclenchement frotteur négatif", + "Déclenchement pneu de guidage", + "Déclenchement pneu porteur intérieur", + "Déclenchement pneu porteur extérieur", + + "Erreur de comptage ZT2", + "Déclenchement pneu porteur intérieur ZT2", + "Déclenchement pneu porteur extérieur ZT2", + + "Panne équipement ZT1", + "Panne équipement ZT2", + + }; + +const char * CZTData::ShortErrorString[] = {"V00", + "DFN", + "DPG", + "DPPI", + "DPPE", + + "V002", + "DPPI2", + "DPPE2", + + "PEQ1", + "PEQ2"}; + +const char* CZTData::GetErrorString(unsigned int ErrorID) +{ + if(ErrorID >= DETECTION_MAX_DETECTION_ID) + ErrorID = 0; + return ErrorString[ErrorID]; +} + +const char* CZTData::GetShortErrorString(unsigned int ErrorID) +{ + if(ErrorID >= DETECTION_MAX_DETECTION_ID) + ErrorID = 0; + return ShortErrorString[ErrorID]; +} + +const char* CZTData::GetTrainTypeString(unsigned int TrainType) +{ + if(TrainType >= TRAIN_TYPE_MAX_ID) + TrainType = TRAIN_TYPE_UNKNOWN; + return TrainTypeString[TrainType]; +} + + +CZT1LogData::CZT1LogData(CZT1ThreadData *ThreadData): + mZT1ThreadData(ThreadData) +{ +} +CZT1LogData::~CZT1LogData() +{ + if(mZT1ThreadData != 0) + delete mZT1ThreadData; +} + +CZT1ThreadData::~CZT1ThreadData() +{ + +} + +void CZT1ThreadData::operator =(CZT1ThreadData& TD) +{ + mTimeStamp = TD.mTimeStamp; + mDateTime = TD.mDateTime; + mS1 = TD.mS1; + mS2 = TD.mS2; + mPInt = TD.mPInt; + mPExt = TD.mPExt; + mFN = TD.mFN; + mPG = TD.mPG; + + mBogie = TD.mBogie; + mRank = TD.mRank; + mS1Count = TD.mS1Count; + mS2Count = TD.mS2Count; + mFNCount = TD.mFNCount; + mPGExtValue = TD.mPGExtValue; + mPGIntValue = TD.mPGIntValue; + mTrainSpeed = TD.mTrainSpeed; + mTrainType = TD.mTrainType; +} + + + +QDataStream &operator<<(QDataStream &out, const CZT1FlagsData &source) +{ + out << source.mExtPGOffset + << source.mIntPGOffset + << source.mPGCalibrationON + << source.mPGTresholdValue + << source.mAnalogTracePresent + << source.mIsProblematicPassage; + + //do not save mPEQ1Type + + return out; +} + +QDataStream &operator>>(QDataStream &in, CZT1FlagsData &dest) +{ + in >> dest.mExtPGOffset + >> dest.mIntPGOffset + >> dest.mPGCalibrationON + >> dest.mPGTresholdValue + >> dest.mAnalogTracePresent + >> dest.mIsProblematicPassage; + + //do not restore mPEQ1Type + + return in; +} + +QDataStream &operator<<(QDataStream &out, const CZT2FlagsData &source) +{ + out << source.mIsProblematicPassage; + + return out; +} + +QDataStream &operator>>(QDataStream &in, CZT2FlagsData &dest) +{ + in >> dest.mIsProblematicPassage; +} + +QDataStream& operator<<(QDataStream &out, const CZT1LogData &source) +{ + quint32 ThreadDataValid = 0; + if(source.mZT1ThreadData != 0) + ThreadDataValid = 1; + + + out << source.mDateTime + << source.mTimestamp + << source.mCIZT1 + << source.mCDVApproach_ZT1 + << source.mCDVARM_ZT1 + << ThreadDataValid; + + if(ThreadDataValid == 1) + { + out << source.mZT1ThreadData->mS1 + << source.mZT1ThreadData->mS2 + << source.mZT1ThreadData->mFN + << source.mZT1ThreadData->mPInt + << source.mZT1ThreadData->mPExt + << source.mZT1ThreadData->mPG + << source.mZT1ThreadData->mTrainSpeed + << source.mZT1ThreadData->mBogie + << source.mZT1ThreadData->mRank + << source.mZT1ThreadData->mPGExtValue + << source.mZT1ThreadData->mPGIntValue + << source.mZT1ThreadData->mTrainType + << source.mZT1ThreadData->mS1Count + << source.mZT1ThreadData->mS2Count; + } + + return out; +} + +QDataStream &operator>>(QDataStream &in, CZT1LogData &dest) +{ + quint32 ThreadValid; + in >> dest.mDateTime + >> dest.mTimestamp + >> dest.mCIZT1 + >> dest.mCDVApproach_ZT1 + >> dest.mCDVARM_ZT1 + >> ThreadValid; + if(ThreadValid == 1) + { + dest.mZT1ThreadData = new CZT1ThreadData(); + in >> dest.mZT1ThreadData->mS1 + >> dest.mZT1ThreadData->mS2 + >> dest.mZT1ThreadData->mFN + >> dest.mZT1ThreadData->mPInt + >> dest.mZT1ThreadData->mPExt + >> dest.mZT1ThreadData->mPG + >> dest.mZT1ThreadData->mTrainSpeed + >> dest.mZT1ThreadData->mBogie + >> dest.mZT1ThreadData->mRank + >> dest.mZT1ThreadData->mPGExtValue + >> dest.mZT1ThreadData->mPGIntValue + >> dest.mZT1ThreadData->mTrainType + >>dest.mZT1ThreadData->mS1Count + >>dest.mZT1ThreadData->mS2Count; + } + + return in; +} + + +QDataStream &operator<<(QDataStream &out, const CZTDetectionData &source) +{ + out << source.mTimeStamp + << source.mRank + << source.mDetectionID; + + return out; +} + +QDataStream &operator>>(QDataStream &in, CZTDetectionData &dest) +{ + in >> dest.mTimeStamp + >> dest.mRank + >> dest.mDetectionID; + + return in; +} + +void CZTDetectionData::operator =(const CZTDetectionData& DT) +{ + mDetectionID = DT.mDetectionID; + mRank = DT.mRank; + mTimeStamp = DT.mTimeStamp; +} + +CZTDetectionData::CZTDetectionData() +{ + mTimeStamp = 0; + mDetectionID = 0; + mRank = 0; +} + +CZT2LogData::CZT2LogData(CZT2ThreadData *ThreadData): + mZT2ThreadData(ThreadData) +{ +} +CZT2LogData::~CZT2LogData() +{ + if(mZT2ThreadData != 0) + delete mZT2ThreadData; +} + + +QDataStream& operator<<(QDataStream &out, const CZT2LogData &source) +{ + quint32 ThreadDataValid = 0; + if(source.mZT2ThreadData != 0) + ThreadDataValid = 1; + + out << source.mDateTime + << source.mTimestamp + << source.mCIZT2 + << source.mCDVARM_ZT2 + << source.mCDVApproach_ZT2 + << ThreadDataValid; + + if(ThreadDataValid == 1) + { + out << source.mZT2ThreadData->mS1 + << source.mZT2ThreadData->mPPInt + << source.mZT2ThreadData->mPPExt + << source.mZT2ThreadData->mBogie + << source.mZT2ThreadData->mRank + << source.mZT2ThreadData->mS1Count; + } + + return out; +} + +QDataStream &operator>>(QDataStream &in, CZT2LogData &dest) +{ + quint32 ThreadValid; + in >> dest.mDateTime + >> dest.mTimestamp + >> dest.mCIZT2 + >> dest.mCDVARM_ZT2 + >> dest.mCDVApproach_ZT2 + >> ThreadValid; + if(ThreadValid == 1) + { + dest.mZT2ThreadData = new CZT2ThreadData(); + in >> dest.mZT2ThreadData->mS1 + >> dest.mZT2ThreadData->mPPInt + >> dest.mZT2ThreadData->mPPExt + >> dest.mZT2ThreadData->mBogie + >> dest.mZT2ThreadData->mRank + >> dest.mZT2ThreadData->mS1Count; + } + + return in; +} + +CZTDetectionFunctionConfig::CZTDetectionFunctionConfig() +{ + for(int i = 0; i < DETECTION_FCT_MAX_FCT; i++) + { + mZTDetectionConfig[i].AnalysisActive = false; + mZTDetectionConfig[i].TKActive = false; + } +} + +void CZTDetectionFunctionConfig::operator =(CZTDetectionFunctionConfig& DF) +{ + for(int i = 0; i < DETECTION_FCT_MAX_FCT; i++) + { + mZTDetectionConfig[i].AnalysisActive = DF.mZTDetectionConfig[i].AnalysisActive; + mZTDetectionConfig[i].TKActive = DF.mZTDetectionConfig[i].TKActive; + } +} + +QDataStream &operator<<(QDataStream &out, const CZTDetectionFunctionConfig &source) +{ + for(int i = 0; i < DETECTION_FCT_MAX_FCT; i++) + { + out << source.mZTDetectionConfig[i].AnalysisActive + << source.mZTDetectionConfig[i].TKActive; + } + return out; +} + +QDataStream &operator>>(QDataStream &in, CZTDetectionFunctionConfig &dest) +{ + for(int i = 0; i < DETECTION_FCT_MAX_FCT; i++) + { + in >> dest.mZTDetectionConfig[i].AnalysisActive + >> dest.mZTDetectionConfig[i].TKActive; + } + return in; +} + +CZTSettingsData::CZTSettingsData() +{ + mDetectionFunctionSettings = new CZTDetectionFunctionConfig(); + mAutoExportZT1CSV = false; + mAutoExportZT2CSV = false; +} diff --git a/sources/ZTData.h b/sources/ZTData.h new file mode 100644 index 0000000..eacb0d1 --- /dev/null +++ b/sources/ZTData.h @@ -0,0 +1,342 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Ces classes contiennent l'état de la Zone Tests et les informations nécessaires + au fonctionnement des machines à états. +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130501 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZTDATA_H +#define ZTDATA_H + +#include "GlobalDefine.h" +#include +#include +#include +#include + +enum eZTLOGType +{ + ZT1_LOG_TYPE, + ZT2_LOG_TYPE, + UNKNOWN_LOG_TYPE +}; + +enum eCDVState +{ + CDV_STATE_OCCUPIED, + CDV_STATE_FREE, + CDV_STATE_ITI_CMD, + CDV_STATE_UNKNOWN +}; + +enum eSwitchCVDPosition +{ + SWITCH_CDV_NORMAL_POSITION, + SWITCH_CDV_REVERSE_POSITION, + SWITCH_CDV_UNKNOWN_POSITION +}; + +enum eCDVType +{ + CDV_NORMAL_TYPE, + CDV_SWITCH_TYPE +}; + +enum eDetectionID +{ + DETECTION_MAGNETIC_SENSOR_COUNT, + DETECTION_FN_DETECTION, + DETECTION_PG_DETECTION, + DETECTION_PPI_DETECTION, + DETECTION_PPE_DETECTION, + + DETECTION_ZT2_MAGNETIC_SENSOR_COUNT, + DETECTION_ZT2_PPI_DETECTION, + DETECTION_ZT2_PPE_DETECTION, + + DETECTION_PEQ1_DETECTION, + DETECTION_PEQ2_DETECTION, + + DETECTION_MAX_DETECTION_ID +}; + +enum eDetectionFunctionID +{ + DETECTION_FCT_FN, + DETECTION_FCT_PG, + DETECTION_FCT_PP, + DETECTION_FCT_PP2, + DETECTION_FCT_ZT1, + DETECTION_FCT_ZT2, + + DETECTION_FCT_MAX_FCT +}; + +enum ePEQ1Types +{ + PEQ1_UNKNOWN_TYPE, + PEQ1_FN_PREDETECTION_TYPE, + PEQ1_PG_PREDETECTION_TYPE, + PEQ1_PINT_PREDETECTION_TYPE, + PEQ1_PEXT_PREDETECTION_TYPE, + PEQ1_MAG_SENSOR_S1_PREDETECTION_TYPE, + PEQ1_MAG_SENSOR_S2_PREDETECTION_TYPE, + PEQ1_LAZER_SENSOR_INT_PREDETECTION_TYPE, + PEQ1_LAZER_SENSOR_EXT_PREDETECTION_TYPE, + PEQ1_FN_STUCK_LOW_TYPE, + + PEQ1_MAX_TYPE +}; + +enum eTrainTypeID +{ + TRAIN_TYPE_UNKNOWN, + TRAIN_TYPE_MR63_MR73, + TRAIN_TYPE_MPM10, + + + TRAIN_TYPE_MAX_ID +}; + +enum eZT1FlagsID +{ + ZT1_INT_PG_OFFSET_FLAG_ID, + ZT1_EXT_PG_OFFSET_FLAG_ID, + ZT1_PG_TRESHOLD_VALUE_FLAG_ID, + ZT1_PG_CALIB_ON_FLAG_ID, + ZT1_PEQ_TYPE_FLAG_ID, + + + ZT1_MAX_FLAG_ID +}; + +enum eZTTypeID +{ + ZT1_TYPE_ID, + ZT2_TYPE_ID, + ZTGLOBAL_TYPE_ID, + + ZT_MAX_TYPE_ID +}; + +class CZTData +{ +public: + CZTData(); + + + + unsigned int mCIZT2; + + static const char *ErrorString[]; + static const char *ShortErrorString[]; + static const char* GetErrorString(unsigned int ErrorID); + static const char* GetShortErrorString(unsigned int ErrorID); + + static const char *TrainTypeString[]; + static const char *GetTrainTypeString(unsigned int TrainType); + +}; + +//This class contains data from the ZT1 analysis thread +//that is periodically communicated to the main thread +class CZT1ThreadData +{ + +public: + ~CZT1ThreadData(); + qint64 mTimeStamp; //nanosecs + QDateTime mDateTime; + quint32 mS1; + quint32 mS2; + quint32 mPInt; + quint32 mPExt; + quint32 mFN; + quint32 mPG; + + quint32 mBogie; + quint32 mRank; + quint32 mS1Count; + quint32 mS2Count; + quint32 mFNCount; + qint32 mPGExtValue; + qint32 mPGIntValue; + qreal mTrainSpeed; + quint32 mTrainType; + + void operator=(CZT1ThreadData& a); +}; + + +class CZT1FlagsData +{ +public: + qint32 mIntPGOffset; + qint32 mExtPGOffset; + qint32 mPGTresholdValue; + qint32 mPGCalibrationON; + qint32 mAnalogTracePresent; + qint32 mIsProblematicPassage; //This flag will be set if problems have been detected but not sent to PCC due to PURE comitee rules. + qint32 mPEQ1Type; //Not saved in passage files... +}; +QDataStream &operator<<(QDataStream &out, const CZT1FlagsData &source); +QDataStream &operator>>(QDataStream &in, CZT1FlagsData &dest); + +class CZT2FlagsData +{ +public: + qint32 mIsProblematicPassage; //This flag will be set if problems have been detected but not sent to PCC due to PURE comitee rules. +}; +QDataStream &operator<<(QDataStream &out, const CZT2FlagsData &source); +QDataStream &operator>>(QDataStream &in, CZT2FlagsData &dest); + + +class CZT1LogData +{ +public: + CZT1LogData(CZT1ThreadData *ThreadData = 0); + ~CZT1LogData(); + + QDateTime mDateTime; + qint64 mTimestamp; + quint32 mCIZT1; + quint32 mCDVApproach_ZT1; + quint32 mCDVARM_ZT1; + qint32 mAnalogData; //The analog data must be written or read to/from file manually (not part of the QStream << operator overloading) + + CZT1ThreadData *mZT1ThreadData; +}; + +class CZT1Log +{ +public: + QVector mZT1LogData; + CZT1FlagsData mZT1Flags; +}; + +QDataStream &operator<<(QDataStream &out, const CZT1LogData &source); +QDataStream &operator>>(QDataStream &in, CZT1LogData &dest); + +class CZT2ThreadData +{ +public: + qint64 mTimeStamp; + quint32 mS1; + quint32 mPPInt; + quint32 mPPExt; + + quint32 mBogie; + quint32 mRank; + quint32 mS1Count; +}; + +class CZTDetectionData +{ +public: + + CZTDetectionData(); + qint64 mTimeStamp; +// QDateTime mDateTime; + quint32 mDetectionID; + quint32 mRank; +// quint32 mBogie; + + void operator=(const CZTDetectionData &in); + +}; +QDataStream &operator<<(QDataStream &out, const CZTDetectionData &source); +QDataStream &operator>>(QDataStream &in, CZTDetectionData &dest); + + + + +class CZT2LogData +{ +public: + CZT2LogData(CZT2ThreadData *ThreadData = 0); + ~CZT2LogData(); + + QDateTime mDateTime; + qint64 mTimestamp; + quint32 mCIZT2; + quint32 mCDVARM_ZT2; + quint32 mCDVApproach_ZT2; + + CZT2ThreadData *mZT2ThreadData; +}; +QDataStream &operator<<(QDataStream &out, const CZT2LogData &source); +QDataStream &operator>>(QDataStream &in, CZT2LogData &dest); + +class CZT2Log +{ +public: + QVector mZT2LogData; + CZT2FlagsData mZT2Flags; +}; + +class CZTDetectionConfig +{ +public: + bool AnalysisActive; + bool TKActive; +}; + +class CZTDetectionFunctionConfig +{ +public: + CZTDetectionFunctionConfig(); + CZTDetectionConfig mZTDetectionConfig[DETECTION_FCT_MAX_FCT]; + + void operator=(CZTDetectionFunctionConfig& a); + +}; + +QDataStream &operator<<(QDataStream &out, const CZTDetectionFunctionConfig &source); +QDataStream &operator>>(QDataStream &in, CZTDetectionFunctionConfig &dest); + +class CZTSettingsData +{ + public: + CZTSettingsData(); + + CZTDetectionFunctionConfig *mDetectionFunctionSettings; + bool mAutoExportZT1CSV; + bool mAutoExportZT2CSV; + int mPGTreshold; + int mMaxLogCount; + bool mKeepMPM10Logs; + bool mKeepAllZT1Logs; + bool mKeepAllZT2Logs; + +}; + +class CZTPGCalibrationData +{ + public: + qint64 mTimestamp; + int mTrainNbr; + qint32 mPGExtValue; + qint32 mPGIntValue; +}; + +#endif // ZTDATA_H diff --git a/sources/ZTLog.cpp b/sources/ZTLog.cpp new file mode 100644 index 0000000..ab10757 --- /dev/null +++ b/sources/ZTLog.cpp @@ -0,0 +1,198 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe permet de créer un fichier log. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZTLog.h" +#include +#include +#include +#include "EngLog.h" +#include + +//singleton instantiation +CZTLog CZTLog::mSingleton; + +CZTLog::CZTLog(): + mZTLogFile(NULL) +{ + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + mLogBuffer.clear(); + mLogBufferToEngLog = false; + mProgramHandle = 0; +} + +CZTLog::~CZTLog() +{ + if(mZTLogFile) + { + mZTLogFile->close(); + delete mZTLogFile; + } +} + +void CZTLog::Init() +{ + QString FileName; + FileName = "./LOG/LogZT.txt"; + + mZTLogFile = new QFile(FileName); + if(mZTLogFile) + { + mZTLogFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text | QIODevice::Unbuffered); + + QString temp; + mZTLogFile->write("\n\n"); + AddLogString(temp.sprintf("********************************************************************")); + AddLogString(temp.sprintf("Démarrage du logiciel ZT le %s à %s",QDateTime::currentDateTime().date().toString("yyyy-MM-dd").toAscii().data(),QDateTime::currentDateTime().time().toString("hh:mm:ss").toAscii().data())); + AddLogString(temp.sprintf("********************************************************************")); + } +} + +void CZTLog::AddLogString(QString string,bool AddToEngLog) +{ +// qDebug(string.toUtf8().data()); + + if(mZTLogFile == NULL) + return; + + if(mZTLogFile->isOpen() == false) + return; + + if(AddToEngLog) + CEngLog::instance()->AddLogString(string); + + if(string.at(string.length()-1) != '\n') + string.append('\n'); + + if(string.length() > 1) + string.prepend(QDateTime::currentDateTime().toString("yyyy/MM/dd - hh:mm:ss.zzz : ").toAscii().data()); + + mZTLogFile->write(string.toUtf8()); + + + +//#ifndef WINDOWS_OS +// system("sync"); +//#endif + +} + +void CZTLog::AddBufferString(QString string, bool AddToEngLog, bool ForceWrite) +{ + if(string.at(string.length()-1) != '\n') + string.append('\n'); + + if(string.length() > 1) + string.prepend(QDateTime::currentDateTime().toString("yyyy/MM/dd - hh:mm:ss.zzz : ").toAscii().data()); + + mLogBuffer += string; + + if(AddToEngLog) + mLogBufferToEngLog = true; + + if(ForceWrite) + mForceWriteBuffer = true; +} + +void CZTLog::ClearBufferString() +{ + mLogBuffer.clear(); + mLogBufferToEngLog = false; + mForceWriteBuffer = false; +} + +void CZTLog::WriteBufferToLog() +{ + if(mLogBufferToEngLog) + { + CEngLog::instance()->WriteFormattedString(mLogBuffer); + } + + mZTLogFile->write(mLogBuffer.toUtf8()); + + ClearBufferString(); +} + +unsigned int CZTLog::CopyLogFile(QString Dest,bool DeleteIfPresent) +{ + if(QFile::exists(Dest)) + { + if(DeleteIfPresent == false) + return RET_ERROR; + + QFile::remove(Dest); + } + mZTLogFile->close(); + QFile::copy("./LOG/LogZT.txt",Dest); + mZTLogFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text | QIODevice::Unbuffered); + + return RET_OK; +} + +unsigned int CZTLog::DeleteLogFile() +{ + mZTLogFile->remove(); + delete mZTLogFile; + + mZTLogFile = new QFile("./LOG/LogZT.txt"); + if(mZTLogFile) + { + mZTLogFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text | QIODevice::Unbuffered); + + QString temp; + mZTLogFile->write("\n\n"); + AddLogString(temp.sprintf("********************************************************************")); + AddLogString(temp.sprintf("Création d'un nouveau fichier LOG après sa destruction le %s à %s",QDateTime::currentDateTime().date().toString("yyyy-MM-dd").toAscii().data(),QDateTime::currentDateTime().time().toString("hh:mm:ss").toAscii().data())); + AddLogString(temp.sprintf("********************************************************************")); + } + mZTLogFile->flush(); + + + //Insert the current ZT settings in the log file. + if(mProgramHandle != 0) + { + mProgramHandle->LogZTSettingsRequest(true); + } + + + + + return RET_OK; +} + +QString CZTLog::GetEntireLogFile() +{ + mZTLogFile->close(); + mZTLogFile->open(QIODevice::ReadOnly | QIODevice::Text); + QTextStream Stream(mZTLogFile); + + QString str = Stream.readAll(); + + mZTLogFile->close(); + mZTLogFile->open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text | QIODevice::Unbuffered); + + return str; +} diff --git a/sources/ZTLog.h b/sources/ZTLog.h new file mode 100644 index 0000000..b865cf7 --- /dev/null +++ b/sources/ZTLog.h @@ -0,0 +1,69 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20130201 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include "GlobalDefine.h" + +#ifndef ZTLOG_H +#define ZTLOG_H + +#include +#include "Zonetest.h" + + +class CZTLog +{ +public: + + //CEngLog is a singleton class + static CZTLog* instance(){return &mSingleton;} + static CZTLog mSingleton; + + CZTLog(); + ~CZTLog(); + + void AddLogString(QString string,bool AddToEngLog = false); + void AddBufferString(QString string, bool AddToEngLog = false, bool ForceWrite = false); + void ClearBufferString(); + void WriteBufferToLog(); + void Init(); + bool IsWriteForced(){return mForceWriteBuffer;} + unsigned int CopyLogFile(QString Dest,bool DeleteIfPresent = false); + unsigned int DeleteLogFile(); + QString GetEntireLogFile(); + + CZoneTest *mProgramHandle; + +private: + QFile *mZTLogFile; + QString mLogBuffer; + bool mLogBufferToEngLog; + bool mForceWriteBuffer; + + + +}; + +#endif // ZTLOG_H diff --git a/sources/ZTSettings.cpp b/sources/ZTSettings.cpp new file mode 100644 index 0000000..792b9e7 --- /dev/null +++ b/sources/ZTSettings.cpp @@ -0,0 +1,230 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Utilisée pour la configuration non volatile de certains paramètres comme + les fonction de détection hors service (TK HS). Les paramètres sont sauvegardés + dans un fichier binaire qui est ouvert au démarrage du programme. +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121219 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZTSettings.h" +#include "EngLog.h" +#include +#include "ZTLog.h" +#include "ZTVersion.h" + +CZTSettingsFileMgr::CZTSettingsFileMgr() +{ + mStationName = "Inconnue"; +} + +unsigned int CZTSettingsFileMgr::LoadSettings(CZTSettingsData *SettingsData) +{ + QFile* SettingsFile = new QFile("./Configuration/ZTSettings.ztc"); + if(SettingsFile) + { + if(SettingsFile->open(QIODevice::ReadOnly | QIODevice::Unbuffered) == false) + { + CEngLog::instance()->AddLogString("Impossible d'ouvrir (open()) le fichier de settings. Chargement des paramètres par défaut",1); + LoadDefaultSettings(SettingsData); + CEngLog::instance()->AddLogString("Tentative de créer un fichier de settings par défaut.",1); + SaveSettings(SettingsData); + return RET_ERROR; + } + } + else + { + CEngLog::instance()->AddLogString("Impossible d'ouvrir (new Qfile()) le fichier de settings. Chargement des paramètres par défaut",1); + LoadDefaultSettings(SettingsData); + CEngLog::instance()->AddLogString("Tentative de créer un fichier de settings par défaut.",1); + return RET_ERROR; + } + + QDataStream * InputStream = new QDataStream(SettingsFile); + + quint32 MagicNbr;// = 0xBAADCAFE; + + *InputStream >> MagicNbr; + + if(MagicNbr != 0xBAADCAFE + 1) + { + CEngLog::instance()->AddLogString("Fichier de settings invalide (mauvais magic number). Chargement des paramètres par défaut"); + LoadDefaultSettings(SettingsData); + return RET_ERROR; + } + + *InputStream >> *(SettingsData->mDetectionFunctionSettings); + *InputStream >> SettingsData->mAutoExportZT1CSV; + *InputStream >> SettingsData->mAutoExportZT2CSV; + *InputStream >> SettingsData->mPGTreshold; + *InputStream >> SettingsData->mMaxLogCount; + *InputStream >> SettingsData->mKeepMPM10Logs; + *InputStream >> SettingsData->mKeepAllZT1Logs; + *InputStream >> SettingsData->mKeepAllZT2Logs; + + + SettingsFile->close(); + delete SettingsFile; + delete InputStream; + + LogSettings(SettingsData); + + return RET_OK; +} + +unsigned int CZTSettingsFileMgr::SaveSettings(CZTSettingsData *SettingsData) +{ + QFile* SettingsFile = new QFile("./Configuration/ZTSettings.ztc"); + if(SettingsFile) + { + if(SettingsFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered) == false) + { + CEngLog::instance()->AddLogString("Impossible de créer le fichier de settings (open())."); + return RET_ERROR; + } + } + else + { + CEngLog::instance()->AddLogString("Impossible de créer le fichier de settings (new QFile())"); + return RET_ERROR; + } + + QDataStream * OutputStream = new QDataStream(SettingsFile); + + quint32 MagicNbr = 0xBAADCAFE + 1; + + *OutputStream << MagicNbr; + + + *OutputStream << *(SettingsData->mDetectionFunctionSettings); + *OutputStream << SettingsData->mAutoExportZT1CSV; + *OutputStream << SettingsData->mAutoExportZT2CSV; + *OutputStream << SettingsData->mPGTreshold; + *OutputStream << SettingsData->mMaxLogCount; + *OutputStream << SettingsData->mKeepMPM10Logs; + *OutputStream << SettingsData->mKeepAllZT1Logs; + *OutputStream << SettingsData->mKeepAllZT2Logs; + + SettingsFile->flush(); + SettingsFile->close(); + + delete SettingsFile; + delete OutputStream; + + CZTLog::instance()->AddLogString("Changement de settings",true); + LogSettings(SettingsData); + + return RET_OK; +} + +void CZTSettingsFileMgr::LoadDefaultSettings(CZTSettingsData *SettingsData) +{ + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive = true; + + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].TKActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].TKActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].TKActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive = true; + SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive = true; + + SettingsData->mAutoExportZT1CSV = false; + SettingsData->mAutoExportZT2CSV = false; + + SettingsData->mPGTreshold = 125; + SettingsData->mMaxLogCount = 100; + SettingsData->mKeepMPM10Logs = false; + SettingsData->mKeepAllZT1Logs = false; + SettingsData->mKeepAllZT2Logs = false; + +} +void CZTSettingsFileMgr::SetStationName(QString StationName) +{ + mStationName = StationName; +} + +void CZTSettingsFileMgr::LogSettings(CZTSettingsData *SettingsData, bool LogStationName) +{ + QString temp; + temp.clear(); + QTextStream stream(&temp); + CZTLog::instance()->AddLogString(QString().sprintf("Version logiciel: %s",ZT_SOFT_VERSION),true); + if(LogStationName) + { + CZTLog::instance()->AddLogString(QString().sprintf("Station: %s",mStationName.toUtf8().data())); + } + CZTLog::instance()->AddLogString("Configuration de la ZT: ",true); + + + stream << " Analyse FN = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Analyse PG = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Analyse PP ZT1 = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Analyse PP ZT2 = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " TK FN = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].TKActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " TK PG = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].TKActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " TK PP ZT1 = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].TKActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " TK PP ZT2 = " << SettingsData->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Exportation automatique ZT1 CSV = " << SettingsData->mAutoExportZT1CSV; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Exportation automatique ZT2 CSV = " << SettingsData->mAutoExportZT2CSV; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Seuil PG = " << SettingsData->mPGTreshold; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Nb fichiers de passage = " << SettingsData->mMaxLogCount; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Conserver LOGS MPM10 = " << SettingsData->mKeepMPM10Logs; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Conserver LOGS ZT1 = " << SettingsData->mKeepAllZT1Logs; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + stream << " Conserver LOGS ZT2 = " << SettingsData->mKeepAllZT2Logs; + CZTLog::instance()->AddLogString(temp,true); + temp.clear(); + +} + diff --git a/sources/ZTSettings.h b/sources/ZTSettings.h new file mode 100644 index 0000000..0a1ab7d --- /dev/null +++ b/sources/ZTSettings.h @@ -0,0 +1,24 @@ +#ifndef ZTSETTINGS_H +#define ZTSETTINGS_H + +#include "GlobalDefine.h" +#include "ZTData.h" + +class CZTSettingsFileMgr +{ +public: + CZTSettingsFileMgr(); + + unsigned int LoadSettings(CZTSettingsData *SettingsData); + unsigned int SaveSettings(CZTSettingsData *SettingsData); + void LoadDefaultSettings(CZTSettingsData *SettingsData); + void LogSettings(CZTSettingsData *SettingsData,bool LogStationName = false); + void SetStationName(QString StationName); + +private: + QString mStationName; + + +}; + +#endif // ZTSETTINGS_H diff --git a/sources/ZTStateMachine.cpp b/sources/ZTStateMachine.cpp new file mode 100644 index 0000000..24890f9 --- /dev/null +++ b/sources/ZTStateMachine.cpp @@ -0,0 +1,1806 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Machine à état principale de la ZT. Elle lit les entrées des CDV et des CI + et démarre le thread d'analyse lorsqu'un train procède sur la ZT. La classe + gère aussi la compilation des déclenchements et des logs de passage. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZTStateMachine.h" +#include "ZTSimulator.h" +#include +#include +#include +#include "ZTLog.h" +#include "math.h" +#include "MaintenancePage.h" +#include "RamMonitor.h" +#include "ModbusCCDefs.h" + +CZTStateMachine::CZTStateMachine(QObject *parent) : + QObject(parent) +{ + QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); + + mZT1State = ZT1_WAIT_FOR_CI_STATE; + mZT2State = ZT2_WAIT_FOR_CI_STATE; + mZTState = ZT_INIT_STATE; + mZT2Present = true; + +// mZTDataPtr = new CZTData; + mZTStationPtr = 0; + mZTDetectionConfig = 0; + + mLastInputs = 0; + mZtSimPtr = 0; + mLogMgr = 0; + mCalibrationPassagesCount = 0; + mCCModbusRepo = 0; + //mExtIOInterface = 0; + + mNbPassages = 0; + mNbTriggers = 0; +// mZT1Active = false; //JFM ztstatus +// mZT2Active = false; + mZT1ActiveStatus = SB_ZT_INACTIVE_STATUS; + mZT2ActiveStatus = SB_ZT_INACTIVE_STATUS; + + mCIZT1Active = false; + + mLogDelay = ZT_SM_DEFAULT_LOG_DELAY; + + mAutoExportZT1CSV = false; + mAutoExportZT2CSV = false; + + //mTKGenerator = new CTKGenerator(); + + mIsPGCalibON = false; + mIsMaintenanceModeON = false; + + //Create the ZT1 train analysis thread + mZT1SMThread = new QThread; + mZT1WorkerThread = new CZT1AnalysisThread(); + mZT1WorkerThread->moveToThread(mZT1SMThread); + connect(mZT1SMThread,SIGNAL(started()),mZT1WorkerThread,SLOT(AnalyzeZT1Train())); + connect(mZT1WorkerThread,SIGNAL(ZT1DataUpdate(CZT1ThreadData*,bool,int)),this,SLOT(ZT1StateChanged(CZT1ThreadData*,bool,int))); + connect(mZT1WorkerThread,SIGNAL(DetectionTriggered(CZTDetectionData*)),this,SLOT(ZT1NewDetection(CZTDetectionData*))); + connect(mZT1WorkerThread,SIGNAL(NewPGCalibrationData(CZTPGCalibrationData*)),this,SLOT(NewPGCalibrationData(CZTPGCalibrationData*))); + connect(mZT1WorkerThread,SIGNAL(NewZT1Flag(int,CZT1FlagsData*)),this,SLOT(ZT1NewFlag(int,CZT1FlagsData*))); + connect(mZT1WorkerThread,SIGNAL(AddLogString(QString)),this,SLOT(AddLogStringFromThread(QString))); + + //Create the ZT2 train analysis thread (even if the station has no ZT2... it doesn't hurt anyone) + mZT2SMThread = new QThread; + mZT2WorkerThread = new CZT2AnalysisThread(); + mZT2WorkerThread->moveToThread(mZT2SMThread); + connect(mZT2SMThread,SIGNAL(started()),mZT2WorkerThread,SLOT(AnalyzeZT2Train())); + connect(mZT2WorkerThread,SIGNAL(ZT2DataUpdate(CZT2ThreadData*)),this,SLOT(ZT2StateChanged(CZT2ThreadData*))); + connect(mZT2WorkerThread,SIGNAL(DetectionTriggered(CZTDetectionData*)),this,SLOT(ZT2NewDetection(CZTDetectionData*))); + connect(mZT2WorkerThread,SIGNAL(AddLogString(QString)),this,SLOT(AddLogStringFromThread(QString))); + + + mZT1LogDelayTimer.start(); + + mTimeToForceSyncFS = false; + mFSSyncTimer.start(); +} + +CZTStateMachine::~CZTStateMachine() +{ + mZT1SMThread->quit(); + mZT1SMThread->wait(1000); + delete mZT1SMThread; + delete mZT1WorkerThread; + mZT2SMThread->quit(); + mZT2SMThread->wait(1000); + delete mZT2SMThread; + delete mZT2WorkerThread; + + //delete mTKGenerator; + + DestroyZT1Log(); + DestroyZT2Log(); + DestroyCalibrationData(); +} + +unsigned int CZTStateMachine::ZTStateMachine(unsigned int Event, unsigned int SubEvent) +{ + + mCurInputs = mInputModule->GetInputs(); + + switch(mZTState) + { + case ZT_INIT_STATE: + { + //mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1Active,mZT2Active); + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + mZTStationPtr->UpdateStationMasks(mCurInputs); + mZTStationPtr->UpdateCDVs(mCurInputs); + + //Wait for ZT1 and ZT2 CDVs to be free before starting the State Machine... + if(!mZTStationPtr->IsZT1CDVOccupied() && !mZTStationPtr->IsZT2CDVOccupied()) + { + mZTState = ZT_EXECUTE_STATE; + } + else + { + mZTPagePTr->UpdateCDVDisplay(); + if(mZtSimPtr != 0) //ptr will be 0 if not in sim mode + { + mZtSimPtr->UpdateSimulatorDisplay(); + } + } + break; + } + case ZT_EXECUTE_STATE: + { + + if(mCurInputs != mLastInputs) + { + //Update masks + mZTStationPtr->UpdateStationMasks(mCurInputs); + + //Update variables according to new inputs + mZTStationPtr->UpdateCDVs(mCurInputs); + + mCIZT1Active = ((mCurInputs & mZTInputMasks->InputZT1ITIMask) != 0); + mCIZT2Active = ((mCurInputs & mZTInputMasks->InputZT2ITIMask) != 0); + bool AN1State, AN2State; + + //If the mCCModbusRepo is not 0, then it has to be used (Modbus connection is used as CC interface) + if(mCCModbusRepo == 0) + { + AN1State = (mCurInputs & mZTInputMasks->InputZT1ANMask) != 0; + AN2State = (mCurInputs &mZTInputMasks->InputZT2ANMask) != 0; + } +// else +// { +// AN1State = (mCCModbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD) & MODBUS_CC_AN1_FLAG_MASK) != 0; +// AN2State = (mCCModbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD) & MODBUS_CC_AN2_FLAG_MASK) != 0; +// } + +// mTKGenerator->SetInputStates((mCurInputs & mZTInputMasks->InputZT1ANMask) != 0, +// mZTStationPtr->IsZT1AlarmAutoAcquireCDVOccupied(), +// (mCurInputs &mZTInputMasks->InputZT2ANMask) != 0, +// mZTStationPtr->IsZT2AlarmAutoAcquireCDVOccupied()); + mTKGenerator->SetInputStates(AN1State,mZTStationPtr->IsZT1AlarmAutoAcquireCDVOccupied(), + AN2State,mZTStationPtr->IsZT2AlarmAutoAcquireCDVOccupied()); + } + + + if(mIsMaintenanceModeON == false) + { + ZT1StateMachine(Event,SubEvent); + + if(mZT2Present) //if there is no ZT2, don't execute the ZT2 SM + { + ZT2StateMachine(Event,SubEvent); + } + } + else + { + //Do the data acquisition for the PP detection while in maintenance mode. + unsigned int Inputs = mPCIIOPtr->GetInputs(); + + if((Inputs & mZTInputMasks->InputZT1PIMask) == 0) + { + if(mMaintenancePPIZT1Latch == false) + { + emit MaintenancePPActivated(MAINTENANCE_PPI_ZT1_ID); + SendTKToPCC(DETECTION_PPI_DETECTION, 27); + mMaintenancePPIZT1Latch = true; + } + } + + if((Inputs & mZTInputMasks->InputZT1PEMask) == 0) + { + if(mMaintenancePPEZT1Latch == false) + { + SendTKToPCC(DETECTION_PPE_DETECTION, 18); + emit MaintenancePPActivated(MAINTENANCE_PPE_ZT1_ID); + mMaintenancePPEZT1Latch = true; + } + } + + if(mZT2Present) //if there is no ZT2, don't check the pedals + { + if((Inputs & mZTInputMasks->InputZT2PIMask) == 0) + { + if(mMaintenancePPIZT2Latch == false) + { + SendTKToPCC(DETECTION_ZT2_PPI_DETECTION, 27); + emit MaintenancePPActivated(MAINTENANCE_PPI_ZT2_ID); + mMaintenancePPIZT2Latch = true; + } + } + + if((Inputs & mZTInputMasks->InputZT2PEMask) == 0) + { + if(mMaintenancePPEZT2Latch == false) + { + SendTKToPCC(DETECTION_ZT2_PPE_DETECTION, 18); + emit MaintenancePPActivated(MAINTENANCE_PPE_ZT2_ID); + mMaintenancePPEZT2Latch = true; + } + } + } + + } + + + mZTPagePTr->UpdateCDVDisplay(); + if(mZtSimPtr != 0) //ptr will be 0 if not in sim mode + { + mZtSimPtr->UpdateSimulatorDisplay(); + } + + if(mTimeToForceSyncFS == true) + { + mFSSyncTimer.start(); + system("sync"); + mTimeToForceSyncFS = false; + qDebug() << "Sync FS took: " << mFSSyncTimer.elapsed() << "ms"; + mFSSyncTimer.start(); + + } + + break; + } + } + + if(mCurInputs != mLastInputs) + mLastInputs = mCurInputs; + + return RET_OK; +} + +unsigned int CZTStateMachine::ZT1StateMachine(unsigned int Event, unsigned int SubEvent) +{ + Q_UNUSED(Event) + Q_UNUSED(SubEvent) + + switch(mZT1State) + { + case ZT1_WAIT_FOR_CI_STATE: + { + if(mCIZT1Active) + { + mZT1State = ZT1_WAIT_FOR_TRAIN_STATE; + } + else + { + } + break; + } + case ZT1_WAIT_FOR_TRAIN_STATE: + { + if(mCIZT1Active == false) + { + mZT1State = ZT1_WAIT_FOR_CI_STATE; + } + if(!mZTStationPtr->IsZT1ApproachPresent())//When there is no approach CDV (Montmorency), use the subsequent CDV to detect maintenance vehicles going backward + { + if(mZTStationPtr->IsZT1SubsequentCDVOccupied()) //If subsequent CDV is occupied when waiting for train = vehicle going backward + { + mZT1State = ZT1_WAIT_FOR_SUBSEQUENT_LIBERATION; + } + else if(mZTStationPtr->IsZT1CDVOccupied()) //since the approach is the ZT CDV, just consider the latter + { + DestroyZT1Log(); + mEventsRefTimer.start(); + mNbPassages++; + InsertZT1LogItem(); + mZT1Log.mZT1Flags.mPGCalibrationON = (mIsPGCalibON == true); + mZT1State = ZT1_TRAIN_ON_APPROACH_CDV_STATE; + } + + } + else if(mZTStationPtr->IsZT1ApproachCDVOccupied() && !mZTStationPtr->IsZT1CDVOccupied()) //Normal situation + { + DestroyZT1Log(); + mEventsRefTimer.start(); + mNbPassages++; + InsertZT1LogItem(); + mZT1Log.mZT1Flags.mPGCalibrationON = (mIsPGCalibON == true); + mZT1State = ZT1_TRAIN_ON_APPROACH_CDV_STATE; + } + break; + } + case ZT1_WAIT_FOR_SUBSEQUENT_LIBERATION: //Subsequent CDV should never be occupied before ZT CDV. + { + if(mCIZT1Active == false) + { + mZT1State = ZT1_WAIT_FOR_CI_STATE; + } + if(!mZTStationPtr->IsZT1CDVOccupied() && !mZTStationPtr->IsZT1SubsequentCDVOccupied()) + { + mZT1State = ZT1_WAIT_FOR_TRAIN_STATE; + } + + break; + } + case ZT1_TRAIN_ON_APPROACH_CDV_STATE: + { + if(mCIZT1Active == false) + { + mZT1State = ZT1_WAIT_FOR_CI_STATE; + } + else if(!mZTStationPtr->IsZT1ApproachCDVOccupied()) + { + mZT1State = ZT1_WAIT_FOR_TRAIN_STATE; + } + else if(mZTStationPtr->IsZT1CDVOccupied()) + { + mZT1ActiveStatus = SB_ZT_ACTIVE_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + mZTPagePTr->SetZT1ActivationState(true); + + mZTPagePTr->ResetZT1Stats(); + InsertZT1LogItem(); + + mZT1WorkerThread->UpdateDetectionConfig(mZTDetectionConfig); + mTKGenerator->UpdateDetectionConfig(mZTDetectionConfig); + mZT1SMThread->start(QThread::NormalPriority); + + mZT1PassageTimeLimitTimer.start(); + //CZTLog::instance()->AddLogString("ZT1 activée",true); + + + CZTLog::instance()->ClearBufferString(); + CZTLog::instance()->AddBufferString("ZT1 activée",true); + + if(mIsPGCalibON) + { + emit PGCalibrationStatus(mCalibrationPassagesCount+1,mPGNbTotalPassages); + } + mZT1State = ZT1_ANALYZE_TRAIN_STATE; + } + break; + } + case ZT1_ANALYZE_TRAIN_STATE: + { + if(mZTStationPtr->IsZT1AnalysisFinished()) //Normally, this is true when the train leaves CDV ZT1 (except in Snowdon)... + { + + mZT1ActiveStatus = SB_ZT_INACTIVE_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + + //The train is leaving the ZT1 CDV. Stop the analysis thread. + mZT1WorkerThread->TerminateAnalysis(); + mZT1SMThread->quit(); + + InsertZT1LogItem(); + + CZTLog::instance()->AddBufferString("ZT1 désactivée",true); + + mZT1State = ZT1_POST_DETECTION_STATE; + } + else if(mZT1PassageTimeLimitTimer.elapsed() > ZT1_MAX_PASSAGE_DELAY) //Si le train prend plus de 5 minutes à passer = ignorer le passage. + { + mZT1ActiveStatus = SB_ZT_INACTIVE_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + + //Stop the analysis thread. + mZT1WorkerThread->TerminateAnalysis(); + mZT1SMThread->quit(); + + DestroyZT1Log(); + CZTLog::instance()->AddLogString("Délai de passage expiré: ZT1 désactivée",true); + + + mZT1State = ZT1_WAIT_FOR_CI_STATE; + } + break; + } + case ZT1_POST_DETECTION_STATE: + { + if(AnalyzeZT1PostDetection() == RET_POST_DETECTION_VALID) + { + SaveZT1EventsLog(&mZT1Log); + mTKGenerator->BeginTKEmission(); + + if(mIsPGCalibON) + { + mCalibrationPassagesCount++; + if(mCalibrationPassagesCount < mPGNbTotalPassages) + { + } + else + { + ComputePGCalibration(); + QuitPGCalibrationMode(); + } + } + } + else //We detected a véhicule travaux. + { + + DestroyZT1Log(); + } + + if(mZT2Present == false && (mFSSyncTimer.elapsed() > FILESYSTEM_FORCED_SYNC_TIMEOUT)) + { + mTimeToForceSyncFS = true; + } + + mZT1State = ZT1_WAIT_FOR_CI_STATE; + break; + } + default: + { + break; + } + } + + return RET_OK; +} + +unsigned int CZTStateMachine::AnalyzeZT1PostDetection() +{ + //Get useful information from detections log... + + + bool MagSensorCountError = false; + bool PEQ1Error = false; + int NbPGDetections = 0; + int NbFNDetections = 0; + mZT1Log.mZT1Flags.mIsProblematicPassage = 0; + + for(int i = 0; i < mZT1DetectionsLog.size(); i++) + { + if(mZT1DetectionsLog.at(i)->mDetectionID == DETECTION_PG_DETECTION) + { + NbPGDetections++; + } + if(mZT1DetectionsLog.at(i)->mDetectionID == DETECTION_MAGNETIC_SENSOR_COUNT) + { + MagSensorCountError = true; + CEngLog::instance()->AddLogString("[Post-Détection]--> Flag de détection d'erreur de comptage actif",3); + } + if(mZT1DetectionsLog.at(i)->mDetectionID == DETECTION_PEQ1_DETECTION) + { + CEngLog::instance()->AddLogString("[Post-Détection]--> Flag de détection PEQ1 actif",3); + PEQ1Error = true; + } + } + + + + //2015-03-03 + //Computer crash may be related to addition of this section + ///START + + //If the thread did not detect any count error, check if the rank count is valid... + + if(MagSensorCountError == false) + { + quint32 S1Count = 0, S2Count = 0; + for(int sample = 0; sample < mZT1Log.mZT1LogData.size(); sample++) + { + if(mZT1Log.mZT1LogData.at(sample)->mZT1ThreadData != 0) + { + if(mZT1Log.mZT1LogData.at(sample)->mZT1ThreadData->mS1Count > S1Count) + { + S1Count = mZT1Log.mZT1LogData.at(sample)->mZT1ThreadData->mS1Count; + } + if(mZT1Log.mZT1LogData.at(sample)->mZT1ThreadData->mS2Count > S2Count) + { + S2Count = mZT1Log.mZT1LogData.at(sample)->mZT1ThreadData->mS2Count; + } + } + } + + //Thread should have detected S1 S2 count discrepancy but it's easy to re-check here. + if(S1Count != S2Count) + { + MagSensorCountError = true; + } + else if(S1Count != 12 && S1Count != 24 && S1Count != 36) //Make shure we counted all the ranks + { + MagSensorCountError = true; + } + else if(S2Count != 12 && S2Count != 24 && S2Count != 36) //Make shure we counted all the ranks + { + MagSensorCountError = true; + } + + } + ///END + + + bool PostAnalyseData = MagSensorCountError; //If we have a count error, do a post-analysis of the data + + if(PEQ1Error == true && mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive) //If we have a PEQ1 detection, clear all other errors and emit PEQ1 only + { + //If we have a counting error AND the PEQ1 is FN stuck (most of the time this will happen because + //of the sensor count error), then ignore the PEQ1... + if(MagSensorCountError == true && mZT1PEQType == PEQ1_FN_STUCK_LOW_TYPE) + { + PostAnalyseData = true; + } + else + { + PostAnalyseData = false; + + ClearZT1DetectionsList(); + NbPGDetections = 0; + + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive) + { + CZTLog::instance()->AddBufferString("Panne équipement ZT1: SDF à 1",true); + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_PEQ1_DETECTION; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.prepend(NewDetection); + + + } + } + } + + if(PostAnalyseData == true) //check if we need to do a post-analysis of the data. + { + int S1Count = 0, S2Count = 0, FNCount = 0, PGCount = 0, PPICount = 0, PPECount = 0; + + int S1 = 0, S2 = 0, FN = 0, PPI = 0, PPE = 0; + + bool PGActive = false; + bool PGCalibrationON = mZT1Log.mZT1Flags.mPGCalibrationON == 1; + qint32 PGIOffset = mZT1Log.mZT1Flags.mIntPGOffset; + qint32 PGEOffset = mZT1Log.mZT1Flags.mExtPGOffset; + qint32 PGValueTreshold = mZT1Log.mZT1Flags.mPGTresholdValue; + qint32 Quadra; + int PGNonDetectionSampleCount = 0; + + CEngLog::instance()->AddLogString("[Post-Détection]--> Début de l'analyse en Post-Détection",3); + + + //First, clear the detections list. + ClearZT1DetectionsList(); + + CZT1ThreadData *Data; + //Analyze the log and add detections to the list if any. + for(int sample = 0; sample < mZT1Log.mZT1LogData.size(); sample++) + { + if(mZT1Log.mZT1LogData.at(sample)->mZT1ThreadData != 0) + { + Data = mZT1Log.mZT1LogData.at(sample)->mZT1ThreadData; + + //Count magnetic sensors. + //Detect High to Low transitions + if(S1 == 1 && Data->mS1 == 0) + { + S1Count++; + } + S1 = Data->mS1; + + //Detect High to Low transitions + if(S2 == 1 && Data->mS2 == 0) + { + S2Count++; + } + S2 = Data->mS2; + + //Count FN occurences + //Detect High to Low transitions + if(FN == 1 && Data->mFN == 0) + { + FNCount++; + } + FN = Data->mFN; + + //If we were calibrating, ignore the PG data. + if(PGCalibrationON == false) + { + //Compute and verify if the PG is detected. + Quadra = ((Data->mPGIntValue - PGIOffset) * (Data->mPGExtValue - PGEOffset)); + if(Quadra > PGValueTreshold) + { + if(PGActive == false) + { + PGCount++; + PGActive = true; + } + PGNonDetectionSampleCount = 0; + } + else + { + if(PGActive == true) + { + if(PGNonDetectionSampleCount >= 3) //To avoid false detections when glitches or rebounds appear, we need to have at least 3 consecutive samples + { //without detection to consider the PG inactive + PGActive = false; + } + PGNonDetectionSampleCount++; + } + + } + } + + + //Check for PP detections if needed + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive == true) + { + if(PPI == 1 && Data->mPInt == 0) + { + PPICount++; + + //register the detection in the list. + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_PPI_DETECTION; + NewDetection->mTimeStamp = Data->mTimeStamp; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.append(NewDetection); + + } + PPI = Data->mPInt; + + if(PPE == 1 && Data->mPExt == 0) + { + PPECount++; + + //register the detection in the list. + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_PPE_DETECTION; + NewDetection->mTimeStamp = Data->mTimeStamp; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.append(NewDetection); + } + PPE = Data->mPExt; + } + } + } + + CEngLog::instance()->AddLogString(QString().sprintf("[Post-Détection]--> Résultat des données brutes: [S1Count = %d], [S2Count = %d], [PGCount = %d], [FNCount = %d], [PPICount = %d], [PPECount = %d]",S1Count,S2Count,PGCount,FNCount,PPICount,PPECount),3); + + //First, try to detect a véhicule travaux. If we have a PG count of 0, it is a véhicule travaux and we + //just totally ignore this passage + if(PGCalibrationON == false) + { + if(PGCount == 0) + { + CZTLog::instance()->AddLogString("[POST DETECTION]--> Véhicule travaux détecté. Annulation et fin de l'analyse ZT1",true); + ClearZT1DetectionsList(); + return RET_POST_DETECTION_WORK_VEHICLE; + } + } + + + //Analyze the PG count if necessary + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive == true) + { + if(PGCalibrationON == false) + { + + + if(PGCount == 12 || PGCount == 24 || PGCount == 36) + { + //Everything is fine with the PG. + NbPGDetections = 0; + } + else + { + CEngLog::instance()->AddLogString(QString().sprintf("[Post-Détection]--> Compte PG invalide : PGCount = %d",PGCount),3); + if(PGCount > 24) + { + NbPGDetections = 36 - PGCount; + } + else if(PGCount > 12) + { + NbPGDetections = 24 - PGCount; + } + else + { + NbPGDetections = 12 - PGCount; + } + } + + int alarms = NbPGDetections; + + if(alarms < 0) + { + alarms = -1 * alarms; + } + + for(int i = 0; i < alarms; i++) + { + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_PG_DETECTION; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.append(NewDetection); + } + } + } + + + + //Analyze FN count if necessary + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive == true) + { + + if(FNCount == 6 || FNCount == 12 || FNCount == 18) + { + //Everything is fine with the FN. + NbFNDetections = 0; + } + else + { + CEngLog::instance()->AddLogString(QString().sprintf("[Post-Détection]--> Compte FN invalide : FNCount = %d",FNCount),3); + if(FNCount > 12) + { + NbFNDetections = 18 - FNCount; + } + else if(FNCount > 6) + { + NbFNDetections = 12 - FNCount; + } + else + { + NbFNDetections = 6 - FNCount; + } + } + + int alarms = NbFNDetections; + + if(alarms < 0) + { + alarms = -1 * alarms; + } + + if(alarms != 0) + { + //Send two detections only (rank 1 & 18) when detecting FN errors while in V00 + QString string; + string.sprintf("[POST DETECTION]--> Déclenchement FN avec erreur de comptage (FNCount = %d). Envoi d'alarmes aux rangs 1 et 18.",FNCount); + //CZTLog::instance()->AddBufferString("Déclenchement FN avec erreur de comptage. Envoi d'alarmes aux rangs 1 et 18.",true); + CZTLog::instance()->AddBufferString(string,true); + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_FN_DETECTION; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = 1; + mZT1DetectionsLog.append(NewDetection); + + NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_FN_DETECTION; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = 18; + mZT1DetectionsLog.append(NewDetection); + } + } + + if(mZT1DetectionsLog.size() != 0) + { + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive) + { + //If here, we had at least one detection. We must emit the V00 alarm. + + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_MAGNETIC_SENSOR_COUNT; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.append(NewDetection); + } + } + else + { + //If here, we did not detect other errors than mag. sensor count. + //We can tolerate 2 miss + + if(mZTDetectionConfig->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive) + { + int SensorCount = S1Count; + if(SensorCount > S2Count) + SensorCount = S2Count; //Use the least of the 2 counts... + + bool Error = false; + if(S1Count > 36 || S2Count > 36) + { + //Counted more than 36 ranks on at least one sensor... + Error = true; + } + if(SensorCount > 24 && SensorCount < 34) + { + //more than 2 miss for a 3 elements train + Error = true; + } + else if(SensorCount > 12 && SensorCount < 22) + { + //more than 2 miss for a 2 elements train + Error = true; + } + else if(SensorCount < 10) + { + //more than 2 miss for a 1 element train + Error = true; + } + + if(Error) + { + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_MAGNETIC_SENSOR_COUNT; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.append(NewDetection); + } + else + { + QString string; + string.sprintf("[POST DETECTION]--> Erreur de comptage ZT1 : [S1=%d] [S2=%d] essieux comptés (TK non émise au PCC car <= 2 essieux sans autre détection )",S1Count, S2Count); + CZTLog::instance()->AddBufferString(string,true,true); + mZT1Log.mZT1Flags.mIsProblematicPassage = 1; + } + } + } + + } + else//No magnetic sensors count error + { + //If we have more than 3 PG detections, check if they happened on consecutive ranks + //if so, remove them from the list and emit a PEQ1 alarm instead. + if(NbPGDetections >= 3 && mZT1DetectionsLog.size() >= 3) + { + //List the detections + int DetectionIDs[1024/*NbPGDetections*/]; + int index = 0; + + for(int i = 0; i < mZT1DetectionsLog.size(); i++) + { + if(mZT1DetectionsLog.at(i)->mDetectionID == DETECTION_PG_DETECTION) + { + DetectionIDs[index++] = i; + } + } + + //Now check if the ranks are consecutive. If so, remove the events from the list. + if((mZT1DetectionsLog.at(DetectionIDs[0])->mRank+1 == mZT1DetectionsLog.at(DetectionIDs[1])->mRank) && + (mZT1DetectionsLog.at(DetectionIDs[1])->mRank+1 == mZT1DetectionsLog.at(DetectionIDs[2])->mRank)) + { + //remove all PG detections. + for(int i = NbPGDetections-1 ; i >= 0 ; i--) + { + delete mZT1DetectionsLog.at(DetectionIDs[i]); + mZT1DetectionsLog.remove(DetectionIDs[i]); + } + + CZTLog::instance()->AddBufferString("[POST DETECTION]--> Plus de 3 PG consécutifs détectés (TK non émise au PCC)",true,true); + mZT1Log.mZT1Flags.mIsProblematicPassage = 1; + + } + + } + + //Check if the rank count is valid even without mag. sensor error + unsigned int S1Count = 0, S2Count = 0; + for(int i = 0; i < mZT1Log.mZT1LogData.size(); i++) + { + if(mZT1Log.mZT1LogData.at(i)->mZT1ThreadData != 0) + { + if(mZT1Log.mZT1LogData.at(i)->mZT1ThreadData->mS1Count > S1Count) + { + S1Count = mZT1Log.mZT1LogData.at(i)->mZT1ThreadData->mS1Count; + } + if(mZT1Log.mZT1LogData.at(i)->mZT1ThreadData->mS2Count > S2Count) + { + S2Count = mZT1Log.mZT1LogData.at(i)->mZT1ThreadData->mS2Count; + } + } + } + + if((S1Count == 12 || S1Count == 24 || S1Count == 36) && + (S2Count == 12 || S2Count == 24 || S2Count == 36)) + { + //Everything is fine, no sensor count error... + } + else + { + if(mZT1DetectionsLog.size() != 0) + { + //If here, we had at least one detection. We must emit the V00 alarm. + CEngLog::instance()->AddLogString(QString().sprintf("[Post-Détection]--> Erreur de comptage sans flag en temps réel"),3); + + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_MAGNETIC_SENSOR_COUNT; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.prepend(NewDetection); //Put the V00 alarm first (prepend) + + //Clear the detections rank of all the detections since it may not be valid. + for(int i = 0; i < mZT1DetectionsLog.size(); i++) + { + mZT1DetectionsLog.at(i)->mRank = ZT_DEFAULT_DETECTION_RANK; + } + + //JFM 20160112 V1.10 + //If there was FN detection, replace it with two alarms at rank 1 and 18. + bool FNDetection = false; + int i = 0; + while(i < mZT1DetectionsLog.size()) + { + if(mZT1DetectionsLog.at(i)->mDetectionID == DETECTION_FN_DETECTION) + { + CEngLog::instance()->AddLogString(QString().sprintf("[Post-Détection]--> Déclenchement FN détecté dans liste des alarmes"),3); + FNDetection = true; + delete mZT1DetectionsLog.at(i); + mZT1DetectionsLog.remove(i); //remove this alarm + } + else + { + i++; + } + }; + if(FNDetection == true) + { + CZTLog::instance()->AddBufferString("[Post-Détection]--> Déclenchement FN avec erreur de comptage. Envoi d'alarmes aux rangs 1 et 18.",true); + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_FN_DETECTION; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = 1; + mZT1DetectionsLog.append(NewDetection); + + NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_FN_DETECTION; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = 18; + mZT1DetectionsLog.append(NewDetection); + } + } + else + { + //If here, we did not detect other errors than mag. sensor count. + //We can tolerate 2 miss + + unsigned int SensorCount = S1Count; + if(SensorCount > S2Count) + SensorCount = S2Count; //Use the least of the 2 counts... + + bool Error = false; + if(S1Count > 36 || S2Count > 36) + { + //Counted more than 36 ranks... + Error = true; + } + else if(SensorCount > 24 && SensorCount < 34) + { + //more than 2 miss for a 3 elements train + Error = true; + } + else if(SensorCount > 12 && SensorCount < 22) + { + //more than 2 miss for a 2 elements train + Error = true; + } + else if(SensorCount < 10) + { + //more than 2 miss for a 1 element train + Error = true; + } + + if(Error) + { + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_MAGNETIC_SENSOR_COUNT; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT1DetectionsLog.append(NewDetection); + + } + else + { + QString string; + string.sprintf("[POST DETECTION]--> Erreur de comptage ZT1 : [S1=%d] et [S2=%d] essieux comptés (TK non émise au PCC car <= 2 essieux sans autre détection )",S1Count, S2Count); + CZTLog::instance()->AddBufferString(string,true,true); + mZT1Log.mZT1Flags.mIsProblematicPassage =1; + + } + } + } + } + + + //Process detections and send TKs to PCC/PCM + for(int i = 0; i < mZT1DetectionsLog.size(); i++) + { + mTKGenerator->ProcessDetectionsTK(mZT1DetectionsLog.at(i)); + + mNbTriggers++; + + QString str(""); + if(mZT1DetectionsLog.at(i)->mDetectionID == DETECTION_FN_DETECTION) + str.sprintf("[POST DETECTION]--> %s au bogie %d (rang %d ou %d)",CZTData::GetErrorString(mZT1DetectionsLog.at(i)->mDetectionID),mZT1DetectionsLog.at(i)->mRank,(mZT1DetectionsLog.at(i)->mRank*2)-1,mZT1DetectionsLog.at(i)->mRank*2); + else + str.sprintf("[POST DETECTION]--> %s au rang %d",CZTData::GetErrorString(mZT1DetectionsLog.at(i)->mDetectionID),mZT1DetectionsLog.at(i)->mRank); + CZTLog::instance()->AddBufferString(str,true); + } + + if(mZT1DetectionsLog.size() != 0 || CZTLog::instance()->IsWriteForced()) + { + CZTLog::instance()->WriteBufferToLog(); + } + else + { + CZTLog::instance()->ClearBufferString(); //2015-03-03 To avoid potention memory leak. Computer Crash problem resolution tentative... + } + + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + + return RET_POST_DETECTION_VALID; +} + +unsigned int CZTStateMachine::ZT2StateMachine(unsigned int Event, unsigned int SubEvent) +{ + Q_UNUSED(Event) + Q_UNUSED(SubEvent) + + if(IsZT1Active() == false) + { + switch(mZT2State) + { + case ZT2_WAIT_FOR_CI_STATE: + { + if(mCIZT2Active) + { + if(mZTStationPtr->IsZT2CDVOccupied() == false) //the ZT2 CDV must be free. + { + mZT2State = ZT2_WAIT_FOR_TRAIN_STATE; + } + else + { + mZT2State = ZT2_WAIT_FOR_APPROACH_LIBERATION_STATE; + } + + } + break; + } + case ZT2_WAIT_FOR_APPROACH_LIBERATION_STATE: + { + if(mZTStationPtr->IsZT2ApproachCDVOccupied() == false) + { + mZT2State = ZT2_WAIT_FOR_CI_STATE; + } + break; + } + case ZT2_WAIT_FOR_TRAIN_STATE: + { + if(mCIZT2Active == false) + { + mZT2State = ZT2_WAIT_FOR_CI_STATE; + } + else if(mZTStationPtr->IsZT2ApproachCDVOccupied()) + { + DestroyZT2Log(); + mEventsRefTimer.start(); + mZTPagePTr->SetZT2ActivationSTate(true); + mZT2ActiveStatus = SB_ZT_ACTIVE_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + mZTPagePTr->ResetZT2Stats(); + InsertZT2LogItem(); + mZT2WorkerThread->UpdateDetectionConfig(mZTDetectionConfig); + mTKGenerator->UpdateDetectionConfig(mZTDetectionConfig); + mZT2SMThread->start(QThread::NormalPriority); + + mZT2PassageTimeLimitTimer.start(); + mZT2State = ZT2_ANALYZE_TRAIN_STATE; + + CZTLog::instance()->ClearBufferString(); + CZTLog::instance()->AddBufferString("ZT2 activée",true); + } + break; + } + case ZT2_ANALYZE_TRAIN_STATE: + { + if(!mZTStationPtr->IsZT2CDVOccupied() && !mZTStationPtr->IsZT2ApproachCDVOccupied()) //train quit the ZT2 cdv. + { + mZT2ActiveStatus = SB_ZT_INACTIVE_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + + //The train is leaving the ZT2 CDV. Stop the analysis thread. + mZT2WorkerThread->TerminateAnalysis(); + mZT2SMThread->quit(); + + InsertZT2LogItem(); + + CZTLog::instance()->AddBufferString("ZT2 désactivée",true); + + mZT2State = ZT2_POST_DETECTION_STATE; + } + if(mZT2PassageTimeLimitTimer.elapsed() > ZT2_MAX_PASSAGE_DELAY ) + { + mZT2ActiveStatus = SB_ZT_INACTIVE_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + + //Stop the analysis thread. + mZT2WorkerThread->TerminateAnalysis(); + mZT2SMThread->quit(); + + DestroyZT2Log(); + CZTLog::instance()->AddLogString("Délai de passage expiré: Analyse ZT2 annulée. Attente de libération du CDV",true); + + mZT2State = ZT2_WAIT_FOR_CDV_LIBERATION_STATE; + } + break; + } + case ZT2_WAIT_FOR_CDV_LIBERATION_STATE: + { + if(!mZTStationPtr->IsZT2CDVOccupied() && !mZTStationPtr->IsZT2ApproachCDVOccupied()) + { + CZTLog::instance()->AddLogString("CDV ZT2 Libéré. ZT2 prête",true); + mZT2State = ZT2_WAIT_FOR_CI_STATE; + } + break; + } + case ZT2_POST_DETECTION_STATE: + { + //InsertZT2LogItem(); //JFM 2014-06-11 Not sure if necessary... + AnalyzeZT2PostDetection(); + SaveZT2EventsLog(&mZT2Log); + mTKGenerator->BeginTKEmission(); + + mZT2State = ZT2_WAIT_FOR_CI_STATE; + + + if(mFSSyncTimer.elapsed() > FILESYSTEM_FORCED_SYNC_TIMEOUT) + { + mTimeToForceSyncFS = true; + } + break; + } + default: + { + break; + } + + } + } + return RET_OK; +} + + +unsigned int CZTStateMachine::AnalyzeZT2PostDetection() +{ + bool PEQ2 = false; + qint64 PEQ2Timestamp = 0; + mZT2Log.mZT2Flags.mIsProblematicPassage = 0; + + for(int i = 0; i < mZT2DetectionsLog.size(); i++) + { + if(mZT2DetectionsLog.at(i)->mDetectionID == DETECTION_PEQ2_DETECTION) + { + PEQ2 = true; + PEQ2Timestamp = mZT2DetectionsLog.at(i)->mTimeStamp; + } + } + + //If we have a PEQ2, we remove all detections an leave only the PEQ2 one + if(PEQ2 == true) + { + for(int i = 0; i < mZT2DetectionsLog.size(); i++) + { + delete mZT2DetectionsLog.at(i); + } + mZT2DetectionsLog.clear(); + + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_PEQ2_DETECTION; + NewDetection->mTimeStamp = PEQ2Timestamp; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT2DetectionsLog.prepend(NewDetection); + } + else + { + + //Check for magnetic sensor count error. + int S1Count = 0; + for(int i = 0; i < mZT2Log.mZT2LogData.size(); i++) + { + if(mZT2Log.mZT2LogData.at(i)->mZT2ThreadData != 0) + { + if((int)mZT2Log.mZT2LogData.at(i)->mZT2ThreadData->mS1Count > S1Count) + { + S1Count = mZT2Log.mZT2LogData.at(i)->mZT2ThreadData->mS1Count; + } + } + } + + if(S1Count == 12 || S1Count == 24 || S1Count == 36) + { + //Everything is fine ! + + } + else + { + //We had a sensor count error. Emit V02 only if we also have a PP detection. + if(mZT2DetectionsLog.size() == 0) + { + //No PP detection. + QString string(""); + string.sprintf("[POST DETECTION]--> Erreur de comptage ZT2 : %d essieux comptés (TK non émise au PCC car pas de déclenchement PP)",S1Count); + CZTLog::instance()->AddBufferString(string,true,true); + mZT2Log.mZT2Flags.mIsProblematicPassage = 1; + } + else + { + //There has been a PP detection. Add V02 alarm to the list (at the beginning) + + CZTDetectionData *NewDetection = new CZTDetectionData(); + NewDetection->mDetectionID = DETECTION_ZT2_MAGNETIC_SENSOR_COUNT; + NewDetection->mTimeStamp = 0; + NewDetection->mRank = ZT_DEFAULT_DETECTION_RANK; + mZT2DetectionsLog.append(NewDetection); + + //Clear the rank value for the other detections since it may not be valid + for(int i = 0; i < mZT2DetectionsLog.size(); i++) + { + mZT2DetectionsLog.at(i)->mRank = ZT_DEFAULT_DETECTION_RANK; + } + + } + } + } + + + //Process detections and send TKs to PCC/PCM + for(int i = 0; i < mZT2DetectionsLog.size(); i++) + { + mTKGenerator->ProcessDetectionsTK(mZT2DetectionsLog.at(i)); + + mNbTriggers++; + QString str(""); + str.sprintf("[POST DETECTION]--> %s au rang %d",CZTData::GetErrorString(mZT2DetectionsLog.at(i)->mDetectionID),mZT2DetectionsLog.at(i)->mRank); +// CZTLog::instance()->AddLogString(str,true); + CZTLog::instance()->AddBufferString(str,true); + } + + if(mZT2DetectionsLog.size() != 0 || CZTLog::instance()->IsWriteForced()) + { + CZTLog::instance()->WriteBufferToLog(); + } + else + { + CZTLog::instance()->ClearBufferString(); //2015-03-03 To avoid potention memory leak. Computer Crash problem resolution tentative... + } + + //mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1Active,mZT2Active); + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + + return RET_OK; +} + +bool CZTStateMachine::IsZT1Active() +{ + if(mZT1State == ZT1_TRAIN_ON_APPROACH_CDV_STATE || mZT1State == ZT1_ANALYZE_TRAIN_STATE) + { + return true; + } + + return false; +} + +bool CZTStateMachine::IsZT2Active() +{ + if(mZT2State == ZT2_WAIT_FOR_CI_STATE || mZT2State == ZT2_WAIT_FOR_TRAIN_STATE) + { + return false; + } + + return true; +} + + +void CZTStateMachine::BindPointers(CStation *ptr,CInputModule *InputModule,COutputModule *OutputModule,CZTPage *ZTPagePTr,CPCIIOMgr *PCIIOPtr,CAbstractLazerProbe *PGIntProbePtr, CAbstractLazerProbe *PGExtProbePTr,CLogMgr *LogMgr,CTKTransportInterface *TKTransport,CZTSimulator *ZTSimPtr,CAnalogInputModule *DataQInterface) +{ + mZTStationPtr = ptr; + mSDFAnalogMonitorInterface = DataQInterface; + mInputModule = InputModule; + mZTPagePTr = ZTPagePTr; + mZtSimPtr = ZTSimPtr; + mZTInputMasks = mZTStationPtr->GetInputMasks(); + mPCIIOPtr = PCIIOPtr; + mPGExtProbePtr = PGExtProbePTr; + mPGIntProbePtr = PGIntProbePtr; + mLogMgr = LogMgr; + + mZT1WorkerThread->Init(PCIIOPtr,mZTInputMasks,mPGExtProbePtr,mPGIntProbePtr,&mEventsRefTimer,mSDFAnalogMonitorInterface); + mZT2WorkerThread->Init(PCIIOPtr,mZTInputMasks,&mEventsRefTimer); + + + //mTKGenerator->BindPointers(mZTStationPtr->GetOutputMasks(),OutputModule); + //mTKGenerator->BindTransportInterface(TKTransport); + mTKGenerator = TKTransport; +} + +void CZTStateMachine::BindCCRepoPtr(CModbusRepository *RepoPtr) +{ + mCCModbusRepo = RepoPtr; +} + +unsigned int CZTStateMachine::SetPGTreshold(qint32 PGTreshold) +{ + mZT1WorkerThread->SetPGTreshold(PGTreshold); + return RET_OK; +} + +void CZTStateMachine::ResetNbTriggers() +{ + mNbTriggers = 0; + + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); +} + +void CZTStateMachine::ResetNbPassages() +{ + mNbPassages = 0; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); +} + +void CZTStateMachine::ZT1StateChanged(CZT1ThreadData *ZT1DataPtr,bool ProbesOnly,int SDF) +{ + //We want to limit the sampling rate in the log file + //BUT we want to log EVERY signal transition, except lazer probes (which sample at 1Khz). + + //JFM 2016-05-31 + //Add this to avoid having queued signals processed after the S.M. finished, + //causing data corruption in the train file. + if(IsZT1Active() == false) + return; + + if(ProbesOnly == true ) + { + //JFM 20140821 + if(mLogDelay != 0) + { + if(mZT1LogDelayTimer.elapsed() < mLogDelay) + { + delete ZT1DataPtr; + return; + } + } + + mZTPagePTr->SetZT1Data(ZT1DataPtr); //update display with the new data. + } + else + { + mZTPagePTr->SetZT1Data(ZT1DataPtr,true); //force update display with the new data. + } + + + InsertZT1LogItem(ZT1DataPtr,SDF); + + mZT1LogDelayTimer.start(); + //qDebug("TimeStamp: %f",(float)ZT1DataPtr->mTimeStamp/1000000000); +} + +void CZTStateMachine::ZT2StateChanged(CZT2ThreadData *ZT2DataPtr) +{ + mZTPagePTr->SetZT2Data(ZT2DataPtr); + InsertZT2LogItem(ZT2DataPtr); +} + +void CZTStateMachine::SetZT2Presence(bool Presence) +{ + mZT2Present = Presence; +} + +void CZTStateMachine::ZT1NewDetection(CZTDetectionData *NewDetection) +{ + + mZT1DetectionsLog.append(NewDetection); + + QString str(""); + if(NewDetection->mDetectionID == DETECTION_FN_DETECTION) + str.sprintf("%s au bogie %d (rang %d ou %d)",CZTData::GetErrorString(NewDetection->mDetectionID),NewDetection->mRank,(NewDetection->mRank*2)-1,NewDetection->mRank*2); + else + str.sprintf("%s au rang %d",CZTData::GetErrorString(NewDetection->mDetectionID),NewDetection->mRank); +// CZTLog::instance()->AddLogString(str,true); + CZTLog::instance()->AddBufferString(str,true); + +} + +void CZTStateMachine::ZT2NewDetection(CZTDetectionData *NewDetection) +{ + // mNbTriggers++; + mZT2DetectionsLog.append(NewDetection); +/* mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1Active,mZT2Active); + mTKGenerator->ProcessDetectionsTK(NewDetection); + QString str("");*/ + QString str(""); + str.sprintf("%s au rang %d",CZTData::GetErrorString(NewDetection->mDetectionID),NewDetection->mRank); +// CZTLog::instance()->AddLogString(str,true); + CZTLog::instance()->AddBufferString(str,true); +} + + +unsigned int CZTStateMachine::DestroyZT1Log() +{ + + for(int i = 0; i < mZT1Log.mZT1LogData.size(); i++) + { + delete mZT1Log.mZT1LogData.at(i); + } + //qDeleteAll(mZT1Log.mZT1LogData); + mZT1Log.mZT1LogData.clear(); +// mZT1Log.mZT1LogData.squeeze(); + + ClearZT1DetectionsList(); +// for(int i = 0; i < mZT1DetectionsLog.size(); i++) +// { +// delete mZT1DetectionsLog.at(i); +// } +// mZT1DetectionsLog.clear(); + + + mZT1Log.mZT1Flags.mExtPGOffset = 0; + mZT1Log.mZT1Flags.mIntPGOffset = 0; + mZT1Log.mZT1Flags.mPGCalibrationON = false; + mZT1Log.mZT1Flags.mPGTresholdValue = 0; + mZT1Log.mZT1Flags.mAnalogTracePresent = (mSDFAnalogMonitorInterface != 0); + mZT1Log.mZT1Flags.mIsProblematicPassage = 0; + + mZT1PEQType = PEQ1_UNKNOWN_TYPE; + + return RET_OK; +} + +unsigned int CZTStateMachine::InsertZT1LogItem(CZT1ThreadData *ThreadData,int SDFReading) +{ + CZT1LogData *NewItem = new CZT1LogData(ThreadData); + + if(ThreadData == 0) //Avoid accessing mEventsRefTimer while thread is running ! + NewItem->mTimestamp = mEventsRefTimer.nsecsElapsed(); + else + NewItem->mTimestamp = ThreadData->mTimeStamp; + + NewItem->mDateTime = QDateTime::currentDateTime(); + NewItem->mCDVApproach_ZT1 = mZTStationPtr->IsZT1ApproachCDVOccupied(); + NewItem->mCDVARM_ZT1 = mZTStationPtr->IsZT1CDVOccupied(); + NewItem->mCIZT1 = (unsigned int)mCIZT1Active; + + NewItem->mAnalogData = SDFReading; + mZT1Log.mZT1LogData.append(NewItem); + + return RET_OK; +} + +unsigned int CZTStateMachine::InsertZT2LogItem(CZT2ThreadData *ThreadData) +{ + CZT2LogData *NewItem = new CZT2LogData(ThreadData); + + if(ThreadData == 0) //Avoid accessing mEventsRefTimer while thread is running ! + NewItem->mTimestamp = mEventsRefTimer.nsecsElapsed(); + else + NewItem->mTimestamp = ThreadData->mTimeStamp; + + NewItem->mDateTime = QDateTime::currentDateTime(); + NewItem->mCDVARM_ZT2 = mZTStationPtr->IsZT2CDVOccupied(); + NewItem->mCDVApproach_ZT2 = mZTStationPtr->IsZT2ApproachCDVOccupied(); + NewItem->mCIZT2 = (unsigned int)mCIZT2Active; + mZT2Log.mZT2LogData.append(NewItem); + return RET_OK; +} +unsigned int CZTStateMachine::DestroyZT2Log() +{ + mZT2Log.mZT2Flags.mIsProblematicPassage = 0; + for(int i = 0; i < mZT2Log.mZT2LogData.size(); i++) + { + delete mZT2Log.mZT2LogData.at(i); + } + mZT2Log.mZT2LogData.clear(); + + for(int i = 0; i < mZT2DetectionsLog.size(); i++) + { + delete mZT2DetectionsLog.at(i); + } + mZT2DetectionsLog.clear(); + return RET_OK; +} + +unsigned int CZTStateMachine::DestroyCalibrationData() +{ + for(unsigned int j = 0; j < ZT_SM_MAX_NB_PG_CALIB_PASSAGES; j++) + { + for(int i = 0; i < mZTPGCalibrationData[j].size(); i++) + { + delete mZTPGCalibrationData[j].at(i); + } + + mZTPGCalibrationData[j].clear(); + } + return RET_OK; +} + +unsigned int CZTStateMachine::SaveZT1EventsLog(CZT1Log *Log) +{ + + QString FileName1 = "./Trains/LOGZT1_"; + FileName1 += QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); + QString FileName = FileName1 + ".bin"; + qDebug("%s",FileName.toAscii().data()); + + CTrainLogFileMgr::instance()->SaveTrainLog(FileName,Log,&mZT1DetectionsLog,mZTStationPtr->GetStationTextualName()); + mLogMgr->ParseNewLog(FileName); + + + if(mAutoExportZT1CSV) + { + FileName = FileName1 + ".csv"; + CTrainLogFileMgr::instance()->SaveCSVFile(FileName,Log,&mZT1DetectionsLog,mZTStationPtr->GetStationTextualName()); + } + + DestroyZT1Log(); + + emit NewTrainLogSaved(); + + + return RET_OK; +} + +unsigned int CZTStateMachine::SaveZT2EventsLog(CZT2Log *Log) +{ + QString FileName1 = "./Trains/LOGZT2_"; + FileName1 += QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz"); + QString FileName = FileName1 + ".bin"; + qDebug("%s",FileName.toAscii().data()); + + CTrainLogFileMgr::instance()->SaveTrainLog(FileName,Log,&mZT2DetectionsLog,mZTStationPtr->GetStationTextualName()); + mLogMgr->ParseNewLog(FileName); + + if(mAutoExportZT2CSV) + { + FileName = FileName1 + ".csv"; + CTrainLogFileMgr::instance()->SaveCSVFile(FileName,Log,&mZT2DetectionsLog,mZTStationPtr->GetStationTextualName()); + } + + DestroyZT2Log(); + + emit NewTrainLogSaved(); + + + return RET_OK; +} + +bool CZTStateMachine::EnterPGCalibrationMode(int NbPassages) +{ + if(IsZT1Active()) + return false; + + if(mZT1WorkerThread->SetPGCalibration(true) == false) + return false; + + mIsPGCalibON = true; + mCalibrationPassagesCount = 0; + mPGNbTotalPassages = NbPassages; + DestroyCalibrationData(); + return true; +} + +bool CZTStateMachine::QuitPGCalibrationMode() +{ + if(IsZT1Active()) + return false; + + if(mZT1WorkerThread->SetPGCalibration(false) == false) + return false; + + mIsPGCalibON = false; + mZT1WorkerThread->SetPGCalibration(false); + DestroyCalibrationData(); + + return true; +} + +void CZTStateMachine::NewPGCalibrationData(CZTPGCalibrationData *NewData) +{ +// qDebug("NewData %d | %d",NewData->mPGExtValue,NewData->mPGIntValue); + mZTPGCalibrationData[mCalibrationPassagesCount].append(NewData); +} + +unsigned int CZTStateMachine::ComputePGCalibration() +{ + //Pour déterminer le seuil de détection du pneu de guidage nous + //appliquons la recette suivante. + //Pour chaque pneu, on multiplie les valeurs intérieur et extérieur + //Ensuite on fait moyenne de ce résultat pour tous les frotteurs d'un même train + //On multiplie cette valeur par un facteur déterminé empiriquement (0.35) + //On fait ensuite la moyenne de ce résultat pour tous les trains + //La valeur que lon recherche correspond alors à la racine carrée de cette valeur + + double Treshold = 0.0; + + for(unsigned int i = 0; i < mPGNbTotalPassages; i++) + { + double Temp = 0; + for(int sample = 0; sample < mZTPGCalibrationData[i].size(); sample++) + { + Temp += (mZTPGCalibrationData[i].at(sample)->mPGExtValue * mZTPGCalibrationData[i].at(sample)->mPGIntValue); //Multiply int and ext samples + } + Temp /= mZTPGCalibrationData[i].size(); //Compute the mean value for this train. + Temp *= 0.35; //multiply by the scaling factor. + + Treshold += Temp; + } + + Treshold /= mPGNbTotalPassages; //Compute the mean value for all the trains. + Treshold = sqrt(Treshold); //Compute the square root, and we have the treshold value. + int PGTreshold = (int)Treshold; + qDebug("Calibration result: %d",PGTreshold); + + DestroyCalibrationData(); + + emit PGCalibrationFinished(PGTreshold); + + return RET_OK; +} + + +void CZTStateMachine::SetLogResolution(bool HighResON) +{ + if(HighResON == true) + { + mLogDelay = 0; //Log each data sample. + } + else + { + mLogDelay = ZT_SM_DEFAULT_LOG_DELAY; + } +} + +void CZTStateMachine::ZT1NewFlag(int FlagID, CZT1FlagsData *FlagData) +{ + switch(FlagID) + { + case ZT1_INT_PG_OFFSET_FLAG_ID: + { + mZT1Log.mZT1Flags.mIntPGOffset = FlagData->mIntPGOffset; + break; + } + case ZT1_EXT_PG_OFFSET_FLAG_ID: + { + mZT1Log.mZT1Flags.mExtPGOffset = FlagData->mExtPGOffset; + break; + } + case ZT1_PG_TRESHOLD_VALUE_FLAG_ID: + { + mZT1Log.mZT1Flags.mPGTresholdValue = FlagData->mPGTresholdValue; + break; + } + case ZT1_PG_CALIB_ON_FLAG_ID: + { + mZT1Log.mZT1Flags.mPGCalibrationON = FlagData->mPGCalibrationON; + break; + } + case ZT1_PEQ_TYPE_FLAG_ID: + { + mZT1PEQType = FlagData->mPEQ1Type; + break; + } + } + + delete FlagData; //We MUST delete this pointer, because the thread will not. +} + + +unsigned int CZTStateMachine::SendTKToPCC(int DetectionID, int Rank) +{ + CZTDetectionData *Detection = new CZTDetectionData(); + Detection->mDetectionID = DetectionID; + Detection->mRank = Rank; + + mTKGenerator->UpdateDetectionConfig(mZTDetectionConfig); + + mTKGenerator->ProcessDetectionsTK(Detection); + delete Detection; + + mTKGenerator->BeginTKEmission(); + + return RET_OK; +} + +unsigned int CZTStateMachine::EnterMaintenanceMode() +{ + if(IsZT1Active() || IsZT2Active()) + { + return RET_ERROR; + } + + if(mIsPGCalibON == true) + { + return RET_ERROR; + } + + if(mTKGenerator->EnterMaintenance() == RET_ERROR) + { + return RET_ERROR; + } + + mIsMaintenanceModeON = true; + mZT1ActiveStatus = SB_ZT_DISABLED_STATUS; + mZT2ActiveStatus = SB_ZT_DISABLED_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + mMaintenancePPIZT1Latch = false; + mMaintenancePPEZT1Latch = false; + mMaintenancePPIZT2Latch = false; + mMaintenancePPEZT2Latch = false; + + return RET_OK; +} + +unsigned int CZTStateMachine::QuitMaintenanceMode() +{ + mIsMaintenanceModeON = false; + mTKGenerator->ExitMaintenance(); + + mZT1ActiveStatus = SB_ZT_INACTIVE_STATUS; + mZT2ActiveStatus = SB_ZT_INACTIVE_STATUS; + mZTPagePTr->SetZTStatus(mNbPassages,mNbTriggers,mZT1ActiveStatus,mZT2ActiveStatus); + + return RET_OK; +} + +unsigned int CZTStateMachine::ClearMaintenanceCurrentTK() +{ + return mTKGenerator->CancelMaintenanceCurrentTK(); +} + + +void CZTStateMachine::ClearZT1DetectionsList() +{ + for(int i = 0; i < mZT1DetectionsLog.size(); i++) + { + delete mZT1DetectionsLog.at(i); + } + mZT1DetectionsLog.clear(); +} + +void CZTStateMachine::AddLogStringFromThread(QString logstring) +{ + CZTLog::instance()->AddLogString(logstring,true); +} + +void CZTStateMachine::ModbusCCANUpdate() +{ +// bool AN1State = false, AN2State = false; +// AN1State = (mCCModbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD) & MODBUS_CC_AN1_FLAG_MASK) != 0; +// AN2State = (mCCModbusRepo->GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD) & MODBUS_CC_AN2_FLAG_MASK) != 0; +// mTKGenerator->SetInputStates(AN1State,mZTStationPtr->IsZT1AlarmAutoAcquireCDVOccupied(), +// AN2State,mZTStationPtr->IsZT2AlarmAutoAcquireCDVOccupied()); + + // qDebug("Modbus changes: AN1 = %d, AN2 = %d",AN1State,AN2State); +} + + + + + + + + + + + + + + + + + diff --git a/sources/ZTStateMachine.h b/sources/ZTStateMachine.h new file mode 100644 index 0000000..e2d9150 --- /dev/null +++ b/sources/ZTStateMachine.h @@ -0,0 +1,245 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZTSTATEMACHINE_H +#define ZTSTATEMACHINE_H + +#include "GlobalDefine.h" +#include +#include "ZTData.h" +#include "Station.h" +#include "ZTPage.h" +#include "PCIIOMgr.h" +#include "ZT1AnalysisThread.h" +#include "ZT2AnalysisThread.h" +#include +#include +#include +#include "TKGenerator.h" +#include "LogMgr.h" +#include "InputModule.h" +#include "MixedModule.h" +#include "ModbusRepository.h" +#include "TKTransportInterface.h" + + +#define ZT_SM_DEFAULT_LOG_DELAY 10 //millilseconds +#define ZT1_MAX_PASSAGE_DELAY (qint64)300000 //milliseconds = 5 minutes +#define ZT2_MAX_PASSAGE_DELAY (qint64)300000 //milliseconds = 5 minutes + +class CZTSimulator; + +//États de la machine à état générale +enum eZTSMStates +{ + ZT_INIT_STATE, + ZT_EXECUTE_STATE +}; +enum eZTSMEvents +{ + ZT_TICK_EVENT +}; + +//états de la machine à états de la ZT1 +enum eZT1SMStates +{ + ZT1_WAIT_FOR_CI_STATE, + ZT1_WAIT_FOR_TRAIN_STATE, + ZT1_TRAIN_ON_APPROACH_CDV_STATE, + ZT1_WAIT_FOR_SUBSEQUENT_LIBERATION, + ZT1_ANALYZE_TRAIN_STATE, +// ZT1_WAIT_FOR_ZT1_LIBERATION_STATE, + ZT1_POST_DETECTION_STATE +}; + +//états de la machine à états ZT2 +enum eZT2SMStates +{ + ZT2_WAIT_FOR_CI_STATE, + ZT2_WAIT_FOR_APPROACH_LIBERATION_STATE, + ZT2_WAIT_FOR_TRAIN_STATE, + ZT2_ANALYZE_TRAIN_STATE, + ZT2_WAIT_FOR_CDV_LIBERATION_STATE, + ZT2_POST_DETECTION_STATE +}; + +enum ePostDetectionRet +{ + RET_POST_DETECTION_VALID, + RET_POST_DETECTION_WORK_VEHICLE, + + RET_POST_DETECTION_MAX_RET +}; + + + +class CZTStateMachine : public QObject +{ + Q_OBJECT +public: + explicit CZTStateMachine(QObject *parent = 0); + ~CZTStateMachine(); + unsigned int ZTStateMachine(unsigned int Event, unsigned int SubEvent = 0); //Exécution de la SM principale + void BindPointers(CStation *ptr,CInputModule *InputModule,COutputModule *OutputModule,CZTPage *ZTPagePTr,CPCIIOMgr *PCIIOPtr,CAbstractLazerProbe *PGIntProbePtr, CAbstractLazerProbe *PGExtProbePTr,CLogMgr *LogMgr,CTKTransportInterface *TKTransport,CZTSimulator *ZTSimPtr = 0,CAnalogInputModule *DataQInterface = 0); //Assignation de pointeurs + void BindCCRepoPtr(CModbusRepository *RepoPtr); + + CZTDetectionFunctionConfig *mZTDetectionConfig; + CTKGenerator *mTKGenerator; //pointeur vers la classe qui gère les alarmes au PCC + //CInterfaceCC *mTKGenerator; //pointeur vers la classe qui gère les alarmes au PCC + void SetZT2Presence(bool Presence); + + void SetAutoExportZT1CSV(bool Export){mAutoExportZT1CSV = Export;} + void SetAutoExportZT2CSV(bool Export){mAutoExportZT2CSV = Export;} + + bool IsZT1Active(); + bool IsZT2Active(); + bool EnterPGCalibrationMode(int NbPassages); + bool QuitPGCalibrationMode(); + unsigned int EnterMaintenanceMode(); + unsigned int QuitMaintenanceMode(); + unsigned int ClearMaintenanceCurrentTK(); + void SetLogResolution(bool HighResON); + unsigned int SetPGTreshold(qint32 PGTreshold); + void ResetNbTriggers(); + void ResetNbPassages(); + + + unsigned int SendTKToPCC(int DetectionID, int Rank); + + unsigned int GetNbPassages(){return mNbPassages;} + unsigned int GetNbTriggers(){return mNbTriggers;} + unsigned int GetZT1ActiveStatus(){return mZT1ActiveStatus;} + unsigned int GetZT2ActiveStatus(){return mZT2ActiveStatus;} + bool IsInMaintenance(){return mIsMaintenanceModeON;} + bool IsInPGCalibration(){return mIsPGCalibON;} + +private: + unsigned int ZT1StateMachine(unsigned int Event, unsigned int SubEvent = 0); + unsigned int ZT2StateMachine(unsigned int Event, unsigned int SubEvent = 0); + + unsigned int InsertZT1LogItem(CZT1ThreadData *ThreadData = 0,int SDFReading = 0); + unsigned int DestroyZT1Log(); + unsigned int InsertZT2LogItem(CZT2ThreadData *ThreadData = 0); + unsigned int DestroyZT2Log(); + unsigned int SaveZT1EventsLog(CZT1Log *Log); + unsigned int SaveZT2EventsLog(CZT2Log *Log); + unsigned int DestroyCalibrationData(); + unsigned int ComputePGCalibration(); + unsigned int AnalyzeZT1PostDetection(); + unsigned int AnalyzeZT2PostDetection(); + + void ClearZT1DetectionsList(); + + + + unsigned int mZT1State; + unsigned int mZT2State; + unsigned int mZTState; + unsigned int mPGCalibState; + + + bool mCIZT1Active; + bool mCIZT2Active; + bool mIsPGCalibON; + bool mIsMaintenanceModeON; + bool mMaintenancePPIZT1Latch, mMaintenancePPEZT1Latch, mMaintenancePPIZT2Latch, mMaintenancePPEZT2Latch; + int mAnalogReading; + + + CStation *mZTStationPtr; + CAnalogInputModule *mSDFAnalogMonitorInterface; + CInputModule *mInputModule; + CModbusRepository *mCCModbusRepo; + + + CPCIIOMgr *mPCIIOPtr; + CAbstractLazerProbe *mPGIntProbePtr; + CAbstractLazerProbe *mPGExtProbePtr; + +// QList *mCDVListPtr; //Pointeur vers la liste des CDV + CZTPage *mZTPagePTr; + CZTSimulator *mZtSimPtr; + GenericInputMasks_t *mZTInputMasks; + + CZT1AnalysisThread *mZT1WorkerThread; //Thread haute fréquence qui analyse le passage en ZT1 + QThread *mZT1SMThread; + + CZT2AnalysisThread *mZT2WorkerThread; //Thread haute fréquence qui analyse le passage en ZT2 + QThread *mZT2SMThread; + + QElapsedTimer mEventsRefTimer; //Cafeful, this timer is shared with the thread. DO NOT access it while the ZT1 or ZT2 thread is running. + QElapsedTimer mZT1LogDelayTimer; //Timer qui limite la fréquence d'écriture dans le log. On peut bypasser en cochant "log haute fréquence" dans la page ingénierie + QElapsedTimer mZT1PassageTimeLimitTimer; + QElapsedTimer mZT2PassageTimeLimitTimer; + qint64 mLogDelay; + CLogMgr *mLogMgr; //Classe qui gère les logs. + + unsigned int mLastInputs, mCurInputs; //Latch des entrées discrètes + + unsigned int mNbPassages; //Nombre de passages + unsigned int mNbTriggers; //Nombre de déclenchements + unsigned int mTrainTypeDetected; //Type de train + unsigned int mCalibrationPassagesCount; //Nombre de passages lors de la calibration + unsigned int mPGNbTotalPassages; //Nombre de passages requis lors de la calibration + unsigned int mZT1ActiveStatus; //état de la ZT1 (Active ou pas) + unsigned int mZT2ActiveStatus; //état de la ZT2 (Active ou pas) + bool mZT2Present; //Flag qui indique si la station possède une ZT2 + bool mAutoExportZT1CSV,mAutoExportZT2CSV; //Flags qui indiquent s'il faut créer des fichiers CSV pour chaque log. Configurable dans la page ingénierie. + unsigned int mZT1PEQType; //Type de la dernière panne équipement lorsqu'il y en a une. + + CZT1Log mZT1Log; //Les données du log ZT1 du passage courant (un seul train) + CZT2Log mZT2Log; + //QVectormZT2Log; //Les données du log ZT2 du passage courant (un seul train) + QVector mZT1DetectionsLog; //Log des déclenchements ZT1 + QVector mZT2DetectionsLog; //Log des déclenchements ZT2 + QList mZTPGCalibrationData[ZT_SM_MAX_NB_PG_CALIB_PASSAGES]; //Données de calibration + + QElapsedTimer mFSSyncTimer; + bool mTimeToForceSyncFS; + +signals: + void PGCalibrationFinished(int); //Signal envoyé lorsque la calibration est terminée. Le paramètre est la valeur calculée. + void PGCalibrationStatus(int,int); //Signal envoyé pour informer de l'état de la calibration. Le paramètre 1 est le nombre de passages à date et le 2è est le nombre requis. + void MaintenancePPActivated(unsigned int); //Signal envoyé à la page d'entretien pour indiquer qu'une pédale PP a été activée. + void NewTrainLogSaved(); //Signal envoyé pour notifier l'interface graphique qu'un nouveau fichier de passage a été sauvegardé. + +public slots: + + void ZT1StateChanged(CZT1ThreadData*, bool, int); //Envoyé par le thread ZT1 lorsque des nouvelles données sont prêtes à ajouter au log + void ZT2StateChanged(CZT2ThreadData* ); //Envoyé par le thread ZT2 lorsque des nouvelles données sont prêtes à ajouter au log + void ZT1NewDetection(CZTDetectionData* ); //Envoyé par le thread ZT1 lorsqu'un déclenchement survient + void ZT1NewFlag(int, CZT1FlagsData*); //Envoyé par le thread ZT1 lorsqu'un flag est disopnible + void ZT2NewDetection(CZTDetectionData* ); //Envoyé par le thread ZT1 lorsqu'un déclenchement survient + void NewPGCalibrationData(CZTPGCalibrationData*); //Envoyé par le thread ZT1 lorsque des données de calibration sont disponibles. + void AddLogStringFromThread(QString); + void ModbusCCANUpdate(); //Envoyé par ModbusCCMgr lorsque la CC change la valeur du signal AN1 ou AN2 via le Modbus. + + + +}; + +#endif // ZTSTATEMACHINE_H diff --git a/sources/ZTVersion.h b/sources/ZTVersion.h new file mode 100644 index 0000000..b28b302 --- /dev/null +++ b/sources/ZTVersion.h @@ -0,0 +1,141 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 - 2013 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### YYYMMDD JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZTVERSION_H +#define ZTVERSION_H + +#define ZT_SOFT_VERSION "ZT_MODBUS_DEV" + +//LOG DES CHANGEMENTS +//Version 1.15 +//Modification de l'initialisation de la station à partir de la clef électrique directement. +//Retrait de la vérification de la cohérence de la clef avec le fichier de configuration. + +//Version 1.14 +//-Correction de la corruption des fichiers de passage lorsque des lectures étaient +// encore dans la queue des "signals" provenant du thread ZT1 alors que le passage +// était terminé. Correction de l'affichage aussi. + +//Version 1.13 +//-À la demande générale, remise à zéro du nombre de passages lors du téléchargement des +// passages. +//-Ajout d'un checkbox permettant de conserver les fichiers lors de l'archivage. + +//Version 1.12 +//-Changement du délai de sortie automatique du mode entretien de 1h à 2h. +//-Ajout du nom de la station dans le fichier LOG lors de sa destruction. +//-Correction du changement de la date qui ignorait l'année. +//-Ajout d'entrées dans le log d'ingénierie pour investiguer les détections FN intempestives. +//-Retrait de la trace du signal virtuel PG dans la visualisation des passages et +// aggrandissement de la trace analogique du SDF + +//Version 1.11 +//-À la demande générale, changement de la couleur d'un CDV occupé pour la couleur orange afin +// de se conformer à l'affichage des PICC. +//-Suite à l'analyse de la Commande Centralisée, le rang par défaut lors d'une détection avec +// erreur de comptage est revenu à 1. +//-Correction d'une fausse détection PEQ1 "FN collé à 1" lors d'une erreur de comptage. +//-Vérification que le fichier log d'ingénierie ne dépasse pas 1Mb. + +//Version 1.10 +//-Ajout de la condition CDV ZT2 libre lors de l'activation de la CIZT2 pour activer la ZT2. +//-Lors d'une erreur de comptage + détection frotteur, envoyer deux alarmes FN aux rangs 1 et 18. +// Le nouveau rang par défaut pour les autres types de déclenchements est changé pour le rang 0 + +//Version 1.09 +//-Changement du CDV d'approche et combinaison du CDV ZT1 à Longueuil car les équipements sont +// installés trop près du joint isolant. +//-Mise à jour de la liste des passages lorsqu'un train passe alors que la liste est en train +// d'être consultée. +//-Allongement du quai à MMO 10/22 pour couvrir le CDV 22 au complet. +//-Les pédales ZT2 ne sont pas affichées dans la page de maintenance si la station ne possède +// pas de ZT2. +//-Scroll de la vue à la fin du fichier LOG lors de son affichage. + +//Version 1.08 +//-Synchronisation du filesystem (commande sync) appelée périodiquement à toutes les 40 minutes +// après qu'un train ait quitté ZT2 (ou ZT1 s'il n'y a pas de ZT2) pour s'Assurer que le système +// ne ralentit pas trop lors d'un sync intempestif. +//-Changement du CDV d'armement ZT2 de Bourassa. +//-Ajout d'un flag dans le fichier de passage lorsqu'un déclenchement survient mais que la TK +// n'est pas envoyée au PCC. Les fichiers de passage avec le flag à 1 sont conservés au même titre +// que les déclenchements réguliers. +//-Ajout d'un bouton d'acquitement manuel des alarmes dans le mode entretien. +//-Les alarmes PEQX et V0X sont émises à la fin plutôt qu'au débutlorsque d'autres déclenchements +// sont présents +//-Changment du nombre minimum de fichiers de passage à conserver (dans la page d'ingénierie) à 1. + + +//Version 1.07 +// +//-La copie des fichiers sur la clef USB pouvait faire redémarrer l'ordinateur étant donné que la +// commande "sync" était appelée dans le thread principal (bloquant ainsi le rafraîchissement du +// watchdog interne). sync peut être longue à exécuter, elle a donc été déplacée dans le thread. +//-Finalisation du fichier station Montmorency.cpp afin d'accueillir les 2 itinéraires. + +//Version 1.06 +// +//-Correction de la valeur par défaut du flag TK ZT1 activé dans ZTSettings::LoadDefaultValues. +// + +//Version 1.05 +// +//-Correction d'un bug qui faisait planter l'application lorsqu'un module externe n'était +// pas détecté. +//-Ajout d'un curseur horizontal dans la visualisation des passages. +//-Adaptation et modification de la state machine pour les particularités d'installation +// à Snowdon. +//-Correction de l'assignation des inputs à Snowdon + +//Version 1.04 +// +//-Ajout de la détection du bouton "power" afin de quitter l'application zonetest adéquatement +// avant de redémarrer l'ordinateur. +//-Changement du "toggle" de la sortie Vigie pour un pulse d'une seconde. + +//Version 1.03 +// +//-Ajout de la possibilité de paramétrer le nombre de fichiers de passages à conserver +// dans la page d'ingénierie et de conserver les fichiers ZT1, ZT2 ou MPM10. +//-Changement du délai de la vigie à 10 secondes pour ménager les relais du module de sortie. + +//Version 1.02 +// +//-Ajout d'un message dans EngLog dans le cas où l'accès aux modules externes est un échec +// afin de trouver pourquoi la vigie ne fonctionnait plus à C-Vertu. + +//Version 1.01 +// +//-Corrections diverses reliées au log des erreurs de comptage et autres suite aux problèmes +// de comptage ZT2 rencontrés à C-Vertu. + +//Version 1.00: +// +//-Version utilisée lors de l'installation du premier T.O. produit par l'atelier à Côte-Vertu. + + +#endif // ZTVERSION_H diff --git a/sources/ZTconfigmgr.cpp b/sources/ZTconfigmgr.cpp new file mode 100644 index 0000000..bf4171a --- /dev/null +++ b/sources/ZTconfigmgr.cpp @@ -0,0 +1,285 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Classe de gestion de la configuration. Gère l'assignation et l'accès aux + paramètres contenues dans le fichier de configuration de la ZT. + Cette classe est Singleton. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121214 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "ZTconfigmgr.h" + +CZTConfigMgr CZTConfigMgr::mSingleton; + +CZTConfigMgr::CZTConfigMgr() +{ + + //Initialize default variable values. + + //External IO Modules + mConfig_ExtIO_MasterIPAddr = "192.168.0.1"; + mConfig_ExtIOModulesConfigList.clear(); + + //DataQ Module + mDataQIPAddr.clear(); + + //Station config + mConfig_Station_StationName = "UNKNOWN"; +// mConfig_Station_LaserSensorCalib = 0; + + //This is the value of verbosity. Returns -1 if log is disabled + mEngLogVerbosity = -1; + + //Lazer probes + mConfig_LazerProbeModulesConfigList.clear(); + + //Simulator activation + mUseSimulator = false; + + //Modbus communication with CC + mUseModbusCC = false; +} + +ZTConfigResult CZTConfigMgr::LoadZTConfig() +{ + mZTConfigFile = new QFile("./Configuration/ZT.cfg"); + if (!mZTConfigFile->open(QIODevice::ReadOnly | QIODevice::Text)) + { + delete mZTConfigFile; + return ZT_CONFIG_FILE_ERROR; + } + + bool finished = false; + QString string; + QString temp; + int pos; + while(!finished) + { + + string.clear(); + string = mZTConfigFile->readLine(1024); + if(string.isEmpty()) + { + finished = true; + break; + } + + if(string.at(0) != '#' && string.at(0) != '\n') + { + string.remove("\n"); //remove trailing "\n" characters inserted by QFile.readline + string.remove(' '); //remove spaces + pos = string.indexOf('='); + if(pos != -1) + { + pos += 1; + + + //External modules configuration parameters + if(string.contains("EXTIO_MASTER_IP")) + { + mConfig_ExtIO_MasterIPAddr = string.mid(pos); + CEngLog::instance()->AddLogString(QString().sprintf("EXTIO_MASTER_IP = %s",mConfig_ExtIO_MasterIPAddr.toUtf8().constData())); + } + else if(string.contains("DATAQ_IP")) + { + mDataQIPAddr = string.mid(pos); + CEngLog::instance()->AddLogString(QString().sprintf("DATAQ_IP = %s",mDataQIPAddr.toUtf8().constData())); + } + else if(string.contains("EXTIO_430_MOD_PHYS_ADDR")) + { + stExtModulesConfig_t ModuleConfig; + ModuleConfig.ModuleID = atoi(string.mid(pos-2,1).toUtf8().constData()); + ModuleConfig.ModuleSlaveAddress = atoi(string.mid(pos).toUtf8().constData()); + ModuleConfig.ModuleType = EXT_IO_TYPE_430; + mConfig_ExtIOModulesConfigList.append(ModuleConfig); + CEngLog::instance()->AddLogString(QString().sprintf("EXTIO_430_MOD_PHYS_ADDR = %d",ModuleConfig.ModuleSlaveAddress)); + } + else if(string.contains("EXTIO_440_MOD_PHYS_ADDR")) + { + stExtModulesConfig_t ModuleConfig; + ModuleConfig.ModuleID = atoi(string.mid(pos-2,1).toUtf8().constData()); + ModuleConfig.ModuleSlaveAddress = atoi(string.mid(pos).toUtf8().constData()); + ModuleConfig.ModuleType = EXT_IO_TYPE_440; + mConfig_ExtIOModulesConfigList.append(ModuleConfig); + CEngLog::instance()->AddLogString(QString().sprintf("EXTIO_440_MOD_PHYS_ADDR = %d",ModuleConfig.ModuleSlaveAddress)); + } + else if(string.contains("EXTIO_470_MOD_PHYS_ADDR")) + { + stExtModulesConfig_t ModuleConfig; + ModuleConfig.ModuleID = atoi(string.mid(pos-2,1).toUtf8().constData()); + ModuleConfig.ModuleSlaveAddress = atoi(string.mid(pos).toUtf8().constData()); + ModuleConfig.ModuleType = EXT_IO_TYPE_470; + mConfig_ExtIOModulesConfigList.append(ModuleConfig); + CEngLog::instance()->AddLogString(QString().sprintf("EXTIO_470_MOD_PHYS_ADDR = %d",ModuleConfig.ModuleSlaveAddress)); + } + else if(string.contains("SIMULATEUR")) + { + if(string.mid(pos) == "OUI") + mUseSimulator = true; + else if(string.mid(pos) == "NON") + mUseSimulator = false; + else + CEngLog::instance()->AddLogString(QString().sprintf("Invalid SIMULATOR parameter: %s",string.mid(pos).toUtf8().constData())); + + CEngLog::instance()->AddLogString(QString().sprintf("SIMULATEUR = %d",mUseSimulator)); + } + else if(string.contains("ENGLOG")) + { + mEngLogVerbosity = atoi(string.mid(pos).toUtf8().constData()); + if(mEngLogVerbosity < 0 || mEngLogVerbosity > 3) + { + CEngLog::instance()->AddLogString(QString().sprintf("Invalid Eng Log verbosity: %d. Eng Log disabled",mEngLogVerbosity)); + mEngLogVerbosity = -1; + } + else + CEngLog::instance()->AddLogString(QString().sprintf("Eng Log verbosity = %d",mEngLogVerbosity)); + } + else if(string.contains("UTILISER_MODBUS_CC")) + { + if(string.mid(pos) == "OUI") + mUseModbusCC = true; + else if(string.mid(pos) == "NON") + mUseSimulator = false; + else + CEngLog::instance()->AddLogString(QString().sprintf("Invalid MODBUS_CC parameter: %s",string.mid(pos).toUtf8().constData())); + + CEngLog::instance()->AddLogString(QString().sprintf("Comm. Modbus avec la CC = %d",mUseModbusCC)); + } + else if(string.contains("MODBUS_CC_DEVID")) + { + bool OK; + mModbusCCDevID = (string.mid(pos).toInt(&OK)); + if(OK == false) + { + CEngLog::instance()->AddLogString(QString().sprintf("Invalid MODBUS_CC_DEVID parameter: %s",string.mid(pos).toUtf8().constData())); + mModbusCCDevID = 1; + } + else + { + CEngLog::instance()->AddLogString(QString().sprintf("Device ID Modbus CC = %d",mModbusCCDevID)); + } + } + else if(string.contains("MODBUS_CC_PORT")) + { + bool OK; + mModbusCCPort = (string.mid(pos).toInt(&OK)); + if(OK == false) + { + CEngLog::instance()->AddLogString(QString().sprintf("Invalid MODBUS_CC_PORT parameter: %s",string.mid(pos).toUtf8().constData())); + mModbusCCPort = 6060; + } + CEngLog::instance()->AddLogString(QString().sprintf("Port Modbus CC = %d",mModbusCCPort)); + } + + //Station configuration parameters + else if(string.contains("STATION")) + { + mConfig_Station_StationName = string.mid(pos); + CEngLog::instance()->AddLogString(QString().sprintf("STATION = %s",mConfig_Station_StationName.toUtf8().constData())); + } +// else if(string.contains("CALIB_PNEU_GUIDAGE")) +// { +// mConfig_Station_LaserSensorCalib = atoi(string.mid(pos).toUtf8().constData()); +// qDebug("CALIB_PNEU_GUIDAGE = %d",mConfig_Station_LaserSensorCalib); +// } + + //Lazer probes serial port configuration parameters + else if(string.contains("SONDE_LASER_INT")) + { + stLazerProbesConfig_t LazerProbeConfig; + LazerProbeConfig.ProbeType = LAZER_PROBE_TYPE_INTERNAL; + LazerProbeConfig.ProbeID = atoi(string.mid(pos-2,1).toUtf8().constData()); + LazerProbeConfig.SerialPort = string.mid(pos); + mConfig_LazerProbeModulesConfigList.append(LazerProbeConfig); + CEngLog::instance()->AddLogString(QString().sprintf("LazerProbeINT_%d = Port: %s",LazerProbeConfig.ProbeID,LazerProbeConfig.SerialPort.toUtf8().constData())); + } + else if(string.contains("SONDE_LASER_EXT")) + { + stLazerProbesConfig_t LazerProbeConfig; + LazerProbeConfig.ProbeType = LAZER_PROBE_TYPE_EXTERNAL; + LazerProbeConfig.ProbeID = atoi(string.mid(pos-2,1).toUtf8().constData()); + LazerProbeConfig.SerialPort = string.mid(pos); + mConfig_LazerProbeModulesConfigList.append(LazerProbeConfig); + CEngLog::instance()->AddLogString(QString().sprintf("LazerProbeEXT_%d = Port: %s",LazerProbeConfig.ProbeID,LazerProbeConfig.SerialPort.toUtf8().constData())); + } + + + } + } + } + + + mZTConfigFile->close(); + delete mZTConfigFile; + + return ZT_CONFIG_OK; +} + +QString CZTConfigMgr::GetStationName() +{ + return mConfig_Station_StationName; +} + +QString CZTConfigMgr::GetExtIOIPAddress() +{ + return mConfig_ExtIO_MasterIPAddr; +} + +QList * CZTConfigMgr::GetExtIOModulesConfigList() +{ + return &mConfig_ExtIOModulesConfigList; +} + +QList * CZTConfigMgr::GetLazerProbesConfigList() +{ + return &mConfig_LazerProbeModulesConfigList; +} + +int CZTConfigMgr::GetEngLog() +{ + return mEngLogVerbosity; +} + +bool CZTConfigMgr::GetSimulatorEnabled() +{ + return mUseSimulator; +} + +bool CZTConfigMgr::GetModbusCCEnabled() +{ + return mUseModbusCC; +} +int CZTConfigMgr::GetModbusCCDevID() +{ + return mModbusCCDevID; +} + +int CZTConfigMgr::GetModbusCCPort() +{ + return mModbusCCPort; +} + +QString CZTConfigMgr::GetDataQIPAddress() +{ + return mDataQIPAddr; +} diff --git a/sources/ZTconfigmgr.h b/sources/ZTconfigmgr.h new file mode 100644 index 0000000..08105ab --- /dev/null +++ b/sources/ZTconfigmgr.h @@ -0,0 +1,112 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZTCONFIGMGR_H +#define ZTCONFIGMGR_H + +#include "GlobalDefine.h" +#include +#include +#include "Externaliomodule.h" +#include "LazerProbe.h" +#include "LazerProbesMgr.h" +#include + + +typedef enum eZTConfigResult +{ + ZT_CONFIG_OK, + ZT_CONFIG_FILE_ERROR, + ZT_CONFIG_PARAMETER_ERROR +}ZTConfigResult; + + +typedef struct stExtModulesConfig +{ + eExternalModuleType_t ModuleType; + unsigned int ModuleSlaveAddress; + unsigned int ModuleID; +}stExtModulesConfig_t; + + +typedef struct stLazerProbesConfig +{ + unsigned int ProbeType; + unsigned int ProbeID; + QString SerialPort; +}stLazerProbesConfig_t; + + +class CZTConfigMgr +{ +public: + + + + static CZTConfigMgr* instance(){return &mSingleton;} + static CZTConfigMgr mSingleton; + + ZTConfigResult LoadZTConfig(void); + + QFile *mZTConfigFile; + + CZTConfigMgr(); + + QString GetStationName(void); + QString GetExtIOIPAddress(void); + QString GetDataQIPAddress(); + QList *GetExtIOModulesConfigList(void); + QList *GetLazerProbesConfigList(void); + int GetEngLog(void); + bool GetSimulatorEnabled(); + bool GetModbusCCEnabled(); + int GetModbusCCPort(); + int GetModbusCCDevID(); +// int GetLaserSensorCalib(){return mConfig_Station_LaserSensorCalib;} + + + +private: + //configuration values + + //External IO Modules + QString mConfig_ExtIO_MasterIPAddr; + QString mDataQIPAddr; + QList mConfig_ExtIOModulesConfigList; + QList mConfig_LazerProbeModulesConfigList; + + QString mConfig_Station_StationName; +// int mConfig_Station_LaserSensorCalib; + int mEngLogVerbosity; + bool mUseSimulator; + bool mUseModbusCC; + int mModbusCCDevID; + int mModbusCCPort; + +}; + +#endif // ZTCONFIGMGR_H diff --git a/sources/Zonetest.cpp b/sources/Zonetest.cpp new file mode 100644 index 0000000..0f708c5 --- /dev/null +++ b/sources/Zonetest.cpp @@ -0,0 +1,1280 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Cette classe est considérée comme l'instance du programme qui + initialise et démarre tous les objets nécessaires. + Elle assure aussi la synchronisation de ces derniers à l'aide de sa + machine à états. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121214 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#include "Zonetest.h" +//#include "MainPanel.h" +#include "ZTconfigmgr.h" +#include +#include "EngLog.h" +#include + +#include "Angrignon.h" +#include "BerriUQAM.h" +#include "CoteVertu.h" +#include "HenriBourassa.h" +#include "HonoreBeaugrand.h" +#include "Longueuil.h" +#include "Montmorency.h" +#include "Montmorency1012.h" +#include "Montmorency1022.h" +#include "SaintMichel.h" +#include "Snowdon.h" +#include "SimulatorIOManager.h" +#include "SimulatorLazerProbesMgr.h" +#include "SimulatorPCIIO.h" +#include +#include "ZTLog.h" +#include "RamMonitor.h" +#include "PCI1756Interface.h" +#include "USB4704Interface.h" +#include "ZTVersion.h" +#include "ModbusCCDefs.h" +#include "ModbusTKTransport.h" + +#ifdef USE_NETWORKING +#include "NetworkManager.h" +#endif + +#include "qextserialport.h" + +CZoneTest::CZoneTest(): + mZTStation(0), + mZtState(ZT_INIT_STATE) +{ + mZTStartDateTime = QDateTime::currentDateTime(); + + mZTStateMachineTimer = new QTimer(); + connect(mZTStateMachineTimer, SIGNAL(timeout()), this, SLOT(SMTimerExpired())); + panel.installEventFilter(this); //Install an event filter for CZoneTest to manage some events from GUI + + mZTStateMachine = new CZTStateMachine(); + mZTSimulator = 0; + mIOManager = 0; + mLazerProbesManager = 0; + mAnalogModule = 0; + mTKTransportInterface = 0; + mCCModbusRepository = 0; + mModbusCCMgr = 0; + + mSimulationON = false; + mWatchdogEnabled = true; + mZTSettings = new CZTSettingsData(); + + mEventMgr = new CEventMgr(); + mLogMgr = new CLogMgr(); + mUSBDriveInterface = new CUSBDriveInterface(); + + mExtIOWorkerThread = new CExtIOThread; + mExtIOThread = new QThread; + mExtIOWorkerThread->moveToThread(mExtIOThread); + connect(mExtIOThread,SIGNAL(started()),mExtIOWorkerThread,SLOT(DoAcquisition())); + + + +} +CZoneTest::~CZoneTest() +{ + delete mLogMgr; + delete mEventMgr; + delete mUSBDriveInterface; + delete mLazerProbesManager; + delete mZTStateMachine; + delete mIOManager; + delete mPCIIO; + delete mZTStation; + delete mZTSettings; + delete mExtIOThread; + delete mExtIOWorkerThread; + delete mInternalWatchdog; + + if(mTKTransportInterface != 0) + delete mTKTransportInterface; + + if(mCCModbusRepository != 0) + delete mCCModbusRepository; + + if(mModbusCCMgr != 0) + { + delete mModbusCCMgr; + } + + if(mAnalogModule != 0) + delete mAnalogModule; +} + +unsigned int CZoneTest::ExecStateMachine(eZTSMEvents_t) +{ + switch(mZtState) + { + case ZT_INIT_STATE: + { + mZTStateMachineTimer->stop(); + mZtState = ZT_RUN_STATE; + mWatchdogTimer.start(); + mZTStateMachineTimer->setSingleShot(false); + + int ret = InitZT(); + + mInternalWatchdog->StartWatchdog(); + + if(ret == RET_OK) + { + mZTStateMachineTimer->start(0); + mExtIOWorkerThread->SetOutputFlags(mZTStation->GetOutputMasks()->OutputWatchdogMask); + mWatchdogTimer.start(); + } + break; + } + case ZT_RUN_STATE: + { + static bool sExtWatchdogFlag = true; + mZTStateMachine->ZTStateMachine(ZT_TICK_EVENT); + mInternalWatchdog->KickWatchdog(); + if(mWatchdogEnabled) + { + if(sExtWatchdogFlag == true) + { + if(mWatchdogTimer.elapsed() >= ZT_EXTERNAL_WATCHDOG_PULSE_TIME) + { + mExtIOWorkerThread->ClearOutputFlags(mZTStation->GetOutputMasks()->OutputWatchdogMask); + mWatchdogTimer.start(); + sExtWatchdogFlag = false; + } + } + else + { + if(mWatchdogTimer.elapsed() >= ZT_EXTERNAL_WATCHDOG_TIMEOUT) + { + mExtIOWorkerThread->SetOutputFlags(mZTStation->GetOutputMasks()->OutputWatchdogMask); + mWatchdogTimer.start(); + sExtWatchdogFlag = true; + } + } + } + break; + } + case ZT_DEADLOCK_STATE: + { + //Stay in this state after a fatal error happened. + mInternalWatchdog->KickWatchdog(); + if(mWatchdogEnabled) + { + if(mWatchdogTimer.elapsed() >= ZT_EXTERNAL_WATCHDOG_TIMEOUT) + { + mExtIOWorkerThread->ToggleOutputFlags(mZTStation->GetOutputMasks()->OutputWatchdogMask); + mWatchdogTimer.start(); + } + } + + break; + } + case ZT_EXIT_APPLICATION_STATE: + { + mZTStateMachineTimer->stop(); + mInternalWatchdog->StopWatchdog(); + + QApplication::exit(78); //Quit the application + break; + } + case ZT_POWER_BUTTON_EXIT_STATE: + { + mZTStateMachineTimer->stop(); + mInternalWatchdog->StopWatchdog(); + + //Initiate a system shutdown + system("shutdown -h -P now"); + + QApplication::exit(79); //Quit the application + break; + } + default: + { + } + + } + return RET_OK; +} + +void CZoneTest::SMTimerExpired() +{ + ExecStateMachine(ZT_SM_TICK_EVENT); +} + +unsigned int CZoneTest::Start() +{ + + //init some pointers... + mWelcomePagePtr = panel.mWelcomePage; + panel.mProgramHandle = this; + panel.mZTMainPage->mProgramHandle = this; + panel.mOptionsPage->mProgramHandle = this; + panel.mFunctionSelectPage->mProgramHandle = this; +// panel.mFunctionSelectPage->SetConfig(mZTSettings->mDetectionFunctionSettings); + panel.mZTMainPage->SetEventListPtr(&mEventMgr->mEventsList); + panel.mLogsListPage->mProgramHandle = this; + panel.mLogsListPage->mLogMgrHandle = mLogMgr; + panel.mLogViewPage->mProgramHandle = this; + panel.mMaintenancePage->mProgramHandle = this; + panel.mGeneralSettingsPage->mProgramHandle = this; + panel.mZTLogViewerPage->mProgramHandle = this; + panel.mEngineeringPage->mDisablePassword = mDisablePassword; + mInternalWatchdog = new CWatchdogCtrl(mUseWatchdog); + + + + + +#ifdef USE_NETWORKING + CNetworkManager::instance()->BindPointers(this); +#endif + + mEventMgr->mProgramPTr = this; + mEventMgr->mMainPagePtr = panel.mZTMainPage; +// mEventMgr->UpdateEvents(mZTSettings->mDetectionFunctionSettings); + + mZTStateMachine->mZTDetectionConfig = mZTSettings->mDetectionFunctionSettings; + connect(mZTStateMachine,SIGNAL(NewTrainLogSaved()),panel.mLogsListPage,SLOT(NewTrainLogFileSaved())); + + CZTLog::instance()->mProgramHandle = this; + + + + //Show Graphic User Interface. + panel.setWindowTitle("ZoneTest"); + if(mFullScreen) + { + panel.showFullScreen(); + } + else + { + panel.show(); + } + + mWelcomePagePtr->ClearTextBoxWidget(); + mWelcomePagePtr->InsertTextBoxString("Application Zone Tests"); + mWelcomePagePtr->InsertTextBoxString(QString().sprintf("Version: %s",ZT_SOFT_VERSION)); + mWelcomePagePtr->ShowTextboxWidget(); + + mZTStateMachineTimer->setSingleShot(false); + mZTStateMachineTimer->start(1000); + return RET_OK; +} + + +unsigned int CZoneTest::InitZT() +{ + + //mWelcomePagePtr->ClearTextBoxWidget(); + + CheckAndCreateDirectories(); + + CZTLog::instance()->Init(); + + //Load the config file + if(CZTConfigMgr::instance()->LoadZTConfig() != ZT_CONFIG_OK) + { + mWelcomePagePtr->InsertTextBoxString("Erreur d'ouverture du fichier de configuration"); + mWelcomePagePtr->InsertTextBoxString("Vérifier la présence du fichier ZT.conf"); + // mWelcomePagePtr->InsertTextBoxString("L'exécution du logiciel va se terminer."); + + EnterDeadlockState(); + return RET_ERROR; + } + + + + //Create engineering log if defined in config file. + if(CZTConfigMgr::instance()->GetEngLog() != -1) + { + CEngLog::instance()->Init(CZTConfigMgr::instance()->GetEngLog()); + } + else + qDebug("Engineering Log disabled"); + + + //Load the ZoneTest settings + mZTSettingsFileMgr.LoadSettings(mZTSettings); + mEventMgr->UpdateEvents(mZTSettings->mDetectionFunctionSettings); + panel.mFunctionSelectPage->SetConfig(mZTSettings->mDetectionFunctionSettings); + mLogMgr->SetMaxLogFilesCount(mZTSettings->mMaxLogCount); + mLogMgr->KeepAllMPM10Logs(mZTSettings->mKeepMPM10Logs); + mLogMgr->KeepAllZT1Logs(mZTSettings->mKeepAllZT1Logs); + mLogMgr->KeepAllZT2Logs(mZTSettings->mKeepAllZT2Logs); + panel.mEngineeringPage->ZTLogFilesSettings(mZTSettings->mMaxLogCount,mZTSettings->mKeepMPM10Logs,mZTSettings->mKeepAllZT1Logs,mZTSettings->mKeepAllZT2Logs); + + connect(&mACPISocket,SIGNAL(connected()),this,SLOT(ACPISocketConnected())); + connect(&mACPISocket,SIGNAL(readyRead()),this,SLOT(ACPISocketEvent())); + mACPISocket.connectToServer("/var/run/acpid.socket",QIODevice::ReadOnly); + + //Check if we must enter simulated mode + if(CZTConfigMgr::instance()->GetSimulatorEnabled() == true) + { + mSimulationON = true; + CZTLog::instance()->AddLogString("Mode Simulation détecté.",true); + + //Create simulated I/O objects + mIOManager = new CSimulatorIOManager(); + mLazerProbesManager = new CSimulatorLazerProbesMgr(); + mPCIIO = new CSimulatorPCIIO(); + + mZTSimulator = new CZTSimulator((CSimulatorIOManager*)mIOManager); +// mZTSimulator->Init(panel.mZTMainPage); + panel.mZTMainPage->SetZTSimulator(mZTSimulator); + + mZTSimulator->SetPGTreshold(mZTSettings->mPGTreshold); + } + else + { +#ifndef WINDOWS_OS + //Create actual I/O objects + mIOManager = new CExternalIOMgr(); + if(mSimulateLazerProbes) + { + mLazerProbesManager = new CSimulatorLazerProbesMgr(); + } + else + { + mLazerProbesManager = new CLazerProbesMgr(); + } + #ifdef USE_DAQNAVI_LIB + mPCIIO = new CPCI1756Interface(); + #else + mPCIIO = new CComediLibInterface(); + #endif +#endif + } + + + //Open the external IO modules connection and create instances of + //the modules as they are configured in the config file. + if(mIOManager->InitIO() != EXTIO_MGR_RET_OK) + { + + mWelcomePagePtr->InsertTextBoxString(QString("Impossible d'initialiser les modules externes")); + mWelcomePagePtr->InsertTextBoxString(QString("Vérifier le fichier de configuration et la connexion au module maître.")); + CZTLog::instance()->AddLogString("Impossible d'initialiser les modules externes",true); + + mWatchdogEnabled=false; + EnterDeadlockState(); + return RET_ERROR; + } + mWelcomePagePtr->InsertTextBoxString(QString("Initialisation des modules externes: OK")); + + mAnalogModule = 0; + +// //Open the DataQ datalogger module if present in config file +// QString DataQIP = CZTConfigMgr::instance()->GetDataQIPAddress(); +// if(DataQIP.isEmpty()) +// { +// CZTLog::instance()->AddLogString("Module DataQ non trouvé dans le fichier de configuration.",true); +// } +// else +// { +// mDI710Module = new CDI710Driver; +// if(mDI710Module->OpenDevice(DataQIP,DI710_TCP_PORT) != DI710_RET_OK) +// { +// mWelcomePagePtr->InsertTextBoxString(QString("Impossible d'initialiser le module DataQ")); +// mWelcomePagePtr->InsertTextBoxString(QString("Vérifier le fichier de configuration et la connexion.")); +// CZTLog::instance()->AddLogString("Impossible d'initialiser le module DataQ",true); +// delete mDI710Module; +// mDI710Module = 0; +// } +// else +// { +// mDataQThread = new QThread; +// mDI710Module->moveToThread(mDataQThread); +// connect(mDataQThread,SIGNAL(started()),mDI710Module,SLOT(Run())); +// mDataQThread->start(); +// mWelcomePagePtr->InsertTextBoxString(QString("Initialisation du module DataQ: OK")); +// } +// } + + //Now, determine which of the analog module is detected. + +// if((mIOManager->GetModule(IO_MODULE_MIXED_TYPE,1) != 0)) +// { +// mAnalogModule = (CMixedModule*)mIOManager->GetModule(IO_MODULE_MIXED_TYPE,1); +// } +// else if(mDI710Module != 0) +// { +// mAnalogModule = mDI710Module; +// } + + + //Open advantech USB-4704 analog acquisition module. + CUSB4704Interface *USBAnalogModule = new CUSB4704Interface(); + if(USBAnalogModule->OpenInterface() == RET_OK) + { + mAnalogModule = USBAnalogModule; + } + + +#ifndef NO_PCI_CARD_INSTALLED + //Open an check internal PCI inputs/outputs adapter card. + if(mPCIIO->OpenPCIInterface() != PCIIO_OK) + { + mWelcomePagePtr->InsertTextBoxString(QString("Impossible d'initialiser la carte PCI")); + CZTLog::instance()->AddLogString(QString("Impossible d'initialiser la carte PCI"),true); + + EnterDeadlockState(); + return RET_ERROR; + } + mWelcomePagePtr->InsertTextBoxString(QString("Initialisation de la carte PCI: OK")); +#else + mWelcomePagePtr->InsertTextBoxString(QString("Carte PCI Ignorée. (NO_PCI_CARD_INSTALLED)")); +#endif + + //Open the lazer probes as configured in the config file + if(mLazerProbesManager->InitLazerProbes() != LAZERPROBES_MGR_RET_OK) + { + mWelcomePagePtr->InsertTextBoxString(QString("Impossible d'initialiser une ou plusieurs sondes laser")); + + CZTLog::instance()->AddLogString(QString("Impossible d'initialiser une ou plusieurs sondes laser"),true); + EnterDeadlockState(); + return RET_ERROR; + } + mWelcomePagePtr->InsertTextBoxString(QString("Initialisation des sondes laser: OK")); + + + + //Instantiate the station according to the physical key + if(InitStation() == RET_ERROR) + { + EnterDeadlockState(); + return RET_ERROR; + } + mZTSettingsFileMgr.SetStationName(GetStationTextualName()); + + mOutputModule = (COutputModule*)mIOManager->GetModule(IO_MODULE_OUTPUT_TYPE,1); + + mExtIOWorkerThread->BindPointers((CInputModule*)mIOManager->GetModule(IO_MODULE_INPUT_TYPE,1), + (COutputModule*)mIOManager->GetModule(IO_MODULE_OUTPUT_TYPE,1), + (CAnalogInputModule*)mIOManager->GetModule(IO_MODULE_MIXED_TYPE,1), + mZTStation->GetAnalogAcqChannels()->SDFAcquisitionChannel); + + mExtIOThread->start(QThread::NormalPriority); + + if(CZTConfigMgr::instance()->GetModbusCCEnabled() == true) + { + int ModbusPort = CZTConfigMgr::instance()->GetModbusCCPort(); + int DevID = CZTConfigMgr::instance()->GetModbusCCDevID(); + if(DevID >= 255) + { + mWelcomePagePtr->InsertTextBoxString(QString("Valeur DevID Modbus CC invalide (%1)").arg(DevID)); + EnterDeadlockState(); + return RET_ERROR; + } + + mCCModbusRepository = new CModbusRepository; + mCCModbusRepository->AddHRDataMap(MODBUS_ZT_DATA_BASE_REG,MODBUS_ZT_TABLE_DATA_SIZE); //Add the ZT data map + mCCModbusRepository->AddHRDataMap(MODBUS_CC_DATA_BASE_REG_ADD,MODBUS_ZT_TABLE_DATA_SIZE); //Add the CC data map + mModbusCCMgr = new CModbusCCMgr(mCCModbusRepository,ModbusPort,DevID); + mModbusCCMgr->StartModbusCCServer(); + + CModbusTKTransport *TransportInterface = new CModbusTKTransport(mCCModbusRepository); + mTKTransportInterface = (CTKTransportInterface*)TransportInterface; + connect(mModbusCCMgr,SIGNAL(RepoHasChanged()),TransportInterface,SLOT(ModbusCCUpdated())); + + mZTStateMachine->BindCCRepoPtr(mCCModbusRepository); + // connect(mModbusCCMgr,SIGNAL(RepoHasChanged()),mZTStateMachine,SLOT(ModbusCCANUpdate())); + connect(mModbusCCMgr,SIGNAL(ModbusCCConnected()),panel.mZTMainPage,SLOT(ModbusCCConnected())); + connect(mModbusCCMgr,SIGNAL(ModbusCCDisconnected()),panel.mZTMainPage,SLOT(ModbusCCDisconnected())); + panel.mZTMainPage->ModbusCCDisconnected(); + } + else + { + CDiscreteTKTransport *TransportInterface = new CDiscreteTKTransport; + mTKTransportInterface = (CTKTransportInterface*)TransportInterface; + TransportInterface->BindPointers(mZTStation->GetOutputMasks(),mExtIOWorkerThread); + } + connect(mTKTransportInterface,SIGNAL(TKOutputStatesChanged(bool,bool)),panel.mMaintenancePage,SLOT(TKOutputChanged(bool,bool))); + + + if(mSimulationON == true) + { +#ifdef USE_REAL_ANALOG_EXTERNAL_MODULE + mZTSimulator->Init(panel.mZTMainPage,mZTStation,mIOManager,mPCIIO,mLazerProbesManager,mUSBDriveInterface,mAnalogModule); +#else + mZTSimulator->Init(panel.mZTMainPage,mZTStation,mIOManager,mPCIIO,mLazerProbesManager,mUSBDriveInterface); +#endif + mZTStateMachine->BindPointers(mZTStation, + mExtIOWorkerThread, + mExtIOWorkerThread, + panel.mZTMainPage, + mPCIIO, + mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_INTERNAL,1), + mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_EXTERNAL,1), + mLogMgr, + mTKTransportInterface, + mZTSimulator, + mAnalogModule); + + } + else + { + mZTStateMachine->BindPointers(mZTStation, + mExtIOWorkerThread, + mExtIOWorkerThread, + panel.mZTMainPage, + mPCIIO, + mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_INTERNAL,1), + mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_EXTERNAL,1), + mLogMgr, + mTKTransportInterface, + 0, + mAnalogModule); + } + + mZTStateMachine->SetPGTreshold(mZTSettings->mPGTreshold); + panel.mEngineeringPage->BindPointers(this, + mExtIOWorkerThread, + mExtIOWorkerThread, + mPCIIO, + mZTSettings, + mUSBDriveInterface, + mZTStation, + mAnalogModule); + connect(mZTStateMachine,SIGNAL(PGCalibrationFinished(int)),panel.mEngineeringPage,SLOT(PGCalibFinished(int))); + connect(mZTStateMachine,SIGNAL(PGCalibrationStatus(int,int)),panel.mEngineeringPage,SLOT(PGCalibUpdate(int,int))); + connect(mZTStateMachine,SIGNAL(MaintenancePPActivated(uint)),panel.mMaintenancePage,SLOT(PPActivated(uint))); + panel.mEngineeringPage->Init(); + if(mSimulationON == false) + { + connect((CLazerProbe*)mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_INTERNAL,1),SIGNAL(NewProbeData(unsigned int,unsigned int)),panel.mEngineeringPage,SLOT(LazerProbeDataAvailable(uint,uint))); + connect((CLazerProbe*)mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_EXTERNAL,1),SIGNAL(NewProbeData(unsigned int,unsigned int)),panel.mEngineeringPage,SLOT(LazerProbeDataAvailable(uint,uint))); + } + else + { + connect((CSimulatorLazerProbe*)mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_INTERNAL,1),SIGNAL(NewProbeData(unsigned int,unsigned int)),panel.mEngineeringPage,SLOT(LazerProbeDataAvailable(uint,uint))); + connect((CSimulatorLazerProbe*)mLazerProbesManager->GetLazerProbeHandle(LAZER_PROBE_TYPE_EXTERNAL,1),SIGNAL(NewProbeData(unsigned int,unsigned int)),panel.mEngineeringPage,SLOT(LazerProbeDataAvailable(uint,uint))); + + } + + panel.mZTMainPage->SetZT2Presence(mZTStation->StationHasZT2()); + mZTStateMachine->SetZT2Presence(mZTStation->StationHasZT2()); + mWelcomePagePtr->InsertTextBoxString(QString("Chargement des fichiers de passage de trains...")); + mLogMgr->ParseLogs(); + mWelcomePagePtr->InsertTextBoxString(QString("Chargement des fichiers de passage de trains: OK")); + mZTStateMachine->SetAutoExportZT1CSV(mZTSettings->mAutoExportZT1CSV); + mZTStateMachine->SetAutoExportZT2CSV(mZTSettings->mAutoExportZT2CSV); + panel.mLogsListPage->BindPointers(mUSBDriveInterface); + mUSBDriveInterface->Start(); +// if(mDI710Module != 0) +// mDI710Module->StartAcquisition(); + +#ifdef USE_NETWORKING + CNetworkManager::instance()->StartServer(); +#endif + + //CRamMonitor::instance()->StartTimer(); + + + CEngLog::instance()->AddLogString("Initialisation de la Zone Test réussie"); + panel.HideWelcomePage(); + panel.ShowMainPage(); + + return RET_OK; +} + +unsigned int CZoneTest::Run() +{ + return RET_OK; +} + +unsigned int CZoneTest::InitStation() +{ + CEngLog::instance()->AddLogString("CZoneTest::InitStation. Initialisation de la station"); + QString StationName = CZTConfigMgr::instance()->GetStationName(); + + if(mSimulationON == false && mIgnoreStationPhysicalKey == false) //Do not check station physical key in sim mode or if IgnoreKey switch activated. + { + CInputModule *inputmodule = (CInputModule*)mIOManager->GetModule(IO_MODULE_INPUT_TYPE,1); //Access the module directly since the thread is not yet started... + + unsigned int key = inputmodule->GetInputs(); + + if((key & ANGRIGNON_IN_STATION_ID_MASK) == ANGRIGNON_STATION_KEY) + { + StationName = "ANGRIGNON"; + } + else if((key & BERRIUQAM_IN_STATION_ID_MASK) == BERRIUQAM_STATION_KEY) + { + StationName = "BERRI_UQAM"; + } + else if((key & COTEVERTU_IN_STATION_ID_MASK) == COTEVERTU_STATION_KEY) + { + StationName = "COTE_VERTU"; + } + else if((key & HENRIBOURASSA_IN_STATION_ID_MASK) == HENRIBOURASSA_STATION_KEY) + { + StationName = "HENRI_BOURASSA"; + } + else if((key & HONOREBEAUGRAND_IN_STATION_ID_MASK) == HONOREBEAUGRAND_STATION_KEY) + { + StationName = "HONORE_BEAUGRAND"; + } + else if((key & LONGUEUIL_IN_STATION_ID_MASK) == LONGUEUIL_STATION_KEY) + { + StationName = "LONGUEIL"; + } + else if((key & MONTMORENCY_IN_STATION_ID_MASK) == MONTMORENCY_STATION_KEY) + { + StationName = "MONTMORENCY"; + } + else if((key & MONTMORENCY1012_IN_STATION_ID_MASK) == MONTMORENCY1012_STATION_KEY) + { + StationName = "MONTMORENCY_10_12"; + } + else if((key & MONTMORENCY1022_IN_STATION_ID_MASK) == MONTMORENCY1022_STATION_KEY) + { + StationName = "MONTMORENCY_10_22"; + } + else if((key & SAINTMICHEL_IN_STATION_ID_MASK) == SAINTMICHEL_STATION_KEY) + { + StationName = "SAINT_MICHEL"; + } + else if((key & SNOWDON_IN_STATION_ID_MASK) == SNOWDON_STATION_KEY) + { + StationName = "SNOWDON_L5"; + } + else + { + CEngLog::instance()->AddLogString(QString("ERREUR. Clef électrique de station inconnue: ") + StationName,2); + CEngLog::instance()->AddLogString(QString("Impossible d'initialiser la station"),1); + mWelcomePagePtr->InsertTextBoxString("Erreur: Station non reconnue"); + mWelcomePagePtr->InsertTextBoxString("Vérifier la clef électrique"); + return RET_ERROR; + } + } + + if(StationName == "HONORE_BEAUGRAND") + { + mZTStation = new CHonoreBeaugrandStation(); + } + else if(StationName == "ANGRIGNON") + { + mZTStation = new CAngrignonStation(); + } + else if(StationName == "HENRI_BOURASSA") + { + mZTStation = new CHenriBourassaStation(); + } + else if(StationName == "COTE_VERTU") + { + mZTStation = new CCoteVertuStation(); + } + else if(StationName == "BERRI_UQAM") + { + mZTStation = new CBerriUQAMStation(); + } + else if(StationName == "LONGUEIL") + { + mZTStation = new CLongueuilStation(); + } + else if(StationName == "SAINT_MICHEL") + { + mZTStation = new CSaintMichelStation(); + } + else if(StationName == "SNOWDON_L5") + { + mZTStation = new CSnowdonStation(); + } + else if(StationName == "MONTMORENCY") + { + mZTStation = new CMontmorencyStation(); + } + else if(StationName == "MONTMORENCY_10_12") + { + mZTStation = new CMontmorency1012Station(); + } + else if(StationName == "MONTMORENCY_10_22") + { + mZTStation = new CMontmorency1022Station(); + } + + else + { + CEngLog::instance()->AddLogString(QString("ERREUR. Nom de station invalide : ") + StationName,2); + CEngLog::instance()->AddLogString(QString("Impossible d'initialiser la station"),1); + mWelcomePagePtr->InsertTextBoxString("Erreur. Vérifier le fichier de configuration"); + mWelcomePagePtr->InsertTextBoxString(QString("Nom de station invalide : ") + StationName); + return RET_ERROR; + } + +// mZTStation->InitStation(mIOManager,mLazerProbesManager); + + + + mZTStation->BuildCDVList(); + panel.mZTMainPage->SetStationName(mZTStation->GetStationTextualName()); + panel.mZTMainPage->SetCDVList(mZTStation->GetCDVList()); + CZTLog::instance()->AddLogString(QString("Station initialisée : ") + mZTStation->GetStationTextualName(),true); + mWelcomePagePtr->InsertTextBoxString(QString("Station initialisée : ") + mZTStation->GetStationTextualName()); + + + + + return RET_OK; + +} + +void CZoneTest::EnterDeadlockState() +{ + //TODO: Set flags, Alarms, etc.. + + CZTLog::instance()->AddLogString(QString("L'exécution de l'application est terminée. DEADLOCK"),true); + + mZtState = ZT_DEADLOCK_STATE; +} + +//Catch and manage some events from the graphics user interface +//like the keyboard Exit sequence (Ctrl-F10) +bool CZoneTest::eventFilter(QObject *obj, QEvent *event) +{ + if(obj == &panel) //Check if event is coming from the GUI + { + if(event->type() == QEvent::KeyPress) + { + QKeyEvent *KeyEvent = static_cast(event); + + //Check if we received CTRL-F10 + if(KeyEvent->key() == Qt::Key_F10 && + KeyEvent->modifiers() == Qt::ControlModifier) + { + CZTLog::instance()->AddLogString("CTRL-F10...",true); + if(mDisablePassword == true) + { + CZTLog::instance()->AddLogString("Mot de passe désactivé. Sortie du programme.",true); + + ApplicationQuit(); + } + else + { + CZTLog::instance()->AddLogString("Demande du mot de passe.",true); + panel.mZTMainPage->RequestExitPassword(); + } + return true; //keep the keystroke + } + } + } + + return QObject::eventFilter(obj,event); + +} + +////Messages from Options page +void CZoneTest::ZTFunctionsOptionSelected() +{ + panel.mOptionsPage->hide(); + panel.mFunctionSelectPage->show(); +} + +void CZoneTest::ZTMaintenanceOptionSeleced() +{ + panel.mOptionsPage->hide(); + panel.mMaintenancePage->show(); +} + +/////////////// + +////Messages from Main ZT Page +void CZoneTest::OptionsMenuPageSelected() +{ + panel.mOptionsPage->show(); +} + +void CZoneTest::LogsPageSelected() +{ + panel.mLogsListPage->RefreshList(); + panel.mLogsListPage->show(); +} + +void CZoneTest::ProgramExitRequest() +{ + CZTLog::instance()->AddLogString("Mot de passe valide. Fin du programme.",true); + ApplicationQuit(); + QApplication::exit(79); +} + +///////////////// + +////Messages from Detection Functions select page +unsigned int CZoneTest::DetectionFunctionsConfigChanged(CZTDetectionFunctionConfig *NewConfig) +{ + *mZTSettings->mDetectionFunctionSettings = *NewConfig; + mZTSettingsFileMgr.SaveSettings(mZTSettings); + mEventMgr->UpdateEvents(mZTSettings->mDetectionFunctionSettings); + + return RET_OK; +} + +/////Messages from Logs list page +void CZoneTest::LogViewRequest(CLogElement *element) +{ + panel.mLogsListPage->hide(); + panel.mZTMainPage->hide(); + + panel.mLogViewPage->SetLogData(element); + panel.mLogViewPage->show(); + +} + +QString CZoneTest::GetStationShortName() +{ + return mZTStation->GetStationShortName(); +} + +QString CZoneTest::GetStationTextualName() +{ + return mZTStation->GetStationTextualName(); +} + +/// Messages from logs display page +void CZoneTest::LogViewCloseRequest() +{ + panel.mLogViewPage->hide(); + panel.mLogsListPage->show(); + panel.mZTMainPage->show(); + +} + +/// Messages from engineering page +void CZoneTest::OpenEngineeringPageRequest() +{ + panel.mOptionsPage->hide(); + panel.mEngineeringPage->ShowPage(); +} + +void CZoneTest::CloseEngineeringPageRequest() +{ + panel.mEngineeringPage->hide(); +// panel.mOptionsPage->show(); +} + +void CZoneTest::SaveAutoExportCSVSettings(bool AutoExportZT1CSV, bool AutoExportZT2CSV) +{ + mZTSettings->mAutoExportZT1CSV = AutoExportZT1CSV; + mZTSettings->mAutoExportZT2CSV = AutoExportZT2CSV; + mZTSettingsFileMgr.SaveSettings(mZTSettings); + + mZTStateMachine->SetAutoExportZT1CSV(AutoExportZT1CSV); + mZTStateMachine->SetAutoExportZT2CSV(AutoExportZT2CSV); +} + +void CZoneTest::TrainFilesChanged() +{ + mLogMgr->ParseLogs(); +} + +bool CZoneTest::StartPGCalibrationRequest(int NbPassages) +{ + if(mZTStateMachine->EnterPGCalibrationMode(NbPassages) == true) + { + mEventMgr->AddSingleEvent(EVENT_CA_PG); + return true; + } + + return false; +} + +bool CZoneTest::StopPGCalibrationRequest() +{ + if(mZTStateMachine->QuitPGCalibrationMode() == true) + { + mEventMgr->RemoveSingleEvent(EVENT_CA_PG); + return true; + } + + return false; + +} + +void CZoneTest::HighResLogging(bool HighResON) +{ + mZTStateMachine->SetLogResolution(HighResON); +} + +int CZoneTest::GetPGTreshold() +{ + return mZTSettings->mPGTreshold; +} + +void CZoneTest::KeepAllMPM10Logs(bool Keep) +{ + mZTSettings->mKeepMPM10Logs = Keep; + mZTSettingsFileMgr.SaveSettings(mZTSettings); + mLogMgr->KeepAllMPM10Logs(Keep); +} + +void CZoneTest::SetLogFilesNumber(int NbLogFiles) +{ + mZTSettings->mMaxLogCount = NbLogFiles; + mZTSettingsFileMgr.SaveSettings(mZTSettings); + mLogMgr->SetMaxLogFilesCount(NbLogFiles); +} + +void CZoneTest::KeepAllZT1Logs(bool keep) +{ + mZTSettings->mKeepAllZT1Logs = keep; + mZTSettingsFileMgr.SaveSettings(mZTSettings); + mLogMgr->KeepAllZT1Logs(keep); +} +void CZoneTest::KeepAllZT2Logs(bool keep) +{ + mZTSettings->mKeepAllZT2Logs = keep; + mZTSettingsFileMgr.SaveSettings(mZTSettings); + mLogMgr->KeepAllZT2Logs(keep); +} + + +unsigned int CZoneTest::SetPGTreshold(int NewTreshold) +{ + mZTStateMachine->SetPGTreshold(NewTreshold); + if(mSimulationON) + mZTSimulator->SetPGTreshold(NewTreshold); + mZTSettings->mPGTreshold = NewTreshold; + mZTSettingsFileMgr.SaveSettings(mZTSettings); + + return RET_OK; +} + +///Messages from Maintenance page +bool CZoneTest::EnterMaintenanceModeRequest() +{ + if(mZTStateMachine->EnterMaintenanceMode() == RET_OK) + { + mEventMgr->AddSingleEvent(EVENT_MAINTENANCE); + return true; + } + else + return false; +} + +void CZoneTest::ExitMaintenanceModeRequest() +{ + mWatchdogEnabled = true; + mZTStateMachine->QuitMaintenanceMode(); + mEventMgr->RemoveSingleEvent(EVENT_MAINTENANCE); +} + +unsigned int CZoneTest::ClearMaintenanceCurTKRequest() +{ + return mZTStateMachine->ClearMaintenanceCurrentTK(); +} + +unsigned int CZoneTest::SendTKToPCC(int DetectionID, int Rank) +{ + return mZTStateMachine->SendTKToPCC(DetectionID,Rank); +} + +//THIS IS NOT FOR CPU WATCHDOG BUT FOR EXTERNAL WATCHDOG "VIGIE" INSIDE THE T.A. +void CZoneTest::SetWatchdogEnabled(bool Enabled) +{ + mWatchdogEnabled = Enabled; + mExtIOWorkerThread->ClearOutputFlags(mZTStation->GetOutputMasks()->OutputWatchdogMask); + +} + +void CZoneTest::CloseMaintenancePageRequest() +{ + panel.mMaintenancePage->hide(); + panel.mOptionsPage->show(); +} + +///Messages from general settings page +void CZoneTest::OpenGeneralSettingsPage() +{ + panel.mGeneralSettingsPage->show(); + panel.mOptionsPage->hide(); +} + +void CZoneTest::CloseGeneralSettingsPage() +{ + panel.mGeneralSettingsPage->hide(); +} + + +///Messages from ZTLog viewer page +void CZoneTest::ShowZTLogViewerPage() +{ + panel.mZTLogViewerPage->show(); + panel.mOptionsPage->hide(); +} + +void CZoneTest::HideZTLogViewerPage() +{ + panel.mZTLogViewerPage->hide(); +} + +void CZoneTest::ResetTriggerCount() +{ + mZTStateMachine->ResetNbTriggers(); +} + +void CZoneTest::ResetNbPassages() +{ + mZTStateMachine->ResetNbPassages(); +} + +void CZoneTest::LogZTSettingsRequest(bool LogStationName) +{ + mZTSettingsFileMgr.LogSettings(mZTSettings,LogStationName); +} + +void CZoneTest::CheckAndCreateDirectories() +{ + QDir dir("./Trains"); + if(dir.exists() == false) + { + QDir().mkdir("./Trains"); + } + + dir = QDir("./ING"); + if(dir.exists() == false) + { + QDir().mkdir("./ING"); + } + + dir = QDir("./LOG"); + if(dir.exists() == false) + { + QDir().mkdir("./LOG"); + } + + dir = QDir("./Configuration"); + if(dir.exists() == false) + { + QDir().mkdir("./Configuration"); + } +} + +///Messages from network interface +CTCPZTStatus *CZoneTest::GetTCPStatusRequest() +{ + CTCPZTStatus *status = new CTCPZTStatus; + + status->mZT1Status = (quint32)mZTStateMachine->GetZT1ActiveStatus(); + status->mZT2Status = (quint32)mZTStateMachine->GetZT2ActiveStatus(); + status->mNbPass = (quint32)mZTStateMachine->GetNbPassages(); + status->mNbTrigs = (quint32)mZTStateMachine->GetNbTriggers(); + + status->mZTStartDateTime = mZTStartDateTime; + status->mActualDateTime = QDateTime::currentDateTime(); + + status->mPGTreshold = (qint32)mZTSettings->mPGTreshold; + + status->mModeMaintenanceON = mZTStateMachine->IsInMaintenance(); + status->mCalibModeON = mZTStateMachine->IsInPGCalibration(); + + status->mFNTKActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].TKActive; + status->mFNAnalysisActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive; + status->mPGTKActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].TKActive; + status->mPGAnalysisActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive; + status->mPP1TKActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].TKActive; + status->mPP1AnalysisActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive; + status->mPP2TKActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive; + status->mPP2AnalysisActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive; + status->mZT1TKActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive; + status->mZT1AnalysisActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive; + status->mZT2TKActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive; + status->mZT2AnalysisActive = mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive; + + status->mUSBKeyConnected = mUSBDriveInterface->IsDriveDetected(); + + return status; //HAVE TO BE DELETED BY CALLER !!! +} + +QString *CZoneTest::GetZTLogTextRequest() +{ + QString *string = new QString(CZTLog::instance()->GetEntireLogFile()); + return string; //HAVE TO BE DELETED BY CALLER !!! +} + +QFileInfoList CZoneTest::GetTrainLogsFileListRequest() +{ + return mLogMgr->GetLogsFilenameList(); +} + +unsigned int CZoneTest::DeleteZTLogRequest() +{ + return CZTLog::instance()->DeleteLogFile(); +} + +unsigned int CZoneTest::PauseInternalWatchdog() +{ + mInternalWatchdog->StopWatchdog(); + return RET_OK; +} + +unsigned int CZoneTest::ResumeInternalWatchdog() +{ + mInternalWatchdog->StartWatchdog(); + return RET_OK; +} + +bool CZoneTest::IsZT2PresentInStation() +{ + return mZTStation->StationHasZT2(); +} + +unsigned int CZoneTest::SetZTFunctionsConfig(const CTCPZTFunctionsStatus &FunctionsConfig) +{ + if(FunctionsConfig.mZT1AnalysisActive != mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive) + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive = FunctionsConfig.mZT1AnalysisActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive = FunctionsConfig.mZT1AnalysisActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive = FunctionsConfig.mZT1AnalysisActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].AnalysisActive = FunctionsConfig.mZT1AnalysisActive; + + } + else + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].AnalysisActive = FunctionsConfig.mFNAnalysisActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].AnalysisActive = FunctionsConfig.mPGAnalysisActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].AnalysisActive = FunctionsConfig.mPP1AnalysisActive; + } + if(FunctionsConfig.mZT2AnalysisActive != mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive) + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive = FunctionsConfig.mZT2AnalysisActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].AnalysisActive = FunctionsConfig.mZT2AnalysisActive; + } + else + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].AnalysisActive = FunctionsConfig.mPP2AnalysisActive; + } + + + if(FunctionsConfig.mZT1TKActive != mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive) + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].TKActive = FunctionsConfig.mZT1TKActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].TKActive = FunctionsConfig.mZT1TKActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].TKActive = FunctionsConfig.mZT1TKActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT1].TKActive = FunctionsConfig.mZT1TKActive; + } + else + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_FN].TKActive = FunctionsConfig.mFNTKActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PG].TKActive = FunctionsConfig.mPGTKActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP].TKActive = FunctionsConfig.mPP1TKActive; + } + if(FunctionsConfig.mZT2TKActive != mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive) + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive = FunctionsConfig.mZT2TKActive; + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_ZT2].TKActive = FunctionsConfig.mZT2TKActive; + } + else + { + mZTSettings->mDetectionFunctionSettings->mZTDetectionConfig[DETECTION_FCT_PP2].TKActive = FunctionsConfig.mPP2TKActive; + } + + mZTSettingsFileMgr.SaveSettings(mZTSettings); + panel.mFunctionSelectPage->SetConfig(mZTSettings->mDetectionFunctionSettings); + mEventMgr->UpdateEvents(mZTSettings->mDetectionFunctionSettings); + + + return RET_OK; +} + + +void CZoneTest::ApplicationQuit(bool PowerButton) +{ + mExtIOWorkerThread->SetOutput((quint32)0); + mExtIOWorkerThread->StopAcquisition(); + + //Wait for the thread to stop + while(mExtIOWorkerThread->IsThreadRunning() == true) + { + usleep(1000); + } + +// if(mDI710Module != 0) +// { +// mDI710Module->StopThread(); +// while(mDI710Module->IsThreadRunning() == true) +// { +// usleep(1000); +// } +// } +// mDataQThread->quit(); +// if(mDataQThread->wait(1000) == false) +// { +// qDebug("DataqThread wait = false"); +// } + + + if(PowerButton == false) + mZtState = ZT_EXIT_APPLICATION_STATE; + else + mZtState = ZT_POWER_BUTTON_EXIT_STATE; + + + + // qDebug("Creating escape file..."); + system("echo exit > ./Escape.ZT"); //Crée un fichier vide pour informer le script de ne pas redémarrer l'application + system("sync"); + + mExtIOThread->quit(); + if(mExtIOThread->wait(1000) == false) + { + qDebug("ExtIOThread wait = false"); + } + +} + +void CZoneTest::ACPISocketConnected() +{ + CEngLog::instance()->AddLogString("Socket ACPI connecté"); +} + +void CZoneTest::ACPISocketEvent() +{ + + QString Res(mACPISocket.readAll()); + if(Res.contains("button/power")) + { + CZTLog::instance()->AddLogString("Activation du bouton << Power >>, sortie du programme",true); + mACPISocket.close(); + ApplicationQuit(true); + } + else + { + Res.prepend("Événement ACPI inconnu: "); + CZTLog::instance()->AddLogString(Res); + } +} + + + + + + + + + + diff --git a/sources/Zonetest.h b/sources/Zonetest.h new file mode 100644 index 0000000..08cf62b --- /dev/null +++ b/sources/Zonetest.h @@ -0,0 +1,223 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Description du fichier si nécessaire. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ + +#ifndef ZONETEST_H +#define ZONETEST_H +#include "MainPanel.h" +#include "Station.h" +#ifndef WINDOWS_OS +#include "Seaiolibinterface.h" +#include "ExternalIOMgr.h" +#include "Comedilibinterface.h" +#endif + +#include +#include +#include +#include + +#include "WelcomePage.h" +#include "LazerProbesMgr.h" +#include "ZTStateMachine.h" +#include "ZTSimulator.h" +#include "IOManager.h" +#include "PCIIOMgr.h" +#include "ZTData.h" +#include "EventMgr.h" +#include "LogMgr.h" +#include "ZTSettings.h" +#include "USBDriveInterface.h" +#include "ExtIOThread.h" +#include "DI710Driver.h" +#include "WatchdogCtrl.h" +#include "DiscreteTKTransport.h" +#include "ModbusRepository.h" +#include "ModbusCCMgr.h" + +#include "TCPProtocol.h" + + +class CZoneTest : public QObject +{ + Q_OBJECT +public: + CZoneTest(); + ~CZoneTest(); + + unsigned int Run(); + unsigned int Start(); + + bool mFullScreen; + bool mSimulateLazerProbes; + bool mIgnoreStationPhysicalKey; + bool mDisablePassword; + bool mUseWatchdog; //internal CPU watchdog + + CWelcomePage *mWelcomePagePtr; + + void ZTFunctionsOptionSelected(); + void ZTMaintenanceOptionSeleced(); + void OptionsMenuPageSelected(); + void LogsPageSelected(); + unsigned int DetectionFunctionsConfigChanged(CZTDetectionFunctionConfig *NewConfig); + + + void LogViewRequest(CLogElement* element); + QString GetStationShortName(); + QString GetStationTextualName(); + + void LogViewCloseRequest(); + void OpenEngineeringPageRequest(); + void CloseEngineeringPageRequest(); + void TrainFilesChanged(); + void SaveAutoExportCSVSettings(bool AutoExportZT1CSV, bool AutoExportZT2CSV); + bool StartPGCalibrationRequest(int NbPassages); + bool StopPGCalibrationRequest(); + int GetPGTreshold(); + unsigned int SetPGTreshold(int NewTreshold); + void HighResLogging(bool HighResON); + void ProgramExitRequest(); + void KeepAllMPM10Logs(bool Keep); + void KeepAllZT1Logs(bool keep); + void KeepAllZT2Logs(bool keep); + void SetLogFilesNumber(int NbLogFiles); + + bool EnterMaintenanceModeRequest(); + void CloseMaintenancePageRequest(); + void ExitMaintenanceModeRequest(); + unsigned int ClearMaintenanceCurTKRequest(); + unsigned int SendTKToPCC(int DetectionID, int Rank); + void SetWatchdogEnabled(bool Enabled); + + void OpenGeneralSettingsPage(); + void CloseGeneralSettingsPage(); + + void ShowZTLogViewerPage(); + void HideZTLogViewerPage(); + + void ResetTriggerCount(); + void ResetNbPassages(); + + void LogZTSettingsRequest(bool LogStationName = false); + + void ApplicationQuit(bool PowerButton = false); + + unsigned int PauseInternalWatchdog(); + unsigned int ResumeInternalWatchdog(); + + bool IsZT2PresentInStation(); + + + + //Networking requests + CTCPZTStatus *GetTCPStatusRequest();//HAVE TO BE DELETED BY CALLER !!! + QString *GetZTLogTextRequest();//HAVE TO BE DELETED BY CALLER !!! + QFileInfoList GetTrainLogsFileListRequest(); + unsigned int DeleteZTLogRequest(); + unsigned int SetZTFunctionsConfig(const CTCPZTFunctionsStatus &FunctionsConfig); + + + + + +private: + unsigned int InitZT(); + unsigned int InitStation(); + void EnterDeadlockState(void); + void CheckAndCreateDirectories(); + + Panel panel; + + CStation *mZTStation; //The instance of the station in which the ZT is installed. + CIOManager *mIOManager; + CPCIIOMgr *mPCIIO; + CExtIOThread *mExtIOWorkerThread; + QThread *mExtIOThread; + CAbstractLazerProbeMgr *mLazerProbesManager; + CZTStateMachine *mZTStateMachine; + CZTSimulator *mZTSimulator; + CEventMgr *mEventMgr; + CLogMgr *mLogMgr; + CZTSettingsFileMgr mZTSettingsFileMgr; + QElapsedTimer mWatchdogTimer; + COutputModule *mOutputModule; + CUSBDriveInterface *mUSBDriveInterface; + QDateTime mZTStartDateTime; + CAnalogInputModule *mAnalogModule; + CWatchdogCtrl *mInternalWatchdog; + bool mWatchdogEnabled; + CTKTransportInterface *mTKTransportInterface; + CModbusRepository *mCCModbusRepository; + CModbusCCMgr *mModbusCCMgr; + + QLocalSocket mACPISocket; + // CWatchdogCtrl mWatchdogCtrl; + + + + + + //Zone test main state machine + typedef enum eZTStates + { + ZT_INIT_STATE, + ZT_RUN_STATE, + ZT_DEADLOCK_STATE, + ZT_EXIT_APPLICATION_STATE, + ZT_POWER_BUTTON_EXIT_STATE, + ZT_MAX_STATE + }eZTSMStates_t; + + typedef enum eZTSMEvents + { + ZT_SM_TICK_EVENT, + ZT_SM_MAX_EVENT + }eZTSMEvents_t; + + eZTSMStates_t mZtState; + unsigned int ExecStateMachine(eZTSMEvents_t); + QTimer *mZTStateMachineTimer; + + //CZTDetectionFunctionConfig *mZTDetectionConfig; + CZTSettingsData *mZTSettings; + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + bool mSimulationON; + +public slots: + void SMTimerExpired(); + void ACPISocketConnected(); + void ACPISocketEvent(); + + + // CSeaIOLibInterface mSeaIOLibInterface; +}; + +#endif // ZONETEST_H diff --git a/sources/main.cpp b/sources/main.cpp new file mode 100644 index 0000000..aac4e76 --- /dev/null +++ b/sources/main.cpp @@ -0,0 +1,94 @@ +/******************************************************************************* +* * +* Société de Transports de Montréal. * +* 2012 * +* * +* Projet Zones Tests * +* * +* * +* * +*******************************************************************************/ +/* + Description: + Le main. + +*/ + +/* ************************************************************************** */ +/* Revision: +### 20121210 JFM + Verision d'origine. + +### YYYYMMDD Description du besoin ou du bug + Description du changement. + */ + +/* ************************************************************************** */ +#include +#include "Zonetest.h" +#include "MainPanel.h" +#include + +int main(int argc, char *argv[]) +{ + + QApplication::setGraphicsSystem("raster"); + //Qt Mainframe application instance. + QApplication a(argc, argv); + + QFont serifFont("Times", 10, QFont::Bold); + QApplication::setFont(serifFont); + + //Create program instance + CZoneTest ZoneTest; + + + bool FullScreen = true; + bool SimulLazerProbes = false; + bool IgnoreStationKey = false; + bool DisablePassword = false; + bool UseWatchdog = true; + + for ( int i = 1 ; i < argc ; i ++ ) + { + // qDebug("%d %s",i,argv[i]); + if ( strcmp(argv[i],"-windowed") == 0 ) + { + FullScreen = false; + } + else if ( strcmp(argv[i],"-simullazer") == 0 ) + { + SimulLazerProbes = true; + } + else if ( strcmp(argv[i],"-ignorekey") == 0 ) + { + IgnoreStationKey = true; + } + else if ( strcmp(argv[i],"-disablepassword") == 0 ) + { + DisablePassword = true; + } + else if ( strcmp(argv[i],"-disablewatchdog") == 0 ) + { + UseWatchdog = false; + } + } + + ZoneTest.mFullScreen = FullScreen; + ZoneTest.mSimulateLazerProbes = SimulLazerProbes; + ZoneTest.mIgnoreStationPhysicalKey = IgnoreStationKey; + ZoneTest.mDisablePassword = DisablePassword; + ZoneTest.mUseWatchdog = UseWatchdog; + + + //setup stdout for screen printing. + setvbuf(stdout, NULL, _IONBF, 0 ); + + //Run Zone Tests + ZoneTest.Start(); + + + return a.exec(); + + +}