#ifndef INTERFACE_H
#define INTERFACE_H

#include <QtPlugin>
#include <QStringList>

struct T_emp {
   // Fixdata from EMP:
   uint8_t shaft;      // = changer level
   uint16_t countryCode;
   uint8_t scale;
   uint8_t decimals;
   uint8_t coinValues[16];
   uint16_t routing;

   // Master specs:
   uint8_t gotSetup;       // 1: got specifications from master   0: no specs
   uint16_t coinAccept;    //  bit 0 = coin1  bit H=accept
   uint8_t tokenChannel;
   uint16_t denomination[16];

   // dynamic:
   uint8_t state;      // step counter of EMP (electronic coin checker) FSM (finite state machine):
                       // 0=Emp & Bus power off,  1=powered, poll off    2=polling on
                       // 3=device responded, requesting status
                       // 4=waiting for status     5=have status,
                       // 6: IDLE,  have paramters from master, polling running, ready for payment
                       //          Master can stop/start polling and acceptance
                       // 7: end of transaction,  polling on, accept off, reporting coins, (wait for last coin)
                       // 8: transaction running, polling on, acceptance on, reporting coins,

   uint8_t pollingRunning;
   uint8_t paymentRunning;
};

struct Trtc_DateTime {
   uint8_t rtc_hour;
   uint8_t rtc_min;
   uint8_t rtc_sec;
   uint8_t rtc_dayOfMonth;
   uint8_t rtc_month;
   uint8_t rtc_year;
   uint8_t rtc_dayOfWeek;
};

struct Tprn_hw_state {
    // hardware (IO's)
    bool powerRdBk;     // prn pwr is on
    bool rsSwOk;        // serial switch (printer or modem) is set to printer
    bool rsDrvOk;       // RS232 converter for PTU, Printer and Modem in on

    bool ReadyLine;     // HW signal from printer showing ready
    bool inIdle;        // powered and free from errors
    bool paperNearEnd;  // paper roll runs out
    bool noPaper;
    bool ErrorTemp;
    bool HeadOpen;
    bool cutterJam;
    bool noResponse;    // printer is not connected, cable broken, wrong baudrate
    bool badResponse;
};

struct Tprn_currentSettings {
    uint8_t currFont;
    uint8_t currSize;
    uint8_t currHeigth;
    uint8_t currWidth;
    bool    nowBold;
    bool    nowInvers;
    bool    nowUnderlined;
    uint8_t currDensity;
    uint8_t currSpeed;
    bool    nowAligned;
};

struct T_dynDat {
    uint8_t licensePlate[8];
    uint8_t vendingPrice[8];
    uint8_t parkingEnd[8];
    uint8_t currentTime[8];
    uint8_t currentDate[8];
    uint8_t dynDat5[8];
    uint8_t dynDat6[8];
    uint8_t dynDat7[8];
};

struct T_vaultRecord {
    // Kassenbeleg (Abrechnungsdatensatz = Kassenwechsel-Datensatz)
    char startbuffer[4];		// Psa>  // never move or change this 1st entry
    uint16_t AccountingNumber;
    uint16_t CUNU;
    uint16_t MANU;
    uint16_t resint1;
    //uint16_t resint2;

    char label1buffer[4];	 // tim>
    uint8_t year;
    uint8_t month;
    uint8_t dom;
    uint8_t hour;
    uint8_t min;
    uint8_t sec;
    uint8_t DoW;
    uint8_t reschar3;

    char label2buffer[4];	// abs>
    uint32_t AbsIncome1;
    uint32_t AbsReserve;
    uint32_t AbsNrOfCuts;

//16
    char label3buffer[4];	// mw >

    // Verkauf, Tür zu:
    uint32_t VKcoinsInserted[16];		// nur für Wechsler, soviel wurde eingeworfen
    uint32_t VKcoinsReturned[6];		// nur für Wechsler, Anzahl Münzen pro Typ, soviel wurde zurückgegeben
//88
    // Service, Tür offen:
    uint16_t ServCoinsInserted[16];		// nur für Wechsler, soviel wurde eingeworfen
    uint16_t ServCoinsReturned[6];		// nur für Wechsler, Anzahl Münzen pro Typ, soviel wurde zurückgegeben
    uint16_t resint3;
    uint16_t resint4;
    uint16_t currentTubeContent[6];		//  nur für Wechsler, aktueller Füllstand
    uint16_t resint5;
    uint16_t resint6;
// 56
    char label4buffer[4];	// box>
    uint16_t coinsInVault[16];
    uint16_t billsInStacker[8];
// 48
    char label5buffer[4];	// val>
    // actually constant unless exchange rate is changed
    uint16_t coinDenomination[16];	// 5..50000 (z.B. 2? sind in Ungarn 760Ft)
    uint16_t billDenom[8];
    uint16_t tubeDenom[6];
    uint16_t exchangeRate;
    uint16_t resint9;
// 64
    char endofblock[4];	// end>
// 316 byte Block im Speicher
};

struct T_moduleCondition {
    // store conditon of all system components, hold in RAM
    // 0 means unknown, not yet tested/used
    // 1 means OK
    // 50..99	= HINT / Notification
    // 100..150	= WARNING
    // 200..250	= ERROR

    uint8_t	ram;
    uint8_t	intEe;
    uint8_t	extEe;

    uint8_t	rtc;				// 1: time/date OK   100: time not plausible  200: hardware error
    uint8_t	boardHw;
    uint8_t	printer;
    uint8_t	modem;

    uint8_t	signal;				//		1...99
    uint8_t	regist;				// 100:not  1:reg  2:ping OK   3:gotTime
    uint8_t	mdbBus;
    uint8_t	coinChecker;		// EMP, OMP or mei-cashflow

    uint8_t	coinEscrow;
    uint8_t	mifareReader;
    uint8_t	creditTerm;
    uint8_t	coinReject;

    uint8_t	coinSafe;
    uint8_t   billSafe;
    uint8_t	voltage;			// 1:11..14V
    uint8_t   temper;

    uint8_t	poweronTest;
    uint8_t   doorState;			// 1: alles zu  200: t?r offen + bit1(S) +bit2(CB) + bit3(CB)
    uint8_t	doorWasOpened;		// 1: all doors are closed   200: any door was just opened
    uint8_t	changer;			// can only be tested by usage

    uint8_t   coinBlocker;		// can only be tested by usage
    uint8_t   billReader;			// can only be tested by usage
    uint8_t   ResetReason;
    uint8_t	allModulesChecked;

};

struct T_dynamicCondition {
    char allDoorsDebounced;     // 99: undefined, 0=all closed, bit1=upper door open  2=midlle door open 3=lower door open
    char openedAuthorized;
    uint8_t CBinDebounced;
    char upperDoor;		// 99: undefined  0:closed  1:open
    char middleDoor;    // 99: undefined  0:closed  1:open
    char lowerDoor;     // 99: undefined  0:closed  1:open
    char reserve;       // not used, always 0
    char billBox;
    char modeAbrech;
    char onAlarm;       // 0:alarm aus  1:alarm  2:alarm mit Sirene   3: Sirenentest
    char nowCardTest;
    char nowPayment;
    char lastMifCardType;
    uint8_t lastSDoorState;
    uint8_t lastVDoorState;
    uint8_t lastCBstate;        // 99: undefined  0:not there   1:insered
    char        paymentInProgress;
    char        res1;
    uint16_t    U_Batt;
    uint16_t	Temperatur;
    uint16_t	nrCoinsInBox;
    uint32_t	amountInBox;
    uint32_t	totalTransVolume;
    uint32_t	totalNrOfVends;
    char        jsonValid_config;
    char        jsonValid_device;
    char        jsonValid_cash;
    char        jsonValid_print;
    char        jsonValid_serial;
    char        jsonValid_time;
    char        lastFileType;
// 44
    uint8_t     MifCardHolder[8];
    uint8_t     resultOfLastTemplPrint;
                // 0: unknown or printing in progress
                // 1: OK, doc was printed   2: error, doc was not printed
    uint8_t     lastPrinterStatus;
                //        0: printer OK
                //          bit0: near paper end          bit1: no paper
                //          bit2: temperature error       bit3: error head open
                //          bit4: paper jam in cutter
                //          bit6: no response             bit7: serial rec. error
                //			bit5: printer not ready
    uint8_t     startupTestIsRunning;
    //54
};

