Premier commit suite au crash du repo le 10 juillet 2017

This commit is contained in:
zonetest 2017-07-11 09:18:32 -04:00
commit d08fe76884
267 changed files with 43069 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/LOG/LogZT.txt
/ING/IngLog.txt
/sources/TKGenerator.cpp.autosave
/.svn
*.o
ZT.pro.user
/Debug
/Release
moc_*.*
/Trains
*.Autosave

2
ChangeOwner Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
sudo chown -R zonetest:zonetest ./*

81
Configuration/ZT.cfg Normal file
View File

@ -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

1
Configuration/ZT.pwd Normal file
View File

@ -0,0 +1 @@
zonetest

Binary file not shown.

BIN
Configuration/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

1
Escape.ZT Normal file
View File

@ -0,0 +1 @@
exit

46
FTPGetSources.sh Normal file
View File

@ -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

14
GetSources.sh Executable file
View File

@ -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

BIN
Images/GuiBackground.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
Images/Play Normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
Images/Save-icon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
Images/Slider_Green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
Images/Slider_Red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
Images/green-led-off-md.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
Images/green-led-on-md.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
Images/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
Images/open-file-icon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
Images/pushbutton-green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
Images/red-led-off-md.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
Images/red-led-on-md.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
Images/tools.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

26
LicTemplate.txt Normal file
View File

@ -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.
*/
/* ************************************************************************** */

1496
Makefile Normal file

File diff suppressed because one or more lines are too long

39
SeaMaxLinux/Makefile Normal file
View File

@ -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

Binary file not shown.

122
SeaMaxLinux/cethernet.h Normal file
View File

@ -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__

586
SeaMaxLinux/seamaxlin.h Normal file
View File

@ -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
*
* <b>WARNING! This document is intended for internal use only.</b>
*/
#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 <b>\ref group_seamax_all</b><br>
* The foundation of SeaMAX with functions for configuring, interfacing,
* and modifying supported Sealevel digital I/O modules and devices.
* \li <b>\ref group_cethernet_all</b><br>
* The Ethernet module contains functions related to the discovery and
* configuration of Sealevel I/O devices with an Ethernet interface.
* \li <b>\ref modbusbreakdown</b><br>
* 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__

356
SeaMaxLinux/thirdparty/ftdi.h vendored Normal file
View File

@ -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 <usb.h>
#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__ */

50
StartZT Executable file
View File

@ -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

BIN
ZT Executable file

Binary file not shown.

296
ZT.pro Normal file
View File

@ -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

3
setztexecutable Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
sudo chown root:root ZT
#sudo chmod +s ZT

View File

@ -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()
{
}

View File

@ -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 <QString>
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

View File

@ -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()
{
}

View File

@ -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

View File

@ -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()
{
}

View File

@ -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

104
sources/CDV.cpp Normal file
View File

@ -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;
}

81
sources/CDV.h Normal file
View File

@ -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

31
sources/CStation.cpp Normal file
View File

@ -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()
{
}

39
sources/CStation.h Normal file
View File

@ -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

View File

@ -0,0 +1,786 @@
#include "DiscreteTKTransport.h"
#include "EngLog.h"
#include "ZTLog.h"
#include <QTextStream>
#include "ZTData.h"
#include <QTextCodec>
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;
}

View File

@ -0,0 +1,101 @@
#ifndef DISCRETETKTRANSPORT_H
#define DISCRETETKTRANSPORT_H
#include "TKTransportInterface.h"
#include "OutputModule.h"
#include "Station.h"
#include <QTimer>
#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<CZTDetectionData> 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

152
sources/EngLog.cpp Normal file
View File

@ -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) 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 <QDateTime>
#include <QString>
#include "RamMonitor.h"
#include <QFileInfo>
//#include <QTextCodec>
//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;
}

61
sources/EngLog.h Normal file
View File

@ -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 <QFile>
#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

36
sources/Event.cpp Normal file
View File

@ -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;
}

45
sources/Event.h Normal file
View File

@ -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

176
sources/EventMgr.cpp Normal file
View File

@ -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;
}

78
sources/EventMgr.h Normal file
View File

@ -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 <QList>
#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<CEvent*> 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<CEvent*>*);
};
#endif // EVENTMGR_H

322
sources/ExtIOThread.cpp Normal file
View File

@ -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;
}

133
sources/ExtIOThread.h Normal file
View File

