extface 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc59569d61b550e245d115c0542d9803bc9ded4c
4
- data.tar.gz: 16607248a89cc5776e47a9145eed8a4a68389509
3
+ metadata.gz: ffc7be7748574fcff49cfea02aab44e7f4f97760
4
+ data.tar.gz: 426759fdcff98ca0979ef600877c42674f9b4733
5
5
  SHA512:
6
- metadata.gz: 981cd2238ba9611ea66f5375af2e34d4f33272bdc303109910e8407c979c59946881a17c234150b2275ad878e0b77df4104a6abf52b3ca6a4722870e9af3b700
7
- data.tar.gz: a11e17b3b21d4600915fc7181898258a0eb28961da58d5c0bffaeb8b0d571e0819fca358037a90f573e61bbe5e0e03a6d26e3aa3f135dbd578896646e07fd538
6
+ metadata.gz: 4cf1335ec7f7cf50da17e1816213b740a675e5d0b6223f13b9d4145ff14a14d50c6411b4ec29808568b9d39f456b1d657f160122c64da8596f5dfb0439d86ad9
7
+ data.tar.gz: 6821ca4e6a6e1078740eebc9c7d30a4dd899e204eb1c979eca3dd695080b35141c7eaff4bf036969151031c830dd4a2483b124396c357264e348391bd597361d
@@ -1,4 +1,4 @@
1
- Copyright 2014 YOURNAME
1
+ Copyright 2014 Alex Vangelov
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -269,7 +269,7 @@ module Extface
269
269
  def initialize(buffer)
270
270
  # test Extface::Driver::DaisyFx1200::RespFrame.new("\x16\x16\x01\x2c\x20\x2dP\x04SSSSSS\x05\BBBB\x03")
271
271
  # LEN SEQ CMD DATA STATUS BCC
272
- if match = buffer.match(/\x01(.{1})(.{1})(.{1})(.*)\x04(.{6})\x05(.{4})\x03/n)
272
+ if match = buffer.match(/\x01(.{1})(.{1})(.{1})(.*)\x04(.{6})\x05(.{4})\x03/nm)
273
273
  @frame = match.to_a.first
274
274
  @len, @seq, @cmd, @data, @status, @bcc = match.captures
275
275
  else