struct T_extTime {
    uint8_t     Hours;
    uint8_t     Min;
    uint8_t     Sec;
    uint8_t     Year;
    uint8_t     Month;
    uint8_t     Day;
    uint8_t     DOW;
    uint8_t     res1;
    uint16_t    MinOfDay;
    uint16_t    res2;
    uint32_t    SecOfDay;
    uint8_t     isLeapYear;
    uint8_t     nxtLeapYear;
    uint8_t     lastLeapYear;
    uint8_t     hoursOfThisWeek;
    uint16_t    minutesOfThisWeek;
    uint16_t    hoursOfThisMonth;
    uint16_t    daysOfThisYear;
    uint16_t    GetHoursOfYear;
    uint16_t    res3;
    uint32_t    GetMinutesOfYear;
    uint8_t     getWakeIntvSec;
    uint8_t     res4;
    uint16_t    res5;
    uint32_t    MinutesOfMillenium;
};

typedef uint8_t UCHAR;
typedef uint16_t UINT;

struct T_devices
{
    // set by master, used(1) or notused (0) or type 2....20

    UCHAR   kindOfPrinter;			// 0:off   1:Gebe
    UCHAR	kindOfCoinChecker;		// 0: without  1=EMP820   2=EMP900    3=currenza c²	(MW)
    UCHAR	kindOfMifareReader;		// by now only stronglink SL025 =1
    UCHAR   suppressSleepMode;		// 0:sleep allowed   1: no sleep

    UCHAR	kindOfModem;			// 0:off    1:Sunlink
    UCHAR	kindOfCreditcard;		// 0:off    1:Feig NFC
    UCHAR	CoinEscrow;
    UCHAR   CoinRejectUnit;

    UCHAR	CoinShutter;
    UCHAR	BillAcceptor;
    UCHAR	usevaultLock;
    UCHAR	autoAlarm;				// 1: switch on siren for 1min in doors opened unauthorized

    UCHAR	autoOpen;				// 1: open door covers after valid ATBcard
    UCHAR	printAccReceipt;		// 0/1
    UCHAR   printDoorReceipt;
    UCHAR   printTokenTicket;

    UINT	VaultFullWarnLevel;
    UINT	VaultFullErrorLevel;

};


class hwinf {
public:
    enum class DownloadResult {OK, ERROR, TIMEOUT, NOP};
    enum class FileTypeJson {CONFIG=1, DEVICE, CASH, SERIAL, TIME, PRINTER};

    virtual ~hwinf() {}
               
    virtual QStringList dc_getStatus() const = 0;
                                           
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    //       Use serial interface and protocol stack in Cashagent-Library
    //           Sending Output data to DeviceController DC2b
    //           Sending input requests to DC2 (single or auto-batch)
    //           Getting input data as receiver payload
    //      Furthermore the Cashagent-Library answers with status strings about sending and reading result
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const = 0;
        // Command: open serial interface
        // BaudNr:  0:1200   1:9600   2:19200   3:38400   4:57600   5:115200
        // BaudStr: for exapmle "19200"
        // ComName: for example "COM48"
        // connect: 0, 1

    virtual bool dc_closeSerial(void) const = 0;
        // Command: close serial interface in order to save power while power down
        // or if another port must be used
        
    virtual bool dc_isPortOpen(void) const =0;
        // returns true if port open (don't send unless open. Sending to closed port will crash program)
                   
        
        
    virtual uint8_t test_serialState(void) const =0;
        // test on-board signals for the serials
        // serial drv on/off, Serial mux1, Serial mux2
    
    virtual bool test_serialIsOn(void) const =0;      
        
    virtual bool dc_updateDC(QString binFileName,
                             QString baudrate,
                             QString comPort) const = 0;
        // download binary file down into device controller

    virtual bool dc_updatePrinterTemplate(enum FileTypeJson type,
                                          QVector<int> templateIdx,
                                          QVector<QString> fnames,
                                          QString br,
                                          QString serial = QString()) const = 0;

    virtual bool dc_printTemplate(enum FileTypeJson type,
                                  QVector<int> templateIdx,
                                  QString br,
                                  QString serial = QString()) const = 0;

    virtual void dc_autoRequest(bool on)  const =0;
        // on = true:  select that all READ-Requests are sent automatically 
        // on = false: select that all READ-Requests are sent manually one by one
                    // Every input information from DC2 must be requested 
                    // ( digital and analog sensors, get time/date, get status information )

    virtual uint8_t dc_isRequestDone(void)  const =0;
        // retval:  0: request is still in progress
        //          1: answer from DC2 was OK
        //          2: wrong answer from DC2

    virtual uint16_t dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad)  const =0;
        // get data back in "payLoad", max 64 byte, can be used for diagnosis
        // retval = nr of bytes received. If host buffer too small then
        // only plBufSiz bytes are copied to "payLoad"
        // plBufSiz­z=size of host buffer
                            
    virtual void dc_requTestResponse()  const =0;
        // tell DC2 to send a test-string, useful to see if cable and baudrate is OK
        
    virtual bool dc_readAnswTestResponse()  const =0;
        // retval: true: test was successful, got right response
                                                                 
    virtual uint8_t getRawRecLength(void)  const =0;
        // only needed if protocol stack in Cashagent-Library is bypassed
        
    virtual uint8_t getRawReceivedData(uint8_t *receivedData)  const =0;
        // only needed if protocol stack in Cashagent-Library is bypassed
    
    virtual QString dc_getSerialState(void)  const =0;   
        // get result of opening-command like "ttyS0 opened with 115200 8N1!
        // or error messages like "comport not available..."
        // was saved by last opening event, can be passed for 100ms
            
    virtual void dc_clrSerialStateText(void)  const =0;
        // clear above text to avoid multiple repetive displaying
        
        
    virtual QString dc_getTxt4HsStateLine(void)  const =0;  
        // return string with status of handshakes
    
    virtual void dc_clrTxt4HsStateLine(void)  const =0;    
        // clear above text to avoid multiple repetive displaying
        
                          
    virtual QString dc_getTxt4masterStateLine(void)  const =0;  
        // returns string telling if the received packet is valid and complies protocol
        // if OK: "slave response OK"    in case of error: "wrong length received", "wrong start sign received",
        //                              "received datalen to big", "wrong data len received", "wrong crc received"    
        
    virtual void dc_clrTxt4masterStateLine(void)  const =0;    
        // clear above text to avoid multiple repetive displaying
                           
               
    virtual QString dc_getTxt4resultStateLine(void)  const =0;   
       // returns string telling response of DC. First question: did DC get a correct request telegram?
       // and if: 2nd question did DC perform the contained output and input commands
       // if OK: "Slave OUT and IN Result: 0 0"
       // in case of error: "slave got wrong start sign" ..length"  ...crc"  ... address" 
       //                   slave does not perform and command!
       // 2nd) received telegram was OK, DC tried to perform the master commands. result
       //   result of writing data (e.g switching leds and motors, sending stuff to printer...)
       //      OUT = 0: OK   1: unknown command  2: operation not possible 
       // result of reading data (e.g. switches, voltages, accepted coins, printer status....)
       //       IN = 0: OK   1: unknown command   2: could not read due to hardware error  3: could not read because device is off  
                   
    virtual void dc_clrTxt4resultStateLine(void)  const =0;    
        // clear above text to avoid multiple repetive displaying

        
    virtual QString dc_getdataStateLine(void)  const =0; 
        // check if recveied input data are ok/valid
        // OK-string : "valid INdata...." with protocol details
        // not OK: string empty
    
    virtual void dc_clrTxt4dataStateLine(void)  const =0;
        // clear above text to avoid multiple repetive displaying
        
            
    virtual QString dc_getdatifLine(void)  const =0;
        // returns string with result of function dc_requTestResponse()
            // "correct" or "false"
    
    virtual void dc_clrTxt4datifLine(void)  const =0;
        // clear above text to avoid multiple repetive displaying

               
    virtual QString dc_getTxt4RsDiagWin(void)  const =0;
        // returns string to be displayed in "serial traffic" window 
        // details about sent and received protocol
                
    virtual void dc_clrTxt4RsDiagWin(void)  const =0;       
        // clear above text to avoid multiple repetive displaying
    
    virtual QString dc_get2ndTxt4RsDiagWin(void)  const =0;  
        // returns string to be displayed in "serial traffic" window 
        // details about sent and received protocol
    
    virtual void dc_clr2ndTxt4RsDiagWin(void)  const =0;    
        // clear above text to avoid multiple repetive displaying
    
    