@ -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 <QElapsedTimer>
#ifndef EXTIOTHREAD_H
#define EXTIOTHREAD_H
#include <QObject>
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<COutputTransaction> mOutputTransactionList;
signals:
public slots:
void DoAcquisition();
};
#endif // EXTIOTHREAD_H

View File

@ -0,0 +1,402 @@
#include "DI710Driver.h"
#include <QDebug>
#include <QElapsedTimer>
#include <iostream>
#include <cstring> // Needed for memset
#include <sys/socket.h> // Needed for the socket functions
#include <netdb.h> // Needed for the socket functions
#include <unistd.h>
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;
}

View File

@ -0,0 +1,82 @@
#ifndef DI710DRIVER_H
#define DI710DRIVER_H
#include "GlobalDefine.h"
//#include <QObject>
#include <QTcpSocket>
#include <QReadWriteLock>
#include <QUdpSocket>
#include <AnalogInputModule.h>
#include <iostream>
#include <sys/socket.h>
#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

View File

@ -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<stExtModulesConfig_t> * 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;
}
}
}

View File

@ -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<CExternalIOModule*> mExternalModulesList;
#endif
};
#endif // EXTERNALIOMGR_H

View File

@ -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 <QtGlobal>
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

View File

@ -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

View File

@ -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 <string.h>
#include <QDebug>
#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;
}

View File

@ -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 <QMutex>
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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 <QString>
class CSeaIOLibInterface
{
public:
CSeaIOLibInterface();
~CSeaIOLibInterface();
unsigned int OpenSeaMaxInterface(QString MasterModuleIP);
CSeaMaxLin * GetSeaMaxInterfacePtr(void);
void CloseSeaMaxInterface();
private:
CSeaMaxLin mSeaMaxInterface;
bool mIsOpened;
};
#endif // SEAIOLIBINTERFACE_H

View File

@ -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

View File

@ -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 <QString>
#include <QDebug>
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<DeviceTreeNode> *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;
}

View File

@ -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 <bdaqctrl.h>
#include "GlobalDefine.h"
#include "AnalogInputModule.h"
#include <QMutex>
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

84
sources/GlobalDefine.h Normal file
View File

@ -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 <stdio.h>
#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

View File

@ -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 <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <limits>
#include <QStyleOptionGraphicsItem>
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<CGraphAnalogDataPair*> *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<float>::min();
qreal MinValue = std::numeric_limits<float>::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)
{
}

View File

@ -0,0 +1,60 @@
#ifndef ANALOGGRAPHITEM_H
#define ANALOGGRAPHITEM_H
#include <GlobalDefine.h>
#include <QGraphicsWidget>
#include <QRect>
#include <QTimeLine>
#include <QList>
#include <QPainterPath>
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<CGraphAnalogDataPair*> *mDataSet;
QGraphicsRectItem *mBackgroundRect;
unsigned int DisplayData(quint64 StartTime, quint64 StopTime);
void SetData(QList<CGraphAnalogDataPair*> *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<QLine> mLinesList;
QString mLabelTitle;
QGraphicsTextItem *mLabel;
QPixmap *mGraphPixmap;
qreal mYScaling,mXScaling;
qreal mYOffset;
qreal mHorizLineYPos;
QLine *mHorizLine;
QPainterPath mPainterPath;
};
#endif // ANALOGGRAPHITEM_H

View File

@ -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 <QPainter>
#include "ZTData.h"
#include <QGraphicsSceneMouseEvent>
#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;
}

View File

@ -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 <QGraphicsWidget>
#include <QString>
#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

File diff suppressed because it is too large Load Diff

View File

@ -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 <QGraphicsWidget>
#include "Guipage.h"
#include <QString>
#include "PushButton.h"
#include "ZTSimulator.h"
#include "TextButtonWidget.h"
#include "InputModule.h"
#include "PCIIOMgr.h"
#include "PasswordPrompt.h"
#include "ZTData.h"
#include <QCheckBox>
#include <QFileInfoList>
#include "USBDriveInterface.h"
#include "ToggleButtonWidget.h"
#include <QSpinBox>
#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<CCDV*> *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<CLedWidget*> 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

View File

@ -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 <QPainter>
#include "ZTData.h"
#include <QGraphicsSceneMouseEvent>
#include "CDV.h"
#include <QPoint>
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();
}

View File

@ -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 <QGraphicsWidget>
#include <QString>
#include <QTimeLine>
#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

View File

@ -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 <QPainter>
#include <QPen>
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();
}

View File

