root / pykocard / trunk / pykocard / cartadistcrs.py @ 3539

Revision 3539, 4.8 kB (checked in by jerome, 14 years ago)

Added a comment about the code not working right now with an unpatched PySerial?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# -*- coding: utf-8 -*-
2#
3# PyKoCard
4#
5# PyKoCard : Smart Card / Vending Card managing library
6#
7# (c) 2010 Jerome Alet <alet@librelogiciel.com>
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20#
21# $Id$
22#
23
24import sys
25
26import serial # On Debian/Ubuntu : apt-get install python-serial
27
28class CartadisTCRS :
29    """A class to manage Cartadis TCRS vending card readers.
30
31       Documentation was found in a Cartadis TCRS reader's paper manual.
32
33       Cartadis is a registered trademark from Copie Monnaie France (C.M.F.)
34    """
35    def __init__(self, device, timeout=5.0, debug=False) :
36        """Initializes the connection to the reader."""
37        self.device = device
38        self.timeout = timeout
39        self.debug = debug
40
41        self.lastcommand = None
42        self.tcrsprompt = chr(13) + chr(10) + '$' # the prompt
43        self.eoc = chr(13) # end of command
44
45        # Each Cartadis vending card contain the following informations :
46        #
47        # the card can only be read on readers for which this group number
48        # was specifically allowed.
49        self.group = None
50        # the number of credits on the card.
51        self.value = None
52        # the two following fields allow the card
53        # to be assigned to a particular individual.
54        # only plastic cards can use such attributes,
55        # for throw-away cards, these values should both be set to 0
56        self.department = None
57        self.account = None
58        # transaction number. Max 3000 for plastic cards, else 500.
59        self.trnum = None
60
61        # opens the connection to the reader
62        self.tcrs = serial.Serial(device,
63                                  baudrate=9600,
64                                  bytesize=serial.EIGHTBITS,
65                                  parity=serial.PARITY_NONE,
66                                  stopbits=serial.STOPBITS_ONE,
67                                  xonxoff=False,
68                                  rtscts=True,
69                                  timeout=timeout)
70
71        # cleans up any data waiting to be read
72        self.tcrs.flushInput()
73
74        # Identifies the terminal
75        self.versionNumber = self.version()
76        self.serialNumber = self.serial()
77        self.logDebug("%s terminal detected on device %s with serial number %s" \
78                          % (self.versionNumber,
79                             self.device,
80                             self.serialNumber))
81
82    def __del__(self) :
83        """Ensures the serial link is closed on deletion."""
84        self.close()
85
86    def close(self) :
87        """Closes the serial link if it is open."""
88        if self.tcrs is not None :
89            self.logDebug("Closing serial link...")
90            self.tcrs.close()
91            self.tcrs = None
92            self.logDebug("Serial link closed.")
93
94    def logDebug(self, message) :
95        """Logs a debug message."""
96        if self.debug :
97            sys.stderr.write("%s\n" % message)
98            sys.stderr.flush()
99
100    def sendCommand(self, cmd, param=None) :
101        """Sends a command to the reader."""
102        if param is not None :
103            command = "%s %s%s" % (cmd, param, self.eoc)
104        else :
105            command = "%s%s" % (cmd, self.eoc)
106        self.logDebug("Sending %s to reader" % repr(command))
107        self.tcrs.write(command)
108        self.tcrs.flush()
109        self.lastcommand = command
110        #
111        # IMPORTANT : the following code doesn't work because currently
112        # PySerial doesn't allow an EOL marker to be several chars long.
113        # I've just sent a patch for this to PySerial's author, and we'll
114        # see what happens. If not accepted, I'll write it another way.
115        return = self.tcrs.readline(eol=self.tcrsprompt)[:-len(self.tcrsprompt)]
116
117    def help(self) :
118        """Returns the list of commands supported by the TCRS."""
119        result = self.sendCommand("help")
120        self.logDebug("Supported commands : %s" % result)
121        return result
122
123    def version(self) :
124        """Returns the TCRS' version string."""
125        return self.sendCommand("version")
126
127    def serial(self) :
128        """Returns the TCRS' serial number.'"""
129        return self.sendCommand("serial")
130
131if __name__ == "__main__" :
132    # Minimal testing
133    tcrs = CartadisTCRS("/dev/ttyS0", debug=True)
134    tcrs.help()
135    tcrs.close()
Note: See TracBrowser for help on using the browser.