// 28 functions    
                       
  
                                       
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    //       DC2b internal data 
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
 

    virtual QString dc_getSerialParams(void)  const =0;
        // get DC2 serial settings (not very meaningful as they will not come if different from master settings)
        
    virtual QString dc_getHWversion(void)  const =0;
       // get DC2 hardware version
       
    virtual QString dc_getSWversion(void)  const =0;
       // get DC2 software version
       
    virtual QString dc_getState(void)  const =0;
        // get DC2 status (every OK or any error/warning? )
                                                
    
    // UID - unique number, different in every DC
    virtual void     dc_getUID8byte(uint8_t *buf8byteUid)  const =0;
            // get 8 single bytes in buffer    
            
    virtual QString  dc_getUIDstr()  const =0;
            // get as string                            
        
    virtual uint64_t dc_getUIDnumber(void)  const =0;
            // get UID as one long number

    // Analog values:
    virtual uint32_t dc_getTemperature(void)  const =0;       
        // in Sax-Format 0...400 (0=-50,0°C    100=0,0°C    141=20,5°C    400=150,0°C)
    
    virtual QString  dc_getTemperaturStr(void)  const =0;
        // as string like "-12,5°C"
        
    virtual uint32_t dc_getVoltage(void)  const =0;           
        // as value in mV,  0...65,535V
        
    virtual QString  dc_getVoltagStr(void)  const =0;
        // as string in mV
        
    virtual bool dc_mainFuseIsOk(void) const=0;
        // true if 12V fuse is OK
        // false: fuse blown, DC will continue working but no 12V device can be used!
                                                                              
    virtual void dc_setWakeFrequency(uint8_t period)  const =0;
        // RTC wakes DC2 (and PTU) by hardware signal every 32seconds
        // change wake signal period to 1...64s

    virtual void dc_OrderToReset(void)  const =0;
        // want DC2 to reset (in order to start Bootloader)



    // all read-requests can be sent manually by the following functions
    //   or automatically in background by:   void hwapi::dc_autoRequest(bool on)
    //   in other words:
    //   if automatic-reading is on, then there's no need to send any of these commands,
    //    but it's allowed to send them in order to speed up the refreshing of the inputs

    virtual void request_DC2serialConfig()  const =0;
            // read-request can be sent manually by this function, not needed if auto-request is on

    virtual void request_DC2_HWversion() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_SWversion() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_condition() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_UID() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on


    virtual void request_DC2_analogues() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_digitalInputs() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    virtual void request_DC2_digitalOutputs() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on

// 22

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // using DC2 Bootloader   
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void bl_sendDataDirectly(uint8_t length, uint8_t *buf)  const =0;
        // send without protocol frame, needed for the DC bootloader

    virtual void bl_iniChain(void)  const =0;                             
    
    virtual bool bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl)  const =0;   
    
    virtual uint8_t bl_activatBootloader(uint8_t *sendData)  const =0; 
    
    virtual uint8_t bl_startChain(void)  const =0;     
    
    virtual uint8_t bl_readBLversion(uint8_t *sendData)  const =0;
        // minimum size of sendData-buffer: 5byte  retval: length 
        
    virtual uint8_t bl_readFWversion(uint8_t *sendData)  const =0;
        // minimum size of sendData-buffer: 5byte  retval: length

    virtual uint8_t bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf)  const =0;
        // make BL protocol, retval = outbuf length (5...133)
        // bring data in correct form: start always with 0x02   finish with 0x03 and append checksum
        // 0x02 Cmd < ...sendData ..>  CRC  CRC 0x03
        // Data length = 0...64
        // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes:  0x1B (=ESC) and data|0x80
        // so maxlength = 5 + 2 x 64 (if all data are 2 or 3)  without 2,3: maxlength = 5 + 64

    virtual uint8_t bl_exitBL(uint8_t *sendData)  const =0;
        // minimum size of sendData-buffer: 5byte  retval: length




// 9

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // get Time and Date from DC2b (contains a buffered real time clock) valid for about three days without power
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual uint8_t rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime)  const =0;

    virtual uint8_t rtc_setDateTime(void)  const =0;
        // synch DC2 with PC or PTU system time and date

    virtual void rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss)  const =0;
        // get time directly

    virtual void rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd)  const =0;
        // get date directly

    virtual uint8_t rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday)  const =0;
        // dow=day of week, 1=monday...7
        // minOfToday: 0=midnight...1439= 23:59
        // secOfToday: 0=midnight...86399= 23:59:59

    virtual bool rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear)  const =0;
        // retval true: this year is leap year

    virtual bool rtc_isLeapYear()  const =0;

    virtual void rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek)  const =0;
        // DayOfWeek: 1=monday...7
        // HoursOfWeek: 0=Monday 0:00 o'clock...167=Sunday 23:00
        // MinutesOfWeek: 0=Monday 0:00 o'clock...10079=Sunday 23:59

    virtual void rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth)  const =0;
        // DayOfMonth: 1...31
        // HoursOfMonth: 0 = 0:00o'clock of 1.day in month     up to 743
        // MinutesOfMonth:0 = 0:00o'clock of 1.day in month     up to 44639

    virtual void rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear)  const =0;
        // DayOfYear: 1...366  1= 1.Jan of this current year
        // HoursOfYear: 0=1.Jan 0:00o'clock ...8783=31.12 23 o'clock
        // MinutesOfYear: 0=1.Jan 0:00o'clock ...527039=31.12 23:59 o'clock

    virtual QString rtc_getTimStr(void)  const =0;
    virtual QString rtc_getDatStr(void)  const =0;
    virtual QString rtc_getTimDatStr(void)  const =0;
    

                              
    
    virtual void request_DC2_TimeAndDate() const =0;
        // read-request can be sent manually by this function, not needed if auto-request is on
    
    
    
// 14

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // PTU, Master
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void ptu_switchWake(bool WAKEACTIVE)  const =0;

    virtual bool ptu_WakeINisActive(void)  const =0;

    virtual bool ptu_WakeOutIsOn(void) const =0;

    virtual void sendDeviceSettings(uint8_t kindOfPrinter,      uint8_t kindOfCoinChecker,
                            uint8_t kindOfMifareReader, uint8_t suppressSleep,
                            uint8_t kindOfModem,        uint8_t kindOfCredit        ) const =0;
        // enable hardware in device controller:
        // kindOfPrinter:       0:off 1: GPT4672 (only this one implemented)
        // kindOfCoinChecker:   0:off 1:EMP820 2:EMP900 3: C²_changer
        // kindOfMifareReader:  0:off 1: SL025   (only this one implemented)
        // suppressSleep:       0:sleep allowed 1: sleep surpressed for special reason
        // kindOfModem:         0:off 1: ATB_Sunlink_LTE        (not yet implemented)
        // kindOfCredit:        0:off 1:  cVendTopp  2:cVendPin (not yet implemented)


    virtual void request_ReadbackDeviceSettings() const =0;

    virtual void readback_DeviceSettings(uint8_t *length, uint8_t *data) const =0;