@@ -0,0 +1,78 @@
1
+ #Source: ELTRADE COMMUNICATION PROTOCOL for Fiscal Printers (ver 4.0.2.12)
2
+
3
+ module Extface
4
+ module Driver::Eltrade::CommandsFp4
5
+ STRT = "\xAA\x55"
6
+
7
+ module Info
8
+ GET_SERIAL_NUMBER = 0x10
9
+ GET_HEADING_ROWS_1_6 = 0x11
10
+ GET_FISC_MEM_NUMBER = 0x14
11
+ GET_TAX_NUMBER = 0x15
12
+ GET_HEADING_ROWS_7_10 = 0x17
13
+ GET_TAX_GROUPS = 0x19
14
+ GET_OPERATOR = 0x1A
15
+ GET_PAYMENTS = 0x1B
16
+ GET_PRINTER_STATUS = 0x2C
17
+ GET_FISCAL_STATUS = 0x30
18
+ GET_FISCAL_TYPE = 0x3C
19
+ GET_DATE_TIME = 0x3E
20
+ REQUEST_HARDWARE_STAT = 0x46
21
+ GET_HARDWARE_STATUS = 0x47
22
+ GET_STATUS = 0x70
23
+ end
24
+ module Receipt
25
+ OPEN_RECEIPT = 0x2D
26
+ PRINT_RECEIPT = 0x2E
27
+ module Variant
28
+ COMMENT = "\x01"
29
+ PLU = "\x02"
30
+ START_INVOICE_RECEIPT = "\x0D"
31
+ START_COMMENT_RECEIPT = "\x0F"
32
+ end
33
+ CLOSE_RECEIPT = 0x2F
34
+ LAST_DOC_COPY = 0x31
35
+ SET_INVOICE_NUMBER = 0x34
36
+ PRINT_RECEIPT_HEADER = 0x38
37
+ end
38
+ module Reports
39
+ SILENT0_PLU = 0x22
40
+ SILENT_PRINTER = 0x23
41
+ PLU_REPORT = 0x32
42
+ DAILY_REPORT = 0x33
43
+ end
44
+ module Init
45
+ GRAPHIC_LOGO_PRINTING = 0x13
46
+ SET_OPERATOR_INFO = 0x2A
47
+ SET_PAYMENT_TYPES = 0x2B
48
+ SET_FISCAL_DEV_NUM = 0x35
49
+ FISCAL_PARAMS_REC = 0x36
50
+ SET_PRINT_PLU_NUMBER = 0x3A
51
+ SET_SERIAL_NUMBER = 0x3B
52
+ SET_DATE_TIME = 0x3D
53
+ end
54
+ module Other
55
+ EXEC_PRINTER_TEST = 0x24
56
+ FISC_MEM_READ_TEST = 0x25
57
+ FISC_MEM_WRITE_TEST = 0x26
58
+ PAYED_RECV_ACCOUNT = 0x28 # ?
59
+ GET_DATE_TIME = 0x3E
60
+ SET_DATE_TIME = 0x3D
61
+ OPEN_CASH_DRAWER = 0x4B
62
+ end
63
+
64
+ def build_packet(cmd, fields = [])
65
+ String.new.tap() do |frame|
66
+ frame << STX
67
+ frame << sequence_number
68
+ frame << cmd
69
+ fields.each do |field|
70
+ frame << SEP
71
+ frame << field
72
+ end
73
+ frame << ETX
74
+ frame << bcc(frame)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,359 @@
1
+
2
+ # 1 2 3 4 5 6 6+n
3
+ #STRT ADDR SEQ CMD LEN DATA CS
4
+ # 1 1 1 1 1 1 4 1
5
+ #AAh 55h 0–FFh 0–FFh 10h–70h 0-FFh 30h–3Fh 0-FFh
6
+
7
+ module Extface
8
+ class Driver::EltradeTmU220 < Extface::Driver
9
+ NAME = 'Eltrade TM-U220 (Serial)'.freeze
10
+ GROUP = Extface::FISCAL_DRIVER
11
+
12
+ DEVELOPMENT = true #driver is not ready for production (not passing all tests or has major bugs)
13
+
14
+ # Select driver features
15
+ RAW = true #responds to #push(data) and #pull
16
+ PRINT = false #POS, slip printers
17
+ FISCAL = true #cash registers, fiscal printers
18
+ REPORT = false #only transmit data that must be parsed by handler, CDR, report devices
19
+
20
+ RESPONSE_TIMEOUT = 3 #seconds
21
+ INVALID_FRAME_RETRIES = 6 #seconds
22
+
23
+ FLAG_TRUE = "\xff\xff"
24
+ FLAG_FALSE = "\x00\x00"
25
+
26
+ has_serial_config
27
+
28
+ include Extface::Driver::Eltrade::CommandsFp4
29
+
30
+ def handle(buffer)
31
+ bytes_processed = 0
32
+ if frame_match = buffer.match(/\xAA\x55.{3}(.{1}).*/nm) #m Treat \x0a as a character matched by .
33
+ len = frame_match.captures.first.ord
34
+ skip = frame_match.pre_match.length
35
+ bytes_processed = skip + 7 + len # 6 pre + 1 check sum
36
+ rpush buffer[skip..bytes_processed]
37
+ end
38
+ return bytes_processed
39
+ end
40
+
41
+ def open_receipt(variant = nil)
42
+ fsend Receipt::OPEN_RECEIPT
43
+ status = printer_status!
44
+ unless variant.blank?
45
+ fsend Receipt::PRINT_RECEIPT, variant
46
+ status = printer_status!
47
+ end
48
+ end
49
+
50
+ def close_receipt
51
+ fsend Receipt::CLOSE_RECEIPT
52
+ status = printer_status!
53
+ end
54
+
55
+ def send_comment(text)
56
+ fsend Receipt::PRINT_RECEIPT, Receipt::Variant::COMMENT + text
57
+ status = printer_status!
58
+ end
59
+
60
+ def send_plu(plu_data)
61
+ fsend Receipt::PRINT_RECEIPT, Receipt::Variant::PLU + plu_data
62
+ status = printer_status!
63
+ end
64
+
65
+ def send_payment(type_num = 0, value = nil) # 0, 1, 2, 3
66
+ value_bytes = "\x00\x00\x00\x00" # recalculate
67
+ unless value.nil?
68
+ value_units = (value * 100).to_i # !FIXME
69
+ value_bytes = "".b
70
+ 4.times{ |shift| value_bytes.insert 0, ((value_units >> shift*8) & 0xff).chr }
71
+ end
72
+ fsend Receipt::PRINT_RECEIPT, "" << (9 + type_num).chr << value_bytes
73
+ end
74
+
75
+ def non_fiscal_test
76
+ device.session("Non Fiscal Text") do |s|
77
+ s.notify "Printing Non Fiscal Text"
78
+ s.open_receipt Receipt::Variant::START_COMMENT_RECEIPT
79
+ s.send_comment "********************************"
80
+ s.send_comment "Extface Print Test".center(32)
81
+ s.send_comment "********************************"
82
+ s.send_comment ""
83
+ s.send_comment "Driver: " + "#{self.class::NAME}".truncate(24)
84
+ s.close_receipt
85
+ s.notify "Printing finished"
86
+ end
87
+ end
88
+
89
+ def fiscal_test
90
+ sale_and_pay_items_session([
91
+ { price: 0.01, text1: "Extface Test" }
92
+ ])
93
+ end
94
+
95
+ def build_sale_data(price, text1 = "", text2 = nil, tax_group = 2, qty = 1, percent = nil, neto = nil, number = nil)
96
+ "".b.tap() do |data|
97
+ price_units = (price * 100).to_i # !FIXME
98
+ price_bytes = "".b
99
+ 4.times{ |shift| price_bytes.insert 0, ((price_units >> shift*8) & 0xff).chr }
100
+ data << price_bytes
101
+ qty_units = ((qty || 1) * 1000).to_i # !FIXME
102
+ qty_bytes = "".b
103
+ 4.times{ |shift| qty_bytes.insert 0, ((qty_units >> shift*8) & 0xff).chr }
104
+ data << qty_bytes
105
+ data << "\x00".b #number len FIXME
106
+ data << "\xAA\xAA\xAA\xAA\xAA\xAA".b #number FIXME
107
+ text = text1.truncate(20)
108
+ data << text.length.chr
109
+ data << text.ljust(20, " ").b
110
+ data << (tax_group || 2).chr
111
+ end
112
+ end
113
+
114
+ def sale_and_pay_items_session(items = [], operator = "1", password = "1")
115
+ device.session("Fiscal Doc") do |s|
116
+ s.notify "Fiscal Doc Start"
117
+ s.open_receipt
118
+ items.each do |item|
119
+ s.send_plu build_sale_data(item[:price], item[:text1], nil, item[:tax_group], item[:qty], nil, nil, item[:number])
120
+ s.send_comment(item[:text2]) unless item[:text2].blank?
121
+ end
122
+ s.send_payment
123
+ s.close_receipt
124
+ s.notify "Fiscal Doc End"
125
+ end
126
+ end
127
+
128
+ def z_report_session
129
+ device.session("Z Report") do |s|
130
+ s.notify "Z Report Start"
131
+ s.fsend Reports::DAILY_REPORT, FLAG_TRUE
132
+ status = s.printer_status!
133
+ s.notify "Z Report End"
134
+ end
135
+ end
136
+
137
+ def x_report_session
138
+ device.session("Z Report") do |s|
139
+ s.notify "Z Report Start"
140
+ s.fsend Reports::DAILY_REPORT, FLAG_FALSE
141
+ status = s.printer_status!
142
+ s.notify "Z Report End"
143
+ end
144
+ end
145
+
146
+ def cancel_doc_session
147
+ device.session("Doc cancel") do |s|
148
+ s.notify "Doc Cancel Start"
149
+ #s.fsend Sales::CANCEL_DOC
150
+ s.notify "Doc Cancel End"
151
+ end
152
+ end
153
+
154
+
155
+ def printer_status!
156
+ fsend Info::GET_STATUS
157
+ raise errors.full_messages.join(", ") if errors.any?
158
+ status = PrinterStatus.new(fsend(Info::GET_PRINTER_STATUS))
159
+ raise errors.full_messages.join(", ") if errors.any?
160
+ status
161
+ end
162
+
163
+ def check_status
164
+ flush
165
+ fsend(Info::GET_STATUS)
166
+ errors.empty?
167
+ end
168
+
169
+ def build_packet(cmd, data = "")
170
+ "".tap() do |packet|
171
+ packet << STRT.b
172
+ packet << 0x00 #address
173
+ packet << sequence_number
174
+ packet << cmd
175
+ packet << data.length
176
+ packet << data.b
177
+ packet << check_sum(packet[2..-1])
178
+ end
179
+ end
180
+
181
+ def fsend(cmd, data = "") #return data or nil
182
+ packet_data = build_packet(cmd, data)
183
+ result = false
184
+ INVALID_FRAME_RETRIES.times do |retries|
185
+ errors.clear
186
+ push packet_data
187
+ if resp = frecv(RESPONSE_TIMEOUT)
188
+ if resp.valid?
189
+ result = resp.data
190
+ break
191
+ else
192
+ resp.errors.full_messages.each do |msg|
193
+ errors.add :base, msg
194
+ end
195
+ end
196
+ end
197
+ errors.add :base, "#{INVALID_FRAME_RETRIES} Broken Packets Received. Abort!"
198
+ end
199
+ return result
200
+ end
201
+
202
+ def frecv(timeout) # return RespFrame or nil
203
+ if frame_bytes = pull(timeout)
204
+ return Frame.new(frame_bytes.b)
205
+ else
206
+ errors.add :base, "No data received from device"
207
+ return nil
208
+ end
209
+ end
210
+
211
+ def check_sum(buffer)
212
+ sum = 0
213
+ buffer.each_byte do |byte|
214
+ sum -= byte
215
+ end
216
+ sum & 0xff
217
+ end
218
+
219
+ private
220
+ def sequence_number(increment = true)
221
+ @seq ||= 0
222
+ @seq += 1 if increment
223
+ @seq = 0 if @seq == 0xff
224
+ @seq
225
+ end
226
+
227
+ class Frame
228
+ include ActiveModel::Validations
229
+ attr_reader :frame, :addr, :seq, :cmd, :len, :data, :check_sum
230
+
231
+ validates_presence_of :frame
232
+ validate :check_sum_validation
233
+ validate :len_validation
234
+ validate :response_code_validation
235
+
236
+ def initialize(buffer)
237
+ if match = buffer.match(/\xAA\x55(.{1})(.{1})(.{1})(.{1})(.*)(.{1})$/nm)
238
+ @frame = match.to_a.first
239
+ @addr, @seq, @cmd, @len, @data, @check_sum = match.captures
240
+ end
241
+ end
242
+
243
+ def ready?
244
+ @ready || true
245
+ end
246
+
247
+ private
248
+ def check_sum_validation
249
+ sum = 0
250
+ frame[2..-1].each_byte do |byte|
251
+ sum += byte
252
+ end
253
+ errors.add(:check_sum, I18n.t('errors.messages.invalid')) if (sum & 0xff) != 0
254
+ end
255
+
256
+ def len_validation
257
+ errors.add(:len, I18n.t('errors.messages.invalid')) if len.ord != data.length
258
+ end
259
+
260
+ def response_code_validation
261
+ case cmd.ord
262
+ when 0x2c then
263
+ case data[0] # printer error code
264
+ when 1 then errors.add :base, "Opening of the cash register document is not requested"
265
+ when 2 then errors.add :base, "Transaction code recognized (refer to command 0x2E)"
266
+ when 3 then errors.add :base, "Transaction buffer overflow"
267
+ when 4 then errors.add :base, "Transaction sequence error"
268
+ when 5 then errors.add :base, "Multiplication overflow"
269
+ when 6 then errors.add :base, "Cash register document overflow"
270
+ when 7 then errors.add :base, "'0' length of code name"
271
+ when 8 then errors.add :base, "Negative result"
272
+ when 9 then errors.add :base, "Cash register document surcharge"
273
+ when 10 then errors.add :base, "Out of range parameter"
274
+ when 11 then errors.add :base, "Cash register document not paid"
275
+ when 12 then errors.add :base, "'0' result"
276
+ when 13 then errors.add :base, "Memory overflow because of too many PLUs"
277
+ when 14 then errors.add :base, "Daily report overflow"
278
+ end
279
+ when 0x6F then
280
+ case data[1]
281
+ when 1 then errors.add :base, "End of paper"
282
+ when 2 then errors.add :base, "Printing error"
283
+ when 16 then errors.add :base, "Fiscal error 0: Error at writing in FM"
284
+ when 17 then errors.add :base, "Fiscal error 1: Attempt for writing in overflowing FM"
285
+ when 18 then errors.add :base, "Fiscal error 2: Incorrect structure in fiscal part 1"
286
+ when 19 then errors.add :base, "Fiscal error 3: Control sum error"
287
+ when 20 then errors.add :base, "Fiscal error 4: Incorrect structure in fiscal part 2"
288
+ when 21 then errors.add :base, "Fiscal error 5: No connection with the fiscal memory"
289
+ when 22 then errors.add :base, "Fiscal error 6: Incorrect record structure"
290
+ when 23 then errors.add :base, "Fiscal error 7: Fiscal memory overflow"
291
+
292
+ when 32 then errors.add :base, "No connection with terminal"
293
+ when 33 then errors.add :base, "No valid registration (IMSI on the SIM is different than the one recorded in fiscal memory"
294
+ when 34 then errors.add :base, "Not used"
295
+ when 35 then errors.add :base, "3 Daily reports with zeroing and no connection with NRA’s server"
296
+ when 36 then errors.add :base, "Missing or invalid SIM card"
297
+ when 37 then errors.add :base, "GSM module data reading error"
298
+ when 38 then errors.add :base, "Terminal data memory error"
299
+ when 39 then errors.add :base, "Terminal data memory damaged"
300
+ when 40 then errors.add :base, "GSM module error (registration not possible, wrong PIN, damaged GSM module)"
301
+ when 41 then errors.add :base, "KLEN SD card is not valid"
302
+ when 42 then errors.add :base, "KLEN SD card is missing"
303
+ when 43 then errors.add :base, "KLEN SD card data error"
304
+ when 44 then errors.add :base, "New KLEN SD card is put in a terminal with sales registration in RAM memory (daily report with zeroing must be done before changing the KLEN SD cards)"
305
+ when 45 then errors.add :base, "New KLEN SD card is not registered because some fiscal parameters cannot be changed"
306
+ when 46 then errors.add :base, "New KLEN SD card is put and fiscalization must be done"
307
+ when 47 then errors.add :base, "Recognized a KLEN SD card from a different device – only reports are available"
308
+ end
309
+ when 0x70 then @ready = true
310
+ when 0x71 then @ready = false
311
+ when 0x7E then errors.add :base, "Failed RAM"
312
+ when 0x7F then errors.add :base, "Wrong command"
313
+ end
314
+ end
315
+ end
316
+
317
+ class PrinterStatus
318
+
319
+ def initialize(status)
320
+ end
321
+
322
+ def start_bon_flag?
323
+ end
324
+
325
+ def end_bon_flag?
326
+ end
327
+
328
+ def last_transaction
329
+ end
330
+
331
+ def transaction_count
332
+ end
333
+
334
+ def last_transaction_sum
335
+ end
336
+
337
+ def all_transaction_sum
338
+ end
339
+
340
+ def total_sum
341
+ end
342
+
343
+ def stl_discount_flag?
344
+ end
345
+
346
+ def last_recept_number
347
+ end
348
+
349
+ def last_invoice_number
350
+ end
351
+
352
+ def available_invoice_numbers
353
+ end
354
+
355
+ def plu_count_in_memory
356
+ end
357
+ end
358
+ end
359
+ end
@@ -1,3 +1,3 @@
1
1
  module Extface