@ -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 <QGraphicsWidget>
#include <QList>
#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<CEvent*> *mEventsList;
void UpdateEventsList();
private:
QList<CEventItem*> mEventsItemList;
void UpdateDisplay();
};
#endif // EVENTSBAR_H

View File

@ -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 <QPainter>
#include <QTextStream>
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();
}

View File

@ -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 <QGraphicsWidget>
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<CEventRulerWidgetItem> mEventItems;
};
#endif // RANKRULERWIDGET_H

View File

@ -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 <QFont>
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)
}

View File

@ -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 <QGraphicsWidget>
#include "Guipage.h"
#include <QString>
#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

View File

@ -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 <QPainter>
#include "GlobalDefine.h"
#include <QDialog>
#include <QMainWindow>
#include "Zonetest.h"
#include <QDateTime>
#include <QFont>
#include <QGraphicsProxyWidget>
#include <sys/time.h>
#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)
}

View File

@ -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 <QGraphicsWidget>
#include "Guipage.h"
#include <QString>
#include "PushButton.h"
#include "ZTSimulator.h"
#include "TextButtonWidget.h"
#include <QCalendarWidget>
#include <QTimeEdit>
#include <QSpinBox>
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

View File

@ -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 <QPen>
#include <QPainter>
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;
}

View File

@ -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 <QGraphicsWidget>
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

View File

@ -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 <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QStyleOptionGraphicsItem>
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<CGraphDiscreteDataPair*> *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)
{
}

View File

@ -0,0 +1,56 @@
#ifndef CGRAPHITEM_H
#define CGRAPHITEM_H
#include <GlobalDefine.h>
#include <QGraphicsWidget>
#include <QRect>
#include <QTimeLine>
#include <QList>
#include <QPainterPath>
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<CGraphDiscreteDataPair*> *mDataSet;
QGraphicsRectItem *mBackgroundRect;
// unsigned int DisplayData(quint32 StartIndex, quint32 StopIndex);
unsigned int DisplayData(quint64 StartTime, quint64 StopTime);
void SetData(QList<CGraphDiscreteDataPair*> *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<QLine> mLinesList;
QGraphicsTextItem *mLabel;
QPixmap *mGraphPixmap;
};
#endif // CGRAPHITEM_H

View File

@ -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 <QPainter>
#include <QTextStream>
#include <QStyleOptionGraphicsItem>
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);
}

View File

@ -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 <QGraphicsWidget>
#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

View File

@ -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 <QGraphicsWidget>
CGuiPage::CGuiPage()
{
}
void CGuiPage::ShowPage()
{
}

View File

@ -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 <QGraphicsWidget>
#include <QTimeLine>
#include "GlobalDefine.h"
class CGuiPage : public QGraphicsWidget
{
Q_OBJECT
public:
CGuiPage();
virtual void ShowPage();
};
#endif // GUIPAGE_H

View File

@ -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 <QFontMetrics>
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();
}

View File

@ -0,0 +1,25 @@
#ifndef LEDWIDGET_H
#define LEDWIDGET_H
#include "GlobalDefine.h"
#include <QGraphicsWidget>
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

File diff suppressed because it is too large Load Diff

View File

@ -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 <QGraphicsWidget>
#include "Guipage.h"
#include <QString>
#include "PushButton.h"
#include "TextButtonWidget.h"
#include "LogMgr.h"
#include <QTableWidget>
#include "GraphItem.h"
//#include "qcustomplot.h"
#include "GraphCursorWidget.h"
#include "GraphRulerWidget.h"
#include "AnalogGraphItem.h"
#include "RankRulerWidget.h"
#include "EventsRulerWidget.h"
#include <QElapsedTimer>
#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<CGraphDiscreteDataPair*> *mDataSet;
CGraphItem *mPlotGaph;
};
class CAnalogPlottableItem
{
public:
unsigned int mParamID;
QList<CGraphAnalogDataPair*> *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

View File

@ -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 <QGraphicsProxyWidget>
#include "Zonetest.h"
#include "TrainLogFileMgr.h"
#include <QString>
#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<QTableWidgetItem*> 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<CLogElement*> *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<QTableWidgetItem *> 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<CLogElement*> *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<CLogElement*> *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<CLogElement*> *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<CLogElement*> *LogsList = mLogMgrHandle->GetLogsList();
CLogElement *SelectedElement = LogsList->at(Selection);
ShowItemSummary(SelectedElement);
}
int CLogsListPage::GetCurSelectedItemIndexInTable()
{
QList<QTableWidgetItem*> 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();
}

Some files were not shown because too many files have changed in this diff Show More