/*
            buf66[0]=devPara.kindOfPrinter;
            buf66[1]=devPara.kindOfCoinChecker;
            buf66[2]=devPara.kindOfMifareReader;
            buf66[3]=devPara.suppressSleepMode;
            buf66[4]=devPara.kindOfModem;
            buf66[5]=devPara.kindOfCreditcard;
            buf66[6]=devPara.CoinEscrow;
            buf66[7]=devPara.CoinRejectUnit;
            buf66[8]=devPara.CoinShutter;
            buf66[9]=devPara.BillAcceptor;
            buf66[10]=devPara.usevaultLock;
            buf66[11]=devPara.autoAlarm;
            buf66[12]=devPara.autoOpen;
            buf66[13]=devPara.printAccReceipt;
            buf66[14]=devPara.printDoorReceipt;
            buf66[15]=devPara.printTokenTicket;
            uitmp=devPara.VaultFullWarnLevel;
            buf66[16]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
            buf66[17]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);
            uitmp=devPara.VaultFullErrorLevel;
            buf66[18]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
            buf66[19]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);

*/

    virtual void sendMachineID(uint16_t customerNr, uint16_t machineNr,
                              uint16_t borough, uint16_t zone,
                              uint16_t alias,   char *location) const =0;

    virtual void request_ReadbackMachineID() const =0;

    virtual void readback_machineIDdata(uint8_t *length, uint8_t *data) const =0;
    // state 5.5.21: byte[0,1]=customer number    byte[2,3]=machine number
    //               byte[4,5]=borough   byte[6,7]=zone   byte[8,9]=alias name
    //               byte[10...41]=location
    // 12.4.23TS still the same

   
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Printer
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    


    virtual void prn_switchPower(bool on)  const =0;

    virtual bool prn_isPrinterPowerOn(void)  const =0;

    virtual uint8_t prn_PrnFuseIsOk(void) const=0;
     //retval:  0: fuse blown   1: fuse OK   2:unknown as printer power is off

    virtual bool prn_readyINisActive(void)  const =0;
                       
    virtual  uint8_t cash_getLowPaperSensor(void) const=0;
        // 0: Sensor sees paper 1: no paper 99: off

    // the following device state requests are deployed only if device is powered up:
    virtual void request_PrinterHwState() const =0;
    virtual void request_PrinterCurrentFonts() const =0;
    virtual void request_PrinterStateComplete() const =0;
        
    virtual bool test_serialMux1isSetToPrinter(void) const =0;

    // read printer condition and settings

    virtual uint8_t prn_getHwState(struct Tprn_hw_state *prn_hw_state) const =0;
        // retval: status byte
            // byte 0 = 0: prnter OK,  >0: error
            // bit0: paper low  1: no paper    2: temperature error
            // 3: head open     4: paper jam in cutter
            // 6: no response   7: bad response from printer
        // and return struct "Tprn_hw_state"

    virtual bool prn_isUpAndReady(void) const =0;
        // true: printer is powered, serial is ok, no error, printer is connected and resonding

    virtual void prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const =0;


    // send Commands to printer:

    virtual void prn_sendText(QByteArray *buf) const =0;
        // up to 1280 bytes

    virtual void prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const =0;
        // send three byte through to printer, see printers manual

    virtual void prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const =0;
        // send four byte through to printer, see printers manual


    virtual void prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density,  uint8_t alignment, uint8_t orientation) const =0;
        // send 5 byte: byte 0,1: speed  5...250 mm/s
        //              byte2: density   0....(25)....50
        //              byte3: alignment    'l', 'c', 'r' = left, center, right
        //              byte4: orientation  0, 90, 180    = 0Â°, 90Â°, 180Â° rotation (by now not supported!)
        // not batched! don't use twice within 100ms

    virtual void prn_movePaper(uint8_t wayInMm, uint8_t direction) const =0;
        //direction: 1=forward 2=backward
        //
    virtual void prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const =0;
        // font = kind of font 5...11 (0..22)
        // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge
        // width:  0...4   0=1x  1=2x   2=4x (huge!)  3=8x 4=16x (3,4 make no sense)
        // heigth: 0...7 = 1x...8x  only 0,1,2,(3) make sense

    virtual void prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const =0;
        // bold: 0/1
        // invers: 0/1
        // underlined: 0/1

    virtual void prn_cut(uint8_t kindof) const =0;
        // kindof: 1=full cut 2=partial cut 3=eject (5xLF + full cut)

    virtual void prn_newLine(uint8_t nrOfLines) const =0;

    virtual void prn_printCompleteFontTable(void) const =0;

    virtual void prn_printBarcode(uint8_t kindOf, uint8_t withText,  uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const =0;
        // kind of barcode: 0=Code39   1=Code128   2=EAN13    3= 2/5interleaved    4=UPC-A   5=EAN8
        // withText:    print readable text below
        // offset: move by pixel from left border
        // rotation
        // dataLeng in byte

    virtual void prn_sendQRdata(QByteArray *buf) const =0;
        // maximal 150 alphanummeric bytes

    virtual void prn_printQRcode(void) const =0;
        // QRcode may have 1...150 alphanummeric data, must be transfered in advance


    virtual void prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const =0;
        // nrOfLogo: 1..4 in flash  5...8 in Ram
        // offset: in mm form left border



    // .........................................................
    // Parking Ticket (print-out document) designer TD
    // .........................................................

    // Predefine document Layout (e.g. parking ticket) in advance and stroe it for quick and easy use
    // in opposite to the above "single" commands you need only one or a few commands at vending time.
    // Stored text is just send to printer once the printing command is issued
    // stored commands within the text are interpreted and executed right at the place (in ticket) they are
    // example: start bold, <text in bold>, stop bold
    // Predefinition of up to 16 ticket Layouts is possible, 0...1280 byte each
    // Number 0..15, al keept non-volatile
    // up to 8 dynamic values can be defined in the template ("print val3 here") and will be sent with printing command
    // example: print current time at this point (the time of printing not the storage time!!)

    virtual void pri_startTicketDesign(void) const =0;
        // start for every new printer document, reseting collecting buffer

    // all further functions write/append text, numbers and command to the ticket-buffer, up to 1278 bytes allowed
    // return val of the appending functions: true=ok false=too long, buffer full

    virtual int pri_TD_getCurrentSize(void) const =0;
        // retval: 0...1278

    virtual bool pri_TD_addText(QByteArray text) const =0;
        // example: pri_TD_addText("Hello") const =0;
        // example: pri_TD_addText(tempStr) const =0;
        // retval: true=ok false=too long, buffer full

    virtual bool pri_TD_addValue(int val) const =0;
        // +/- 0...2^(31)

    virtual bool pri_TD_addNewLine(void) const =0;

    virtual bool pri_TD_addSign(char sign) const =0;
        // example: '.'   ' '   0x20 'W' '$'

    virtual bool pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const =0;
        // always add 8 byte to the ticket layout:  ESC & group & attribute & parameter1...5
        /* complete list of possible commands:
            group 50 : paper
                attribute 10 :  move forward
                      p1: wayInMm p2: direction
                attribute 11 : cut
                      p1: kind of, 1=full 2=partial, 3=eject
                attribute 12 : new line(s)
                      p1: nr of lines 1...100

            group 51 : fonts
                attribute 10 : kind of font     see description above
                      p1: 0...8
                attribute 11 : font size
                      p1: 6...20
                attribute 12 : font width
                      p1: 0...4
                attribute 13 : font heigth
                      p1: 0...7
                attribute 14 : switch bold print on/off
                      p1: 0=off  1=on
                attribute 15 : switch invers print on/off
                      p1: 0=off  1=on
                attribute 16 : switch underlined print on/off
                      p1: 0=off  1=on

            group 52 : print graphics
                attribute 10 : print barcode with dynamic data 6 and 7
                      p1...p5 = kindOf, withText, offset, rotation, dataLeng, see description above
                attribute 11 : print QRcode with preset data

                attribute 12 : print Logo
                     p1=nrOfLogo, p2=offset

            group 53 : print dynamics
                attribute 10 :
                        p1: 1...8 = print dynData 0..7 at this place

    */

    virtual char prn_clearDocument(uint8_t documentNumber) const =0;
        // clear memory buffer for ONE document
        // function takes a second! don't send right before "store doc"

    virtual bool prn_store_Document(uint8_t documentNumber ) const =0;
        // send the predefined Layout (generated with above TD functions) to DeviceController to save
        // documentNumber=0...15
        // maximal 1280 bytes each
        // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc)
        // 0x1B=start of embedded command (next 7bytes = command)

    // with a print command a set of 8 dynamic strings can be sent
    // the place in the ticket layout is predefined (already in DC memory)
    // the dynamics are first calculated at printing time

    virtual bool prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const =0;


// 36

    
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Mifare Card Reader
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    
    virtual void mif_readerOn(bool on)  const =0;

    virtual bool mif_cardIsAttached(void)  const =0;
    virtual bool mif_isMifarePowerOn(void)  const =0;

    virtual void request_MifareReaderState() const =0;
    virtual void request_MifareCardType() const =0;
    virtual void request_MifareAtbType() const =0;    
    virtual void request_MifareID() const =0;
    virtual void request_MifareData(uint8_t dataBlockNumber) const =0;
    //virtual void request_MifareData() const =0;

        // dataBlockNumber must be 0....11, returns 64byte of data


    virtual bool test_serialMux2isSetToMifare(void) const =0;

    virtual void mif_creatAtbCard(uint8_t cardType) const =0;

    /* data description:
    byte 0: current read state: 0=power off  1=reader-fault 2=ready
                                3=just reading 4=read complete
                                5=read partial, removed too early
                                6=state unknown
    byte 1,2: read data length from card
    3: 1=reader is OK (reported serial nr is OK)  0=wrong or no reader
    4...15: reader version, expected "ATB25-1.8"
    byte16: 1=card is present   0:not
    17: 0
    18: card type reported from reader
    19: 1=allowed card type 0=not
    20: card size: 1 or 4 (dec) = card size
    21: LengthOfUID: 4 or 7 (dec) (byte)
    22: UID 8 byte in hex
    byte 30: sector logged: 0
    byte 31: current sector: 0
    byte 32: result, always 0
    */
    virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0;
        // retval 0=OK 1=error host buffer too small

    virtual bool mif_readerIsOK(void) const =0;

    virtual bool mif_cardAttached(void) const =0;

    virtual uint8_t mif_readResult(void) const =0;
        // result: 0: unknown or still in progress
        //         1: card read successful
        //         2: reading error

    //virtual void mif_clearDataBuffer(void) const =0;
 
    virtual QString mif_cardUID(void) const =0;
        // returns string with 8 byte

    //virtual bool mif_isBlockAvailable(uint8_t blkNr) const =0;
        //blkNr=0...11
        
    //virtual uint32_t mif_getAvailableDataBlocks(void) const =0;
        // bit0=1 if block 0 = valid ...up to ... bit 11=1 if block 11=read

    virtual uint8_t mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const =0;

    virtual QString mif_getCardDataStr(uint8_t blockNumber) const =0;
        // with blockNumber=0...11

    // read mifare data independant from blocks
    //virtual uint16_t mif_getNrOfAvailableDataBytes(void) const =0;

    //virtual bool mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize) const =0;

    //virtual bool mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize) const =0;

    //virtual QString mif_getCardDataStr(bool useHexFormat, char seperator) const =0;

// 16
    
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Credit Card Terminal
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    
    virtual void credit_switchPower(bool on)  const =0;
        // the same as modem power

    virtual bool cred_isCreditPowerOn(void)  const =0;

    virtual bool test_serialMux2isSetToCredit(void) const =0;

    virtual void credit_switchWake(bool WAKEACTIVE)  const =0;

// 4
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Modem
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
            
    virtual void mod_switchPower(bool on) const=0;

    virtual bool mod_isGsmPowerOn(void)  const =0;

    virtual bool test_serialMux1isSetToModem(void) const =0;

    virtual void mod_switchWake(bool WAKEACTIVE) const=0;

// 2

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // MDB Bus
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void mdb_switchPower(bool on)  const =0;
    virtual void mdb_switchWake(bool WAKEACTIVE)  const =0;

    virtual bool mdb_WakeINisActive(void)  const =0;
    virtual bool mdb_testIsmdbTxDon(void)  const =0;
    virtual bool mdb_isMdbPowerOn(void)  const =0;

    virtual void request_MDB_Status() const =0;
    virtual void request_MDB_lastResponse() const =0;

    virtual bool test_getDO_mdbRXtst(void) const =0;
        //  readback digital outputs of connected devices
        //  these functions are not needed for normal operation
        //  but can be used to test and verify conditions

    virtual void mdb_sendBusReset(void) const =0;

    virtual void mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const =0;
        // send one bus command directly over mdb bus, refer to mdb manual for commands
        // this command is not needed in normal operation, just for new or special things

    virtual void mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const =0;
        // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs
        // same as mdb_sendCommand, just with data

    virtual bool mdb_busIsReadyToWork() const =0;

    virtual bool mdb_deviceVoltageOK() const =0;

    virtual bool mdb_busVoltageOk() const =0;

    virtual uint8_t mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest,
                                      uint8_t *responseLength, uint8_t *responseBuffer) const =0;
        // fromDevice: device nr from which data was requested 0,1,2,3
        // lastRequest: sent mdb command
        // responseLength: nr of payload data (after mdb-ack) 0...34
        // responseBuffer holds payload data (answer from mdb device)
        // return val: mdb result of this request: 1=got ACK  2=got 3xNAK  3=no or bad response    4:got Data (after ACK)