2
- VERSION = "0.1.9"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extface
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Vangelov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-21 00:00:00.000000000 Z
11
+ date: 2014-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: 4.0.1
19
+ version: 4.0.5
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
- version: 4.0.1
26
+ version: 4.0.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: redis
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -98,9 +98,8 @@ files:
98
98
  - app/models/extface/driver.rb
99
99
  - app/models/extface/driver/daisy/commands_fx1200.rb
100
100
  - app/models/extface/driver/daisy_fx1200.rb
101
- - app/models/extface/driver/epson/esc_pos.rb
102
- - app/models/extface/driver/epson/fiscal.rb
103
- - app/models/extface/driver/epson_tm_u220.rb
101
+ - app/models/extface/driver/eltrade/commands_fp4.rb
102
+ - app/models/extface/driver/eltrade_tm_u220.rb
104
103
  - app/models/extface/driver/generic_pos.rb
105
104
  - app/models/extface/driver/star_scp700.rb
106
105
  - app/models/extface/driver/star_tsp200.rb
@@ -111,7 +110,7 @@ files:
111
110
  - app/views/extface/devices/index.html.erb
112
111
  - app/views/extface/devices/show.html.erb
113
112
  - app/views/extface/driver/daisy_fx1200/_settings.html.erb
114
- - app/views/extface/driver/epson_tm_u220/_settings.html.erb
113
+ - app/views/extface/driver/eltrade_tm_u220/_settings.html.erb
115
114
  - app/views/extface/driver/generic_pos/_settings.html.erb