// 15
    

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Coin Changer, Checker (EMP)
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void request_EMP_allParameters() const =0;  
    
    virtual void request_EMP_lastCoin() const =0;
   
    virtual uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const =0;
        // use for changer


    // ---------------------------------- Electronic Coin Validator EMP -----------------------------------------
 
    virtual void emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const =0;
        // coinAcceptance: bit0=coin1 (lowest donomination)  bit15=coin16  bitH=accept  bit L = deny coin (no validation)
        // tokenChannel 0...31: if this signal comes from emp then a token was inserted
        // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...)

    virtual void emp_pollingOnOff(uint8_t on) const =0;

    virtual void emp_startCoinAcceptance(void) const =0;

    virtual void emp_stopCoinAcceptance(void) const =0;

    virtual void emp_getAllParameters(struct T_emp *emp) const =0;
        // see struct in hwapi.h
        // usage example:
        //      hwapi   *HWaccess const =0;
        //      HWaccess = new hwapi() const =0;
        //      struct T_emp   myEmp const =0;
        //      HWaccess->emp_getAllParameters(&myEmp) const =0;
        //          readval=myEmp.pollingRunning const =0;

    virtual uint8_t emp_chkIfCoinInserted(void) const =0;
        // retval: 0...16 coins left in FIFO

    virtual void emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const =0;
        // with every call ONE coin is taken out of FIFO and pointer decremented
        // valid: should be 1
        // signal: comes right from coin checker, 0...15 (0=first programmed coin type) 0xFF=no signal
        // error: was reported from EMP as dynamic signal right after coin insertion (instead of
        //          coin signal), example: 3=unknown coin  4=coin is blocked by host.  0xFF=no error
        // value: of the coin. Depends on parameter "coinDenomination" in function "emp_sendSettings"
        //          if coinDenomination[coin 0..15] = 0 then the value programmed in coin checker is taken
        //          if coinDenomination > 0 then this value is taken.
        //          Useful in case of two currencies (adapt to local currency) or for token.

    // function gives more details as "emp getLastCoin()" but "emp getLastCoin()" is easier to use

    // alternativ to emp_getNewCoinRecord( ):
    virtual uint8_t emp_giveLastCoin(uint16_t *value, uint8_t *signal) const =0;
        // retval: 0: NO coin stored  1: valid coin  2: got wrong coin or coin denied
        // value: if retval1: value of the coin if reval=2: error number
        //          0xFF means NO error or NO signal  (as 0 is a valid error/signal)
        // signal: channel nr reported from checker 0...15

// 11
                           
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // Coin blocker, Coin Escrow, Coin reject
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
                                
    virtual void shut_move(bool open)  const =0;
    virtual void esc_moveFlaps(uint8_t flap )  const =0;
        // 0: close both  1: open take-flap   2: open return

    virtual void coin_switchRejectMotor(uint8_t dir) const =0;
    virtual bool coid_isAttached(void)  const =0;
    virtual bool coin_escrowIsOpen(void)  const =0;
    virtual  bool cash_getRejectMotorHomePos(void) const=0;


    virtual bool coin_shutterIsOpen(void) const =0;
    virtual bool coin_shutterTestOutput(void) const =0;

    virtual uint8_t coin_escrowFlapOpened(void) const =0;
        // retval: 1:return flap is open   2:take flap is open    0:closed

    virtual void shut_openOnce(void) const =0;
        // and close automatic after shutter time

    virtual void shut_openForCoin(bool start) const =0;
        // open flap if coin is attached
        // once process is started it runs until stop command

    virtual void shut_sendOpeningTime(uint16_t timeIn_ms ) const =0;
        // after this time without retrigger the flap is closed

    virtual void esc_takeMoney(void) const =0;
        // and close automatically after escrow time (1s)

    virtual void esc_returnMoney(void) const =0;
        // and close automatically after escrow time (1s)

     virtual void coin_rejectCoins(void) const =0;

// 15

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // MDB Bill evaluator
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

              
    
    
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // doors, locks, cashboxes
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void lock_switchContactPower(bool on)  const =0;
                                    
    virtual bool door_isContactPowerOn(void)  const =0;
                                    
    virtual uint8_t door_getLocks(void)  const =0;
        // retval bit0: upper lever is up   (=open)
        //        bit1: upper lever is down (=locked)
        //        bit2: lower lever is up
        //        bit3: lower lever is down (=locked)
                                        
    virtual bool door_upperDoorIsLocked(void)  const =0;

    virtual bool door_upperDoorIsUnlocked(void)  const =0;
                           
    virtual uint8_t lock_switchUpperLock(uint8_t dir)  const =0;
        // dir 0=off 1=up 2=down         
        // move lock until stop cmd (0)
            
    virtual uint8_t lock_openUpperDoor(void) const =0;
    // Locks stops automatically at end switch or by timeout

    virtual uint8_t lock_closeUpperDoor(void) const =0;
    // Locks stops automatically at end switch or by timeout
                   
    virtual uint8_t door_getSwitches(void)  const =0;
        // retval:  bit0: upper door  1: low door  2:vault door
                  
    virtual bool    door_isUpperDoorOpen(void)  const =0;        
    

    virtual bool door_lowerDoorIsLocked(void)  const =0;

    virtual bool door_lowerDoorIsUnlocked(void)  const =0;
        
    virtual uint8_t lock_switchLowerLock(uint8_t dir)  const =0;
        // dir 0=off 1=up 2=down
        // move lock until stop cmd (0)
                       
    virtual uint8_t lock_getDO_motors(void) const =0;
        // bit0: upper lock forward    bit 1 backward
        // bit2: lower lock forward    bit 3 backward

    virtual uint8_t lock_openLowerDoor(void) const =0;
        // there's no closing function as Lock always makes one complete cycle and can be locked again immed.

    virtual uint8_t lock_closeLowerDoor(void) const =0;

    virtual bool    door_isLowerDoorOpen(void)  const =0;
                                                     
    virtual uint8_t vault_getSwitches(void)  const =0;
        // retval bit0: cash box,  bit 1: bill box
        
    virtual bool    vault_isVaultDoorOpen(void)  const =0;
                          
    virtual void lock_switchVaultDoor(void)  const =0;
    
    virtual bool    vault_isCoinVaultIn(void)  const =0;

    virtual bool    vault_isBillVaultIn(void)  const =0;

// 21
        

    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    
    // LEDs, Barrier, Alarm, Relais, Aux
    // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$    

    virtual void led_switchLedIllumination(uint8_t on) const = 0;

    virtual void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
                  
    virtual bool led_coinIsOn(void) const =0;
        // read back digital output from DC-uC-Port
    virtual bool led_frontIsOn(void) const =0;
                          
    virtual void led_switchLedService(uint8_t on)  const =0;
    // on=1   off=0
    virtual bool led_insideIsOn(void) const =0;
            
    virtual void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
    virtual bool led_ticketIsOn(void) const =0;

    virtual void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
    virtual bool led_StartIsOn(void) const =0;

    virtual void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof)  const =0;
    virtual bool led_pinIsOn(void) const =0;

    
    virtual void fan_switchFan(bool on)  const =0;
    virtual void alarm_switchSiren(bool on) const =0;
    virtual bool fan_isOn(void) const =0;
   
    virtual bool siren_isOn(void) const =0;
    
    virtual void bar_OpenBarrier(bool open)  const =0;       
    virtual bool bar_relayIsOn(void) const =0;

    virtual bool bar_optoIn1isOn(void)  const =0;

    virtual bool bar_optoIn2isOn(void)  const =0;

    virtual void aux_power(bool on)  const =0;
    virtual bool aux_powerIsOn(void) const =0;

    virtual void aux_setUsage(uint8_t PinDirection)  const =0;
    virtual void aux_setOutputs(uint8_t PinIsHigh)  const =0;

    virtual bool aux_isAuxPowerOn(void)  const =0;

    virtual uint8_t aux_getAuxInputs(void)  const =0;



// ------------------------------------------------------------------------------------
// 27.3.2023: Use Device-Controller's Bootloader to send hex-file
// ------------------------------------------------------------------------------------

    virtual void bl_rebootDC(void) const =0;

    virtual void bl_startBL(void) const = 0;
        // send command within 4s after DC power-on, otherwise bl is left

    virtual bool bl_checkBL(void) const = 0;
        // send command to verify if bl is up

    virtual bool bl_isUp(void) const =0;
        // return true is bl is up and running
        // also initializes "sendFile"

    virtual void bl_sendAddress(uint16_t blockNumber) const=0;
        // send start address, nr of 64byte-block, start with 0
        // will be sent only for following block-numbers:
        // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
        // for other addresses nothing happens

    virtual uint8_t bl_wasSendingAddOK(void) const=0;
    // return val: 0: no response by now  1:error  10: OK

    virtual void bl_openBinary(void) const=0;
        // to be used within CashAgent, momentary not processed

    virtual void bl_sendDataBlock(uint8_t length, uint8_t *buffer) const=0;
    // send 64 byte from bin file

    virtual void bl_sendLastBlock(void) const=0;
    // send this command after all data are transfered

    virtual uint8_t bl_wasSendingDataOK(void) const=0;
    // return val: 0: no response by now  1:error  10: OK

    virtual void bl_stopBL(void) const=0;
        // leave BL and start (the new) application

    //virtual bool bl_isDiagAvailable(void) const=0;

    //virtual QString dc_getDiagText(void) const=0;


    // Komplett-schreib Funktion, noch nicht getestet
    // Nachteil: keine Rückmeldung wie lang's noch dauert
    //virtual void bl_startSending(void) const=0;
        // call once after BL is working and file is loaded
    //virtual void bl_sendFile(void) const=0;
        // call cyclic while loading bin-file to bootloader