116
115
  - app/views/extface/driver/star_scp700/_settings.html.erb
117
116
  - app/views/extface/driver/star_tsp200/_settings.html.erb
@@ -1,12 +0,0 @@
1
- require 'active_support/concern'
2
- module Extface
3
- module Driver::Epson::EscPos
4
-
5
- def autocut(partial = true) # (Function B)
6
- # <GS> 'V' 0x65 x - Full-cut command
7
- # <GS> 'V' 0x66 x - Partial-cut command
8
- push partial ? "\x1D\x56\x65\x03" : "\x1D\x56\x66\x03"
9
- end
10
-
11
- end
12
- end
@@ -1,99 +0,0 @@
1
- module Extface
2
- module Driver::Epson::Fiscal
3
- STX = 0x02
4
- ETX = 0x03
5
- SEP = 0x1c
6
- DC2 = 0x12
7
- DC4 = 0x14
8
- NAK = 0x15
9
-
10
- module Control
11
- STATUS_IF = 0x38
12
- X_Z_REPORTS = 0x39
13
- FISC_MEM_REPORT_DATE = 0x3a
14
- FISC_MEM_REPORT = 0x3b
15
- end
16
- module Vouchers
17
- OPEN_FISCAL_VOUCHER = 0x40
18
- PRINT_FISCAL_TEXT = 0x41
19
- PRINT_FISCAL_ARTICLE = 0x42
20
- SUBTOTAL_FISCAL = 0x43
21
- FISCAL_VOUCHER = 0x44 # pay / cancel / discount in
22
- CLOSE_FISCAL_VOUCHER = 0x45
23
- end
24
- module NonFiscal
25
- OPEN_NON_FISCAL_DOC = 0x48
26
- PRINT_NON_FISCAL_TEXT = 0x49
27
- CLOSE_NON_FISCAL_DOC = 0x4a
28
- end
29
- module Printer
30
- CUT_PAPER = 0x4b
31
- ADVANCE_PAPER = 0x50
32
- ACTIVATE_SLIP = 0xa0 #TMU950, TMU675
33
- DISABLE_SLIP = 0xa1
34
- FORMAT_CHECKS = 0xaa
35
- FORMAT_ENDOSEMENT = 0xab
36
- end
37
- module General
38
- SET_DATE_HOUR = 0x58
39
- GET_DATE_HOUR = 0x59
40
- HEADED = 0x5d
41
- FOOT_OF_PAGE = 0x5e
42
- OPEN_DRAWER_1 = 0x7b
43
- OPEN_DRAWER_2 = 0x7c
44
- end
45
-
46
- def handle(buffer)
47
- bytes_processed = 0
48
- if frame_match = buffer.match(/\x02.*\x03.{4}/n)
49
- frame_data = frame_match.to_s
50
- rpush frame_data
51
- bytes_processed = frame_match.pre_match.length + frame_data.length
52
- end
53
- return bytes_processed
54
- end
55
-
56
- def build_packet(cmd, fields = [])
57
- String.new.tap() do |frame|
58
- frame << STX
59
- frame << sequence_number
60
- frame << cmd
61
- fields.each do |field|
62
- frame << SEP
63
- frame << field
64
- end
65
- frame << ETX
66
- frame << bcc(frame)
67
- end
68
- end
69
-
70
- private
71
- def bcc(buffer)
72
- sum = 0
73
- buffer.each_byte do |b|
74
- sum += b
75
- end
76
- sum.to_s(16).rjust(4, '0')
77
- end
78
-
79
- def sequence_number(increment = true)
80
- @seq ||= 0x20
81
- @seq += 1 if increment
82
- @seq = 0x20 if @seq == 0x7f
83
- @seq
84
- end
85
-
86
- class Frame
87
- include ActiveModel::Validations
88
- attr_reader :frame, :seq, :cmd, :fields_data, :fields, :bcc
89
-
90
- def initialize(buffer)
91
- if match = buffer.match(/\x02([\x20-\x7F])([\x30-\xaf])\x1c(.*)\x03(.{4})/n)
92
- @frame = match.to_a.first
93
- @seq, @cmd, @fileds_data, @bcc = match.captures
94
- @fields = @fields_data.split("\x1c")
95
- end
96
- end
97
- end
98
- end
99
- end
@@ -1,21 +0,0 @@
1
- require 'extface/driver/epson/esc_pos'
2
- require 'extface/driver/epson/fiscal'
3
- module Extface
4
- class Driver::EpsonTmU220 < Driver::GenericPos
5
- NAME = 'Epson TM-U220 (Serial)'.freeze
6
- GROUP = Extface::FISCAL_DRIVER
7
-
8
- DEVELOPMENT = true #driver is not ready for production (not passing all tests or has major bugs)
9
-
10
- # Select driver features
11
- RAW = true #responds to #push(data) and #pull
12
- PRINT = true #POS, slip printers
13
- FISCAL = true #cash registers, fiscal printers
14
- REPORT = false #only transmit data that must be parsed by handler, CDR, report devices
15
-
16
- has_serial_config
17
-
18
- include Extface::Driver::Epson::EscPos
19
- include Extface::Driver::Epson::Fiscal
20
- end
21
- end