// ------------------------------------------------------------------------------------
// 6.4.2023: new functions for coin collection and printing
//            some new system functions
// ------------------------------------------------------------------------------------

    virtual bool rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const=0;
        // return true if sending, false if cmd-stack is full

    virtual bool rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const=0;
/*
     buf[0]=GlobTime.Hours;
    buf[1]=GlobTime.Min;
    buf[2]=GlobTime.Sec;
    buf[3]=GlobTime.Year;
    buf[4]=GlobTime.Month;
    buf[5]=GlobTime.Day;
    buf[6]=GlobTime.DOW;
    buf[7]=' ';                   // immer auf 32bit auffüllen sonst Speicherproblem beim Master!
    uitmp=GlobTime.MinOfDay;
    buf[8]=swl_getOneByteFromUint(uitmp, 0);
    buf[9]=swl_getOneByteFromUint(uitmp, 1);
    buf[10]=' ';
    buf[11]=' ';
    ultmp=GlobTime.SecOfDay;
    buf[12]=swl_getOneByteFromUlong(ultmp, 0);
    buf[13]=swl_getOneByteFromUlong(ultmp, 1);
    buf[14]=swl_getOneByteFromUlong(ultmp, 2);
    buf[15]=swl_getOneByteFromUlong(ultmp, 3);

    buf[16]=swl_isLeap(GlobTime.Year);
    buf[17]=swl_getNextLeapYear(GlobTime.Year);
    buf[18]=swl_getLastLeapYear(GlobTime.Year);
    buf[19]=swl_hoursOfThisWeek(GlobTime.DOW, GlobTime.Hours);

    uitmp=swl_minutesOfThisWeek(GlobTime.DOW, GlobTime.Hours, GlobTime.Min);
    buf[20]=swl_getOneByteFromUint(uitmp, 0);    // 0=low byte   1=high byte
    buf[21]=swl_getOneByteFromUint(uitmp, 1);

    uitmp=swl_hoursOfThisMonth(GlobTime.Day, GlobTime.Hours);
    buf[22]=swl_getOneByteFromUint(uitmp, 0);
    buf[23]=swl_getOneByteFromUint(uitmp, 1);

    uitmp=swl_minutesOfThisMonth(GlobTime.Day, GlobTime.Hours, GlobTime.Min);
    buf[24]=swl_getOneByteFromUint(uitmp, 0);
    buf[25]=swl_getOneByteFromUint(uitmp, 1);

    uitmp=swl_GetDaysOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day);
    buf[26]=swl_getOneByteFromUint(uitmp, 0);
    buf[27]=swl_getOneByteFromUint(uitmp, 1);

    uitmp=swl_GetHoursOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day, GlobTime.Hours);
    buf[28]=swl_getOneByteFromUint(uitmp, 0);
    buf[29]=swl_getOneByteFromUint(uitmp, 1);
    buf[30]=0;
    buf[31]=0;
    ultmp= swl_GetMinutesOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day,
                                GlobTime.Hours, GlobTime.Min);
    buf[32]=swl_getOneByteFromUlong(ultmp, 0);
    buf[33]=swl_getOneByteFromUlong(ultmp, 1);
    buf[34]=swl_getOneByteFromUlong(ultmp, 2);
    buf[35]=swl_getOneByteFromUlong(ultmp, 3);

    buf[36]=rtc_getSqwaveSettings();
    buf[37]=0;
    buf[38]=0;
    buf[39]=0;

    ultmp= 0;       // Minutes of the Millenium
    buf[40]=swl_getOneByteFromUlong(ultmp, 0);
    buf[41]=swl_getOneByteFromUlong(ultmp, 1);
    buf[42]=swl_getOneByteFromUlong(ultmp, 2);
    buf[43]=swl_getOneByteFromUlong(ultmp, 3);

    dc2prot_setReadData(44, buf);

 */

    virtual bool rtc_getExtendedTime(struct T_extTime *exTime) const=0;

    virtual bool sys_runCompleteTest(void) const=0;
        // warning: lasts 20s in one pace
        // return true if sending, false if cmd-stack is full

    virtual bool sys_ready4sending(void) const=0;
    // return true if a Json-file can be sent

    virtual bool sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const=0;
        // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer
        //      nrOfTemplate=1...32 if kindOfFile==6
        //      content = content of the Json file, max 800byte ascii signs
        // file is 0-terminated
        // return true if sending, false if cmd-stack is full

    virtual bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const=0;
        // dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string
        //            like:     char prn_dynPrnVal[8][8];
        // return true if sending, false if cmd-stack is full

    virtual bool prn_printTemplate(uint8_t nrOftemplate) const=0;
        // print one of the templates loaded by Json prior
        // nr = 1..32
        // return true if sending, false if cmd-stack is full

    virtual void log_getHoldAccountNumbers(uint8_t *nrOfVals, uint16_t *accNr ) const=0;
        // returns all acc nrs of the backuped vault records
        // use: uint16_t backupedAccNumbers[8]

    virtual bool log_selectVaultRecord(uint16_t accountNr ) const=0;
        // return true if sending, false if cmd-stack is full
        // and trigger transfer

    virtual bool log_chkIfVaultRecordAvailable(void) const=0;
        // return true if completly received

    virtual bool log_getVaultRecord(struct T_vaultRecord *retVR) const=0;
        // which was selected by: log_selectVaultRecord()
        // to be forwarded to Ismas

    virtual bool prn_printAccountReceipt(void) const=0;
        // return true if sending to DC OK, false if cmd-stack is full

    virtual bool prn_printTestTicket(void) const=0;
        // return true if sending to DC OK, false if cmd-stack is full

    virtual bool cash_startPayment(uint32_t amount) const=0;
        // 17.4.23TS: extended to 32bit

    virtual uint32_t getInsertedAmount(void) const=0;

    virtual uint16_t getLastInsertedCoin(void) const=0;

    virtual bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const=0;
        // all inserted coins (max 64) since "cash_startPayment"

    virtual bool cash_cancelPayment(void) const=0;
        // and return coins

    virtual bool cash_stopPayment(void) const=0;
        // and keep coins in escrow

    // after ticket/goods issue:
    virtual bool vend_success(void) const=0;
        // conclude payment process, encash all inserted coins to vault. Printing was successful
        // if possible return change

    virtual bool vend_failed(void) const=0;
        // conclude payment process and return all inserted coins


    virtual uint8_t mif_getCardType(QString *cardholder) const=0;
        // return 1,2,3,4 = upper, lower access card, printer test, coin test
        // cardholder: 7byte Name-String

    virtual uint64_t sys_getWakeSource(void) const =0;
        // retval: 6 bytes, bit coded, 1=event keeps DC awake

    virtual uint8_t sys_getWakeReason(void) const=0;
         // Master was woken by following reason:
         // 1: MDB Event
         // 2: Coin Event
         // ( 3: Master Event) - will not set the wake line
         // ( 4: 32s pulse) - will not set the wake line
         // 5: Door Event
         // ( 6: Diag Event) - will not set the wake line
         // 7: 30min-Pulse for HB

    virtual void sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const=0;
    /*

    outBuf[0]=modCond.ram;
    outBuf[1]=modCond.intEe;
    outBuf[2]=modCond.extEe;
    outBuf[3]=modCond.rtc;
    outBuf[4]=modCond.boardHw;
    outBuf[5]=modCond.printer;
    outBuf[6]=modCond.modem;
    outBuf[7]=modCond.signal;
    outBuf[8]=modCond.regist;
    outBuf[9]=modCond.mdbBus;
    outBuf[10]=modCond.coinChecker;
    outBuf[11]=modCond.coinEscrow;
    outBuf[12]=modCond.mifareReader;
    outBuf[13]=modCond.creditTerm;
    outBuf[14]=modCond.coinReject;
    outBuf[15]=modCond.coinSafe;
    outBuf[16]=modCond.billSafe;
    outBuf[17]=modCond.voltage;
    outBuf[18]=modCond.temper;
    outBuf[19]=modCond.poweronTest;
    outBuf[20]=modCond.doorState;
    outBuf[21]=modCond.doorWasOpened;
    outBuf[22]=modCond.changer;
    outBuf[23]=modCond.coinBlocker;
    outBuf[24]=modCond.billReader;
    outBuf[25]=modCond.ResetReason;
    outBuf[26]=modCond.allModulesChecked;
    outBuf[27]=modCond.alarmState;
    outBuf[28]=0;
    outBuf[29]=0;

     */

    virtual void sys_getDeviceConditions(struct T_moduleCondition *devCond) const=0;
    virtual void sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const=0;
/*

    outBuf[pBuf++]=dynCond.allDoorsDebounced;
    outBuf[pBuf++]=dynCond.openedAuthorized;
    outBuf[pBuf++]=dynCond.CBinDebounced;
    outBuf[pBuf++]=dynCond.upperDoor;

    outBuf[pBuf++]=dynCond.middleDoor;
    outBuf[pBuf++]=dynCond.lowerDoor;
    outBuf[pBuf++]=dynCond.coinBox;
    outBuf[pBuf++]=dynCond.billBox;

    outBuf[pBuf++]=dynCond.modeAbrech;
    outBuf[pBuf++]=dynCond.onAlarm;
    outBuf[pBuf++]=dynCond.nowCardTest;
    outBuf[pBuf++]=dynCond.nowPayment;

    outBuf[pBuf++]=dynCond.lastMifCardType;
    outBuf[pBuf++]=dynCond.lastSDoorState;
    outBuf[pBuf++]=dynCond.lastVDoorState;
    outBuf[pBuf++]=dynCond.lastCBstate;

    outBuf[pBuf++]=dynCond.paymentInProgress;
    outBuf[pBuf++]=0;
    uitmp=dynCond.U_Batt;
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);
    uitmp=dynCond.Temperatur;
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);

    uitmp=dynCond.nrCoinsInBox;	// send seperate also
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETLOWBYT);
    outBuf[pBuf++]=swl_getOneByteFromUint(uitmp, GETHIGHBYT);

    ultmp=dynCond.amountInBox;	// send seperate also
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWESTBYT);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHESTBYT);

    ultmp=dynCond.totalTransVolume;
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWESTBYT);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHESTBYT);

    ultmp=dynCond.totalNrOfVends;
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWESTBYT);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETLOWMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHMID);
    outBuf[pBuf++]=swl_getOneByteFromUlong(ultmp, GETHIGHESTBYT);
// 36
    outBuf[pBuf++]=dynCond.jsonValid_config;
    outBuf[pBuf++]=dynCond.jsonValid_device;
    outBuf[pBuf++]=dynCond.jsonValid_cash;
    outBuf[pBuf++]=dynCond.jsonValid_print;
    outBuf[pBuf++]=dynCond.jsonValid_serial;
    outBuf[pBuf++]=dynCond.jsonValid_time;
    outBuf[pBuf++]=dynCond.lastFileType;
    outBuf[pBuf++]=0;

*/

    virtual void sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const=0;

    // content of Cashbox
    virtual uint32_t cash_getAmountInVault(void) const=0;

    virtual uint16_t cash_getNrCoinsInVault(void) const=0;


    virtual uint8_t prn_getPrintResult() const=0;

    // in case of print-error get detailed error:
    virtual uint8_t prn_getCurrentPrinterState() const=0;
        //        0: printer OK
        //          bit0: near paper end          bit1: no paper
        //          bit2: temperature error       bit3: error head open
        //          bit4: paper jam in cutter
        //          bit6: no response             bit7: serial rec. error
        //			bit5: printer not ready

    virtual void sys_sendDeviceParameter(struct T_devices *deviceSettings) const=0;

    virtual void sys_restoreDeviceParameter(struct T_devices *deviceSettings) const=0;

    /* ---------------------------------------------------------------------------------------------
    // ------------   supervise  all hardware components
    // ------------    assess the machine state

    1. check if DC startup test is through, retrigger if not
    2. get results and find errors
    3. in case of error check if component is used (e.g. billreader is seldom used)
    4: check doors
    5. return value: 0: no response from DC
                     1: no Test results and Test not running. need retrigger!
                     2: state not clear by now, test ongoing, wait
                     3: Service or battery door is open, goto INTRUSION MODE
                            from here: after valid ID-card goto SERVICE MODE
                     4: vault door is open, goto INTRUSION MODE
                            from here: after valid ID-card and vault door closed goto TEST MODE
                            in TEST MODE: complete system check decides if vending mode allowed
                     5: All doors are closed but errors found,
                            goto OOO MODE (out-of-order)
                            from here: run system test until problem is fixed
                     6: All doors are closed, no error, maybe warnings,
                            goto VENDING MODE (normal operation)
                    (priority sinks from 0 to 6)

     --------------------------------------------------------------------------------------------- */

    virtual uint8_t sys_componentAssessment(void) const=0;
    // this function decides if vending mode is possible, independant from door
    // return >0 in case of error
    // is inncluded in sys_superviseSystem

    virtual uint8_t sys_superviseSystem(void) const=0;
    // this function proofs if vending is possible depending of doors state

    virtual uint8_t sys_getSystemErrors(void) const=0;


    // retrigger System-Check with:
    // bool hwapi::sys_runCompleteTest(void) const








    // ---------------------------------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------

signals:
    virtual void hwapi_templatePrintFinished_OK(void) const=0;
    virtual void hwapi_templatePrintFinished_Err(void) const=0;
    virtual void hwapi_gotNewCoin(void) const=0;
    virtual void hwapi_vendStopByMax(void) const=0;
    virtual void hwapi_vendStopByPushbutton(void) const=0;

};


// History
// 11.10.2021: V1.0  222 functions
// 23.12.2021: V1.1  added block-parameter to function "read mifare data"
// 30.12.2021: V1.2  added function: mif_clearDataBuffer(), mif_isBlockAvailable(uint8_t blkNr) and mif_getAvailableDataBlocks()
// 1.1.2022: V1.3    Mifare extended. ( background: read 16 x 48byte from card to DC, read 12 x 64byte from DC to CA)
//                   new:  read full card with 768bytes from HWapi without block borders 
//                   added: mif_getNrOfAvailableDataBytes     mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize)
//                           mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize) 
//                            mif_getCardDataStr(bool useHexFormat, char seperator)    

// 29.03.2023: V3.1 some extensions for PSA1256_ptu5,
//             V3.2 Bootloader improvement
// 12.04.2023: V3.3 new features extended: loading and using Json-files, cash-collection, cash-data-logging
// 14.04.2023: V3.4 new features extended: sys_getDynMachineConditions, sys_getDeviceConditions and
//                    rtc_getExtendedTime return struct in addition. New function to select and get VaultRecord
//

//#define HWINF_iid "Atb.Psa2020.software.HWapi/3.1"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.1"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.3"
//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.4"
#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.5"



Q_DECLARE_INTERFACE(hwinf, HWINF_iid)


#endif



