Commit 6ceba60f5846a5dde0bb9de9318739e55b1ee703

Authored by Adhidarma Hadiwinoto
1 parent d66608f597
Exists in master

hapus last_product ketika gagal transaksi

Showing 1 changed file with 2 additions and 0 deletions Inline Diff

1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 2
3 import logging 3 import logging
4 from logging.handlers import TimedRotatingFileHandler 4 from logging.handlers import TimedRotatingFileHandler
5 import ConfigParser 5 import ConfigParser
6 import json 6 import json
7 from os import getpid 7 from os import getpid
8 import re 8 import re
9 import signal 9 import signal
10 import sys 10 import sys
11 11
12 config = ConfigParser.RawConfigParser() 12 config = ConfigParser.RawConfigParser()
13 config.read('config.ini') 13 config.read('config.ini')
14 14
15 PORT = config.get('globals','PORT') 15 PORT = config.get('globals','PORT')
16 BAUDRATE = config.getint('globals', 'BAUDRATE') 16 BAUDRATE = config.getint('globals', 'BAUDRATE')
17 PIN = None # SIM card PIN (if any) 17 PIN = None # SIM card PIN (if any)
18 PIN_TRX = config.get('globals', 'PIN_TRX') 18 PIN_TRX = config.get('globals', 'PIN_TRX')
19 19
20 BASE_CHIPINFO = config.get('globals', 'BASE_CHIPINFO') 20 BASE_CHIPINFO = config.get('globals', 'BASE_CHIPINFO')
21 CHIPINFO = BASE_CHIPINFO 21 CHIPINFO = BASE_CHIPINFO
22 22
23 AAA_HOST = config.get('globals', 'AAA_HOST') 23 AAA_HOST = config.get('globals', 'AAA_HOST')
24 CITY = config.get('globals', 'CITY') 24 CITY = config.get('globals', 'CITY')
25 PRODUCTS = config.get('globals', 'PRODUCTS') 25 PRODUCTS = config.get('globals', 'PRODUCTS')
26 26
27 REDIS_HOST = config.get('globals', 'REDIS_HOST') 27 REDIS_HOST = config.get('globals', 'REDIS_HOST')
28 REDIS_PORT = config.getint('globals', 'REDIS_PORT') 28 REDIS_PORT = config.getint('globals', 'REDIS_PORT')
29 REDIS_TTL = config.getint('globals', 'REDIS_TTL') 29 REDIS_TTL = config.getint('globals', 'REDIS_TTL')
30 REDIS_DISABLE_PULL_TTL = config.getint('globals', 'REDIS_DISABLE_PULL_TTL') 30 REDIS_DISABLE_PULL_TTL = config.getint('globals', 'REDIS_DISABLE_PULL_TTL')
31 31
32 PULL_INTERVAL = config.getint('globals', 'PULL_INTERVAL') 32 PULL_INTERVAL = config.getint('globals', 'PULL_INTERVAL')
33 SLEEP_AFTER_TOPUP = config.getint('globals', 'SLEEP_AFTER_TOPUP') 33 SLEEP_AFTER_TOPUP = config.getint('globals', 'SLEEP_AFTER_TOPUP')
34 SLEEP_BETWEEN_BALANCE_N_TOPUP = config.getint('globals', 'SLEEP_BETWEEN_BALANCE_N_TOPUP') 34 SLEEP_BETWEEN_BALANCE_N_TOPUP = config.getint('globals', 'SLEEP_BETWEEN_BALANCE_N_TOPUP')
35 TOPUP_USSD_TIMEOUT = config.getint('globals', 'TOPUP_USSD_TIMEOUT') 35 TOPUP_USSD_TIMEOUT = config.getint('globals', 'TOPUP_USSD_TIMEOUT')
36 SLEEP_AFTER_USSD_ERROR = 180 36 SLEEP_AFTER_USSD_ERROR = 180
37 37
38 MIN_SIGNAL_STRENGTH = 0 38 MIN_SIGNAL_STRENGTH = 0
39 try: 39 try:
40 MIN_SIGNAL_STRENGTH = config.getint('globals', 'MIN_SIGNAL_STRENGTH') 40 MIN_SIGNAL_STRENGTH = config.getint('globals', 'MIN_SIGNAL_STRENGTH')
41 except: 41 except:
42 pass 42 pass
43 if not MIN_SIGNAL_STRENGTH: 43 if not MIN_SIGNAL_STRENGTH:
44 MIN_SIGNAL_STRENGTH = 13 44 MIN_SIGNAL_STRENGTH = 13
45 45
46 MIN_BALANCE = config.getint('globals', 'MIN_BALANCE') 46 MIN_BALANCE = config.getint('globals', 'MIN_BALANCE')
47 47
48 PULL_COUNT = 0 48 PULL_COUNT = 0
49 MSISDN = '' 49 MSISDN = ''
50 BALANCE = 0 50 BALANCE = 0
51 51
52 DISABLE_SEM=0 52 DISABLE_SEM=0
53 DISABLE_SEM_ON_TRX=60 53 DISABLE_SEM_ON_TRX=60
54 54
55 TERMINATING=False 55 TERMINATING=False
56 56
57 LAST_REQUEST_ID = None 57 LAST_REQUEST_ID = None
58 LAST_SN = None 58 LAST_SN = None
59 LAST_PRODUCT = '' 59 LAST_PRODUCT = ''
60 60
61 PULSA = 0 61 PULSA = 0
62 MASA_AKTIF = "" 62 MASA_AKTIF = ""
63 63
64 logger = None 64 logger = None
65 65
66 from gsmmodem.modem import GsmModem 66 from gsmmodem.modem import GsmModem
67 from gsmmodem.exceptions import TimeoutException 67 from gsmmodem.exceptions import TimeoutException
68 68
69 from time import sleep 69 from time import sleep
70 from time import strftime 70 from time import strftime
71 71
72 import redis 72 import redis
73 import requests 73 import requests
74 74
75 import sate24 75 import sate24
76 import xltunai 76 import xltunai
77 77
78 redis_client = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=0) 78 redis_client = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, db=0)
79 79
80 def signalHandler(signum, frame): 80 def signalHandler(signum, frame):
81 global TERMINATING 81 global TERMINATING
82 82
83 if signum == signal.SIGINT or signum == signal.SIGTERM: 83 if signum == signal.SIGINT or signum == signal.SIGTERM:
84 logger.info('Signal ({0}) received, waiting for next loop to terminate. Terminating...'.format(signum)) 84 logger.info('Signal ({0}) received, waiting for next loop to terminate. Terminating...'.format(signum))
85 TERMINATING = True 85 TERMINATING = True
86 86
87 def createDenyProductFile(product): 87 def createDenyProductFile(product):
88 f = open('{0}.deny'.format(product), 'w') 88 f = open('{0}.deny'.format(product), 'w')
89 f.write(product) 89 f.write(product)
90 f.close() 90 f.close()
91 91
92 def handleSms(sms): 92 def handleSms(sms):
93 global CHIPINFO 93 global CHIPINFO
94 global DISABLE_SEM 94 global DISABLE_SEM
95 global PRODUCTS 95 global PRODUCTS
96 global LAST_PRODUCT 96 global LAST_PRODUCT
97 global LAST_REQUEST_ID 97 global LAST_REQUEST_ID
98 global LAST_SN 98 global LAST_SN
99 99
100 try: 100 try:
101 logger.info(u'Incoming SMS from: {0}; Time: {1}; Message: {2}'.format(sms.number, sms.time, sms.text)) 101 logger.info(u'Incoming SMS from: {0}; Time: {1}; Message: {2}'.format(sms.number, sms.time, sms.text))
102 except: 102 except:
103 logger.info(u'Incoming SMS from: {0}; Time: {1}; Message: BINARY'.format(sms.number, sms.time)) 103 logger.info(u'Incoming SMS from: {0}; Time: {1}; Message: BINARY'.format(sms.number, sms.time))
104 104
105 try: 105 try:
106 epic_key = 'epic.msgin.gw:' + BASE_CHIPINFO 106 epic_key = 'epic.msgin.gw:' + BASE_CHIPINFO
107 redis_client.publish(epic_key + '.message', u'{0}: {1} ({2})'.format(sms.number, sms.text, CHIPINFO)) 107 redis_client.publish(epic_key + '.message', u'{0}: {1} ({2})'.format(sms.number, sms.text, CHIPINFO))
108 except: 108 except:
109 logger.warning('Fail to publish epic message to redis') 109 logger.warning('Fail to publish epic message to redis')
110 110
111 if not xltunai.isValidSender(sms.number): 111 if not xltunai.isValidSender(sms.number):
112 logger.info('Ignoring incoming SMS from invalid sender') 112 logger.info('Ignoring incoming SMS from invalid sender')
113 return 113 return
114 114
115 if sms.text.find('Terimakasih, transaksi CASH IN ke akun') >= 0: 115 if sms.text.find('Terimakasih, transaksi CASH IN ke akun') >= 0:
116 logger.info('handleSms: CASH IN, aktivasi pull jika non aktif') 116 logger.info('handleSms: CASH IN, aktivasi pull jika non aktif')
117 117
118 LAST_SN = xltunai.getSNFromCashInMessage(sms.text) 118 LAST_SN = xltunai.getSNFromCashInMessage(sms.text)
119 logger.info('Override LAST_SN: {0}'.format(LAST_SN)) 119 logger.info('Override LAST_SN: {0}'.format(LAST_SN))
120 120
121 enablePull() 121 enablePull()
122 return 122 return
123 123
124 if sms.text.find('Maaf, transaksi gagal') >= 0: 124 if sms.text.find('Maaf, transaksi gagal') >= 0:
125 pushTopupStatus(LAST_REQUEST_ID, '40', sms.text) 125 pushTopupStatus(LAST_REQUEST_ID, '40', sms.text)
126 createDenyProductFile('ALL');
127 PRODUCTS = sate24.removeProduct(PRODUCTS, LAST_PRODUCT)
126 return 128 return
127 129
128 if sms.text.find('PIN yang Anda masukkan salah. Silahkan ulangi kembali') >= 0: 130 if sms.text.find('PIN yang Anda masukkan salah. Silahkan ulangi kembali') >= 0:
129 pushTopupStatus(LAST_REQUEST_ID, '91', sms.text) 131 pushTopupStatus(LAST_REQUEST_ID, '91', sms.text)
130 return 132 return
131 133
132 if sms.text.find('Maaf, saldo XL-Tunai anda tidak cukup') >= 0: 134 if sms.text.find('Maaf, saldo XL-Tunai anda tidak cukup') >= 0:
133 pushTopupStatus(LAST_REQUEST_ID, '40', sms.text) 135 pushTopupStatus(LAST_REQUEST_ID, '40', sms.text)
134 return 136 return
135 137
136 if sms.text.find('Maaf, layanan ini hanya untuk nomor tujuan prabayar XL') >= 0: 138 if sms.text.find('Maaf, layanan ini hanya untuk nomor tujuan prabayar XL') >= 0:
137 pushTopupStatus(LAST_REQUEST_ID, '14', sms.text) 139 pushTopupStatus(LAST_REQUEST_ID, '14', sms.text)
138 return 140 return
139 141
140 if sms.text.find('Mohon maaf, nomor yang Anda masukkan tidak valid') >= 0: 142 if sms.text.find('Mohon maaf, nomor yang Anda masukkan tidak valid') >= 0:
141 pushTopupStatus(LAST_REQUEST_ID, '14', sms.text) 143 pushTopupStatus(LAST_REQUEST_ID, '14', sms.text)
142 return 144 return
143 145
144 if sms.text.find('Mohon maaf, transaksi Anda melebihi limit nominal bulanan') >= 0: 146 if sms.text.find('Mohon maaf, transaksi Anda melebihi limit nominal bulanan') >= 0:
145 pushTopupStatus(LAST_REQUEST_ID, '40', sms.text) 147 pushTopupStatus(LAST_REQUEST_ID, '40', sms.text)
146 148
147 logger.info('Monthly limit for "{0}" detected, removing from product list'.format(LAST_PRODUCT)) 149 logger.info('Monthly limit for "{0}" detected, removing from product list'.format(LAST_PRODUCT))
148 PRODUCTS = sate24.removeProduct(PRODUCTS, LAST_PRODUCT) 150 PRODUCTS = sate24.removeProduct(PRODUCTS, LAST_PRODUCT)
149 logger.warning('Monthly limit for "{0}" exceeded. New active products: "{1}"'.format(LAST_PRODUCT, PRODUCTS)) 151 logger.warning('Monthly limit for "{0}" exceeded. New active products: "{1}"'.format(LAST_PRODUCT, PRODUCTS))
150 createDenyProductFile(LAST_PRODUCT) 152 createDenyProductFile(LAST_PRODUCT)
151 return 153 return
152 154
153 if sms.text.find('Maaf, transaksi Anda masih dalam proses') >= 0: 155 if sms.text.find('Maaf, transaksi Anda masih dalam proses') >= 0:
154 pushTopupStatus(LAST_REQUEST_ID, '68', sms.text) 156 pushTopupStatus(LAST_REQUEST_ID, '68', sms.text)
155 return 157 return
156 158
157 if sms.text.find('Maaf, saat ini sistem sedang proses maintenance') >= 0: 159 if sms.text.find('Maaf, saat ini sistem sedang proses maintenance') >= 0:
158 pushTopupStatus(LAST_REQUEST_ID, '91', sms.text) 160 pushTopupStatus(LAST_REQUEST_ID, '91', sms.text)
159 return 161 return
160 162
161 if sms.text.find('Anda terima uang XLTunai') >= 0: 163 if sms.text.find('Anda terima uang XLTunai') >= 0:
162 LAST_SN = xltunai.getSNFromReceiveTransferMessage(sms.text) 164 LAST_SN = xltunai.getSNFromReceiveTransferMessage(sms.text)
163 logger.info('Override LAST_SN: {0}'.format(LAST_SN)) 165 logger.info('Override LAST_SN: {0}'.format(LAST_SN))
164 return 166 return
165 167
166 if sms.text.find('Kirim uang ke ') == 0: 168 if sms.text.find('Kirim uang ke ') == 0:
167 LAST_SN = xltunai.getSNFromSentTransferMessage(sms.text) 169 LAST_SN = xltunai.getSNFromSentTransferMessage(sms.text)
168 logger.info('Override LAST_SN: {0}'.format(LAST_SN)) 170 logger.info('Override LAST_SN: {0}'.format(LAST_SN))
169 return 171 return
170 172
171 destination = xltunai.getDestinationFromMessage(sms.text) 173 destination = xltunai.getDestinationFromMessage(sms.text)
172 if destination == '': 174 if destination == '':
173 logger.warning('handleSms: gagal parsing nomor tujuan') 175 logger.warning('handleSms: gagal parsing nomor tujuan')
174 return 176 return
175 177
176 nominal = xltunai.getNominalFromMessage(sms.text) 178 nominal = xltunai.getNominalFromMessage(sms.text)
177 if nominal == '': 179 if nominal == '':
178 logger.warning('handleSms: gagal parsing nominal') 180 logger.warning('handleSms: gagal parsing nominal')
179 return 181 return
180 182
181 sn = xltunai.getSNFromMessage(sms.text) 183 sn = xltunai.getSNFromMessage(sms.text)
182 if sn == '': 184 if sn == '':
183 logger.warning('handleSms: gagal parsing SN') 185 logger.warning('handleSms: gagal parsing SN')
184 186
185 187
186 DISABLE_SEM = 0 188 DISABLE_SEM = 0
187 189
188 response_code = xltunai.getResponseCodeByMessage(sms.text) 190 response_code = xltunai.getResponseCodeByMessage(sms.text)
189 191
190 request_id = getRequestIdByNominalDestination(nominal, destination) 192 request_id = getRequestIdByNominalDestination(nominal, destination)
191 if not request_id: 193 if not request_id:
192 logger.info('Unknown request id for nominal:{0} destination:{1}'.format(nominal, destination)) 194 logger.info('Unknown request id for nominal:{0} destination:{1}'.format(nominal, destination))
193 return 195 return
194 196
195 pushTopupStatus(request_id, response_code, sms.text) 197 pushTopupStatus(request_id, response_code, sms.text)
196 try: 198 try:
197 deleteMultipleStoredSms(2) 199 deleteMultipleStoredSms(2)
198 except: 200 except:
199 #logger.warning('Failed on delete SMS') 201 #logger.warning('Failed on delete SMS')
200 pass 202 pass
201 203
202 204
203 def getRequestIdByNominalDestination(nominal, destination): 205 def getRequestIdByNominalDestination(nominal, destination):
204 global CHIPINFO 206 global CHIPINFO
205 207
206 redis_key = sate24.keyByNominalDestination(CHIPINFO, nominal, destination) 208 redis_key = sate24.keyByNominalDestination(CHIPINFO, nominal, destination)
207 #return redis_client.spop(redis_key) 209 #return redis_client.spop(redis_key)
208 return redis_client.rpop(redis_key) 210 return redis_client.rpop(redis_key)
209 211
210 def pushTopupStatus(request_id, response_code, _message, dontparsesn = False): 212 def pushTopupStatus(request_id, response_code, _message, dontparsesn = False):
211 global BALANCE 213 global BALANCE
212 global CHIPINFO 214 global CHIPINFO
213 global LAST_SN 215 global LAST_SN
214 216
215 redis_key = sate24.keyByRequestId(CHIPINFO, request_id) + '.response_code' 217 redis_key = sate24.keyByRequestId(CHIPINFO, request_id) + '.response_code'
216 if response_code == '00': 218 if response_code == '00':
217 redis_client.set(redis_key, response_code) 219 redis_client.set(redis_key, response_code)
218 else: 220 else:
219 redis_response_code = redis_client.get(redis_key) 221 redis_response_code = redis_client.get(redis_key)
220 if redis_response_code == '00': 222 if redis_response_code == '00':
221 logger.info('Ignoring message from success trx ') 223 logger.info('Ignoring message from success trx ')
222 return 224 return
223 225
224 message = "{0} -- Prev balance: {1}".format(_message, BALANCE) 226 message = "{0} -- Prev balance: {1}".format(_message, BALANCE)
225 227
226 timestamp = strftime('%Y%m%d%H%M%S') 228 timestamp = strftime('%Y%m%d%H%M%S')
227 229
228 if response_code == '00' and not dontparsesn: 230 if response_code == '00' and not dontparsesn:
229 sn = xltunai.getSNFromMessage(message) 231 sn = xltunai.getSNFromMessage(message)
230 LAST_SN = sn 232 LAST_SN = sn
231 message = 'SN={0};{1}'.format(sn, message) 233 message = 'SN={0};{1}'.format(sn, message)
232 234
233 push_message = CHIPINFO + '$' + message 235 push_message = CHIPINFO + '$' + message
234 236
235 payload = { 237 payload = {
236 'trans_id': request_id, 238 'trans_id': request_id,
237 'trans_date': timestamp, 239 'trans_date': timestamp,
238 'resp_code': response_code, 240 'resp_code': response_code,
239 'ussd_msg': push_message 241 'ussd_msg': push_message
240 } 242 }
241 243
242 url = AAA_HOST + '/topup' 244 url = AAA_HOST + '/topup'
243 245
244 try: 246 try:
245 logger.info('Sending topup status to AAA') 247 logger.info('Sending topup status to AAA')
246 logger.info(payload) 248 logger.info(payload)
247 r = requests.get(url, params=payload) 249 r = requests.get(url, params=payload)
248 except: 250 except:
249 logger.warning('Error sending topup status to AAA') 251 logger.warning('Error sending topup status to AAA')
250 252
251 try: 253 try:
252 # publish echi topup report ke redis 254 # publish echi topup report ke redis
253 echi_key = 'echi.topup_report.gw:' + BASE_CHIPINFO 255 echi_key = 'echi.topup_report.gw:' + BASE_CHIPINFO
254 256
255 redis_client.publish(echi_key + '.json', json.dumps(payload)) 257 redis_client.publish(echi_key + '.json', json.dumps(payload))
256 258
257 echi_message = timestamp + ' - ' + response_code + ' - ' + message 259 echi_message = timestamp + ' - ' + response_code + ' - ' + message
258 redis_client.publish(echi_key + '.message', echi_message) 260 redis_client.publish(echi_key + '.message', echi_message)
259 except: 261 except:
260 logger.warning('Error publishing topup report to redis') 262 logger.warning('Error publishing topup report to redis')
261 263
262 def getIsDisableRedisKey(): 264 def getIsDisableRedisKey():
263 return CHIPINFO + '.pulldisable' 265 return CHIPINFO + '.pulldisable'
264 266
265 def isPullEnable(): 267 def isPullEnable():
266 redis_key = getIsDisableRedisKey() 268 redis_key = getIsDisableRedisKey()
267 result = 'FALSE' 269 result = 'FALSE'
268 270
269 try: 271 try:
270 result = redis_client.get(redis_key) 272 result = redis_client.get(redis_key)
271 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL) 273 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL)
272 except: 274 except:
273 return False 275 return False
274 276
275 if not result: 277 if not result:
276 return True 278 return True
277 279
278 return result == 'FALSE' 280 return result == 'FALSE'
279 281
280 def enablePull(): 282 def enablePull():
281 logger.info('Enabling Pull on products {0}'.format(PRODUCTS)) 283 logger.info('Enabling Pull on products {0}'.format(PRODUCTS))
282 redis_key = getIsDisableRedisKey() 284 redis_key = getIsDisableRedisKey()
283 try: 285 try:
284 redis_client.set(redis_key, 'FALSE') 286 redis_client.set(redis_key, 'FALSE')
285 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL) 287 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL)
286 except: 288 except:
287 return 289 return
288 290
289 def disablePull(): 291 def disablePull():
290 global DISABLE_SEM 292 global DISABLE_SEM
291 global DISABLE_SEM_ON_TRX 293 global DISABLE_SEM_ON_TRX
292 294
293 logger.info('Disabling Pull') 295 logger.info('Disabling Pull')
294 redis_key = getIsDisableRedisKey() 296 redis_key = getIsDisableRedisKey()
295 try: 297 try:
296 redis_client.set(redis_key, 'TRUE') 298 redis_client.set(redis_key, 'TRUE')
297 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL) 299 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL)
298 except: 300 except:
299 return 301 return
300 302
301 def adviceLastSN(requestId, modem): 303 def adviceLastSN(requestId, modem):
302 global DISABLE_SEM 304 global DISABLE_SEM
303 global LAST_SN 305 global LAST_SN
304 global TOPUP_USSD_TIMEOUT 306 global TOPUP_USSD_TIMEOUT
305 307
306 if not LAST_SN: 308 if not LAST_SN:
307 message = 'Tidak ada trx sebelumnya untuk perbandingan SN. Silahkan bandingkan prev balance dengan trx berikutnya di chip yang sama' 309 message = 'Tidak ada trx sebelumnya untuk perbandingan SN. Silahkan bandingkan prev balance dengan trx berikutnya di chip yang sama'
308 pushTopupStatus(requestId, '68', message) 310 pushTopupStatus(requestId, '68', message)
309 DISABLE_SEM = 0 311 DISABLE_SEM = 0
310 return 312 return
311 313
312 ussd_command = xltunai.getHistoryUSSDCommand() 314 ussd_command = xltunai.getHistoryUSSDCommand()
313 315
314 logger.info(u'Executing advice {0}'.format(ussd_command)) 316 logger.info(u'Executing advice {0}'.format(ussd_command))
315 try: 317 try:
316 response = modem.sendUssd(ussd_command, TOPUP_USSD_TIMEOUT) 318 response = modem.sendUssd(ussd_command, TOPUP_USSD_TIMEOUT)
317 319
318 message = response.message.strip() 320 message = response.message.strip()
319 logger.info(u'USSD response: {0}'.format(message)) 321 logger.info(u'USSD response: {0}'.format(message))
320 322
321 lastSNFromHistory = xltunai.getLastSNFromHistoryMessage(message) 323 lastSNFromHistory = xltunai.getLastSNFromHistoryMessage(message)
322 lastTrxTypeFromHistory = xltunai.getLastTrxTypeFromMessage(message) 324 lastTrxTypeFromHistory = xltunai.getLastTrxTypeFromMessage(message)
323 325
324 if response.sessionActive: 326 if response.sessionActive:
325 response.cancel() 327 response.cancel()
326 328
327 if not lastSNFromHistory: 329 if not lastSNFromHistory:
328 if DISABLE_SEM: 330 if DISABLE_SEM:
329 logger.info('Failed to get last sn from history, retrying in 15 secs') 331 logger.info('Failed to get last sn from history, retrying in 15 secs')
330 sleep(15) 332 sleep(15)
331 adviceLastSN(requestid, modem) 333 adviceLastSN(requestid, modem)
332 334
333 elif lastTrxTypeFromHistory and lastTrxTypeFromHistory.find('RELOAD') < 0: 335 elif lastTrxTypeFromHistory and lastTrxTypeFromHistory.find('RELOAD') < 0:
334 topupMessage = "Topup gagal berdasarkan advice. Trx terakhir adalah P2P Transfer." 336 topupMessage = "Topup gagal berdasarkan advice. Trx terakhir adalah P2P Transfer."
335 pushTopupStatus(requestId, '40', topupMessage) 337 pushTopupStatus(requestId, '40', topupMessage)
336 DISABLE_SEM = 0 338 DISABLE_SEM = 0
337 339
338 elif lastSNFromHistory == LAST_SN: 340 elif lastSNFromHistory == LAST_SN:
339 topupMessage = "Topup gagal berdasarkan advice. {0} = {1}. {2}".format(lastSNFromHistory, LAST_SN, message) 341 topupMessage = "Topup gagal berdasarkan advice. {0} = {1}. {2}".format(lastSNFromHistory, LAST_SN, message)
340 pushTopupStatus(requestId, '40', topupMessage) 342 pushTopupStatus(requestId, '40', topupMessage)
341 DISABLE_SEM = 0 343 DISABLE_SEM = 0
342 344
343 else: 345 else:
344 topupMessage = "SN={0}; Topup berhasil berdasarkan advice. {1}".format(lastSNFromHistory, message) 346 topupMessage = "SN={0}; Topup berhasil berdasarkan advice. {1}".format(lastSNFromHistory, message)
345 LAST_SN = lastSNFromHistory 347 LAST_SN = lastSNFromHistory
346 pushTopupStatus(requestId, '00', topupMessage, True) 348 pushTopupStatus(requestId, '00', topupMessage, True)
347 DISABLE_SEM = 0 349 DISABLE_SEM = 0
348 350
349 except: 351 except:
350 message = "USSD Error: Something wrong when executing USSD advice. Signal strength: {0}".format(modem.signalStrength) 352 message = "USSD Error: Something wrong when executing USSD advice. Signal strength: {0}".format(modem.signalStrength)
351 logger.warning(message) 353 logger.warning(message)
352 pushTopupStatus(requestId, '68', message) 354 pushTopupStatus(requestId, '68', message)
353 355
354 sleep(60) 356 sleep(60)
355 adviceLastSN(requestId, modem) 357 adviceLastSN(requestId, modem)
356 #waitForResultSmsAfterUssdError(modem, task['requestId'], message) 358 #waitForResultSmsAfterUssdError(modem, task['requestId'], message)
357 return 359 return
358 360
359 361
360 362
361 def topupTask(task, modem): 363 def topupTask(task, modem):
362 global LAST_REQUEST_ID 364 global LAST_REQUEST_ID
363 global LAST_PRODUCT 365 global LAST_PRODUCT
364 366
365 if not task: 367 if not task:
366 return 368 return
367 369
368 if task['status'] != 'OK': 370 if task['status'] != 'OK':
369 return 371 return
370 372
371 LAST_REQUEST_ID = task['requestId'] 373 LAST_REQUEST_ID = task['requestId']
372 LAST_PRODUCT = task['product'].upper() 374 LAST_PRODUCT = task['product'].upper()
373 375
374 redis_key = sate24.keyByRequestId(CHIPINFO, task['requestId']) 376 redis_key = sate24.keyByRequestId(CHIPINFO, task['requestId'])
375 redis_client.set(redis_key, task) 377 redis_client.set(redis_key, task)
376 redis_client.expire(redis_key, REDIS_TTL) 378 redis_client.expire(redis_key, REDIS_TTL)
377 379
378 nominal = xltunai.getNominalFromProduct(task['product']) 380 nominal = xltunai.getNominalFromProduct(task['product'])
379 intl_destination = xltunai.toInternationalNumber(task['destination']) 381 intl_destination = xltunai.toInternationalNumber(task['destination'])
380 382
381 redis_key = sate24.keyByNominalDestination(CHIPINFO, nominal, intl_destination) 383 redis_key = sate24.keyByNominalDestination(CHIPINFO, nominal, intl_destination)
382 #redis_client.sadd(redis_key, task['requestId']) 384 #redis_client.sadd(redis_key, task['requestId'])
383 try: 385 try:
384 redis_client.rpush(redis_key, task['requestId']) 386 redis_client.rpush(redis_key, task['requestId'])
385 except: 387 except:
386 redis_client.delete(redis_key) 388 redis_client.delete(redis_key)
387 redis_client.rpush(redis_key, task['requestId']) 389 redis_client.rpush(redis_key, task['requestId'])
388 finally: 390 finally:
389 redis_client.expire(redis_key, REDIS_TTL) 391 redis_client.expire(redis_key, REDIS_TTL)
390 392
391 #pushTopupStatus(task['requestId'], '68', 'Siap mengirimkan trx ke operator') 393 #pushTopupStatus(task['requestId'], '68', 'Siap mengirimkan trx ke operator')
392 394
393 message = 'Executing USSD' 395 message = 'Executing USSD'
394 response_code = '68' 396 response_code = '68'
395 397
396 ussd_command = xltunai.getTopupUSSDCommand(task['destination'], task['product'], PIN_TRX) 398 ussd_command = xltunai.getTopupUSSDCommand(task['destination'], task['product'], PIN_TRX)
397 399
398 logger.info(u'Executing {0}'.format(ussd_command)) 400 logger.info(u'Executing {0}'.format(ussd_command))
399 try: 401 try:
400 response = modem.sendUssd(ussd_command, TOPUP_USSD_TIMEOUT) 402 response = modem.sendUssd(ussd_command, TOPUP_USSD_TIMEOUT)
401 403
402 message = response.message.strip() 404 message = response.message.strip()
403 logger.info(u'USSD response: {0}'.format(message)) 405 logger.info(u'USSD response: {0}'.format(message))
404 406
405 response_code = xltunai.getResponseCodeByUSSDResponse(message) 407 response_code = xltunai.getResponseCodeByUSSDResponse(message)
406 408
407 if response.sessionActive: 409 if response.sessionActive:
408 response.cancel() 410 response.cancel()
409 411
410 except TimeoutException: 412 except TimeoutException:
411 message = "USSD Error: Timeout when executing USSD topup. Signal strength: {0}".format(modem.signalStrength) 413 message = "USSD Error: Timeout when executing USSD topup. Signal strength: {0}".format(modem.signalStrength)
412 logger.warning(message) 414 logger.warning(message)
413 pushTopupStatus(task['requestId'], '68', message) 415 pushTopupStatus(task['requestId'], '68', message)
414 #waitForResultSmsAfterUssdError(modem, task['requestId'], message) 416 #waitForResultSmsAfterUssdError(modem, task['requestId'], message)
415 sleep(15) 417 sleep(15)
416 adviceLastSN(task['requestId'], modem) 418 adviceLastSN(task['requestId'], modem)
417 return 419 return
418 except: 420 except:
419 message = "USSD Error: Something wrong when executing USSD topup. Signal strength: {0}".format(modem.signalStrength) 421 message = "USSD Error: Something wrong when executing USSD topup. Signal strength: {0}".format(modem.signalStrength)
420 logger.warning(message) 422 logger.warning(message)
421 pushTopupStatus(task['requestId'], '68', message) 423 pushTopupStatus(task['requestId'], '68', message)
422 #waitForResultSmsAfterUssdError(modem, task['requestId'], message) 424 #waitForResultSmsAfterUssdError(modem, task['requestId'], message)
423 sleep(15) 425 sleep(15)
424 adviceLastSN(task['requestId'], modem) 426 adviceLastSN(task['requestId'], modem)
425 return 427 return
426 428
427 DISABLE_SEM = DISABLE_SEM_ON_TRX 429 DISABLE_SEM = DISABLE_SEM_ON_TRX
428 pushTopupStatus(task['requestId'], response_code, message) 430 pushTopupStatus(task['requestId'], response_code, message)
429 431
430 def waitForResultSmsAfterUssdError(modem, request_id, last_error_message = ''): 432 def waitForResultSmsAfterUssdError(modem, request_id, last_error_message = ''):
431 logger.info('Sleeping for {0} seconds after an USSD error'.format(SLEEP_AFTER_USSD_ERROR)) 433 logger.info('Sleeping for {0} seconds after an USSD error'.format(SLEEP_AFTER_USSD_ERROR))
432 sleep(SLEEP_AFTER_USSD_ERROR) 434 sleep(SLEEP_AFTER_USSD_ERROR)
433 435
434 redis_key = sate24.keyByRequestId(CHIPINFO, request_id) + '.response_code' 436 redis_key = sate24.keyByRequestId(CHIPINFO, request_id) + '.response_code'
435 response_code = redis_client.get(redis_key) 437 response_code = redis_client.get(redis_key)
436 438
437 if response_code == '68' or response_code == None: 439 if response_code == '68' or response_code == None:
438 440
439 prev_balance = BALANCE 441 prev_balance = BALANCE
440 current_balance = checkBalance(modem, do_not_update = True, return_result = True) 442 current_balance = checkBalance(modem, do_not_update = True, return_result = True)
441 443
442 if current_balance == 0: 444 if current_balance == 0:
443 return 445 return
444 446
445 if current_balance < prev_balance: 447 if current_balance < prev_balance:
446 delta = prev_balance - current_balance 448 delta = prev_balance - current_balance
447 pushTopupStatus( 449 pushTopupStatus(
448 request_id, 450 request_id,
449 '00', 451 '00',
450 'Transaksi dianggap sukses karena saldo berkurang {0}. Last error message: {1}'.format( 452 'Transaksi dianggap sukses karena saldo berkurang {0}. Last error message: {1}'.format(
451 delta, 453 delta,
452 last_error_message 454 last_error_message
453 ) 455 )
454 ) 456 )
455 else: 457 else:
456 pushTopupStatus( 458 pushTopupStatus(
457 request_id, 459 request_id,
458 '40', 460 '40',
459 'Transaksi dianggap gagal karena saldo tidak berkurang. Last error message: {0}'.format(last_error_message) 461 'Transaksi dianggap gagal karena saldo tidak berkurang. Last error message: {0}'.format(last_error_message)
460 ) 462 )
461 463
462 def _saveBalanceToRedis(balance_key, balance_value): 464 def _saveBalanceToRedis(balance_key, balance_value):
463 try: 465 try:
464 redis_client.set(balance_key, balance_value) 466 redis_client.set(balance_key, balance_value)
465 redis_client.expire(balance_key, 3600*24*60) 467 redis_client.expire(balance_key, 3600*24*60)
466 except: 468 except:
467 logger.warning('Failed to save balance to redis') 469 logger.warning('Failed to save balance to redis')
468 470
469 def saveBalanceToRedis(balance): 471 def saveBalanceToRedis(balance):
470 global BASE_CHIPINFO 472 global BASE_CHIPINFO
471 global CHIPINFO 473 global CHIPINFO
472 global MSISDN 474 global MSISDN
473 475
474 try: 476 try:
475 balance = int(balance) 477 balance = int(balance)
476 except ValueError: 478 except ValueError:
477 return 479 return
478 480
479 481
480 data = { 482 data = {
481 'balance.gw:' + BASE_CHIPINFO: balance, 483 'balance.gw:' + BASE_CHIPINFO: balance,
482 'balance.gw:' + CHIPINFO: balance, 484 'balance.gw:' + CHIPINFO: balance,
483 'balance.gw:' + MSISDN: balance 485 'balance.gw:' + MSISDN: balance
484 } 486 }
485 487
486 redis_pipe = redis_client.pipeline() 488 redis_pipe = redis_client.pipeline()
487 489
488 try: 490 try:
489 redis_pipe.mset(data) 491 redis_pipe.mset(data)
490 492
491 for k in data: 493 for k in data:
492 redis_pipe.expire(k, 3600 * 24 * 60) 494 redis_pipe.expire(k, 3600 * 24 * 60)
493 495
494 except: 496 except:
495 logger.warning('Failed to save balance to redis') 497 logger.warning('Failed to save balance to redis')
496 finally: 498 finally:
497 redis_pipe.execute() 499 redis_pipe.execute()
498 500
499 def saveSignalStrengthToRedis(value): 501 def saveSignalStrengthToRedis(value):
500 global BASE_CHIPINFO 502 global BASE_CHIPINFO
501 global CHIPINFO 503 global CHIPINFO
502 global MSISDN 504 global MSISDN
503 505
504 try: 506 try:
505 redis_pipe = redis_client.pipeline() 507 redis_pipe = redis_client.pipeline()
506 redis_client.set('balance.gw:' + BASE_CHIPINFO + '.signal', value) 508 redis_client.set('balance.gw:' + BASE_CHIPINFO + '.signal', value)
507 redis_client.expire('balance.gw:' + BASE_CHIPINFO + '.signal', 15 * 60) 509 redis_client.expire('balance.gw:' + BASE_CHIPINFO + '.signal', 15 * 60)
508 except: 510 except:
509 logger.warning('Failed to save signal strength to redis') 511 logger.warning('Failed to save signal strength to redis')
510 512
511 513
512 def pull(modem): 514 def pull(modem):
513 global PRODUCTS 515 global PRODUCTS
514 global PULL_COUNT 516 global PULL_COUNT
515 global BALANCE 517 global BALANCE
516 global DISABLE_SEM 518 global DISABLE_SEM
517 global MIN_SIGNAL_STRENGTH 519 global MIN_SIGNAL_STRENGTH
518 520
519 if not PRODUCTS: 521 if not PRODUCTS:
520 sleep(60) 522 sleep(60)
521 return 523 return
522 524
523 signalStrength = modem.signalStrength 525 signalStrength = modem.signalStrength
524 if signalStrength < MIN_SIGNAL_STRENGTH: 526 if signalStrength < MIN_SIGNAL_STRENGTH:
525 return 527 return
526 528
527 pull_per_minute = 60 / PULL_INTERVAL 529 pull_per_minute = 60 / PULL_INTERVAL
528 530
529 PULL_COUNT += 1 531 PULL_COUNT += 1
530 if PULL_COUNT % (5 * pull_per_minute) == 0: 532 if PULL_COUNT % (5 * pull_per_minute) == 0:
531 checkBalance(modem) 533 checkBalance(modem)
532 sleep(15) 534 sleep(15)
533 PULL_COUNT = 0 535 PULL_COUNT = 0
534 536
535 if DISABLE_SEM > 0: 537 if DISABLE_SEM > 0:
536 logger.info('SEMAPHORE is still on, delaying pull') 538 logger.info('SEMAPHORE is still on, delaying pull')
537 DISABLE_SEM -= 1 539 DISABLE_SEM -= 1
538 return 540 return
539 541
540 if not isPullEnable(): 542 if not isPullEnable():
541 sleep(60) 543 sleep(60)
542 return 544 return
543 545
544 r = None 546 r = None
545 url = AAA_HOST + '/pull?city=' + CITY + '&nom=' + PRODUCTS 547 url = AAA_HOST + '/pull?city=' + CITY + '&nom=' + PRODUCTS
546 try: 548 try:
547 r = requests.get(url) 549 r = requests.get(url)
548 except: 550 except:
549 logger.warning("Error requesting to AAA") 551 logger.warning("Error requesting to AAA")
550 return 552 return
551 553
552 if not r: 554 if not r:
553 return 555 return
554 556
555 task = sate24.parsePullMessage(r.text) 557 task = sate24.parsePullMessage(r.text)
556 558
557 if task['status'] == 'OK': 559 if task['status'] == 'OK':
558 560
559 logger.info('PULL ' + url + ' => ' + r.text) 561 logger.info('PULL ' + url + ' => ' + r.text)
560 publishAAATaskToRedis(task) 562 publishAAATaskToRedis(task)
561 563
562 if not checkBalance(modem) or BALANCE == 0: 564 if not checkBalance(modem) or BALANCE == 0:
563 pushTopupStatus(task['requestId'], '91', 'Transaksi dibatalkan karena gagal check balance') 565 pushTopupStatus(task['requestId'], '91', 'Transaksi dibatalkan karena gagal check balance')
564 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP) 566 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP)
565 return 567 return
566 568
567 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP) 569 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP)
568 570
569 topupTask(task, modem) 571 topupTask(task, modem)
570 sleep(SLEEP_AFTER_TOPUP) 572 sleep(SLEEP_AFTER_TOPUP)
571 573
572 def publishAAATaskToRedis(task): 574 def publishAAATaskToRedis(task):
573 try: 575 try:
574 key = 'kimochi.aaa_pull.gw:' + BASE_CHIPINFO 576 key = 'kimochi.aaa_pull.gw:' + BASE_CHIPINFO
575 plain_text = task['timestamp'] + ' - ' + task['member'] + ' isi ' + task['product'] + ' ke ' + task['destination']; 577 plain_text = task['timestamp'] + ' - ' + task['member'] + ' isi ' + task['product'] + ' ke ' + task['destination'];
576 578
577 redis_client.publish(key + '.json', json.dumps(task)) 579 redis_client.publish(key + '.json', json.dumps(task))
578 redis_client.publish(key + '.text', plain_text); 580 redis_client.publish(key + '.text', plain_text);
579 except: 581 except:
580 logger.warning('Error publishing kimochi') 582 logger.warning('Error publishing kimochi')
581 583
582 def publishMessageToRedis(): 584 def publishMessageToRedis():
583 pass 585 pass
584 586
585 def pullLoop(modem): 587 def pullLoop(modem):
586 global TERMINATING 588 global TERMINATING
587 589
588 while True: 590 while True:
589 signalStrength = modem.signalStrength 591 signalStrength = modem.signalStrength
590 saveSignalStrengthToRedis(signalStrength) 592 saveSignalStrengthToRedis(signalStrength)
591 593
592 if TERMINATING: 594 if TERMINATING:
593 logger.info('Terminated by request signal') 595 logger.info('Terminated by request signal')
594 sys.exit(0) 596 sys.exit(0)
595 597
596 pull(modem) 598 pull(modem)
597 599
598 sleep(PULL_INTERVAL) 600 sleep(PULL_INTERVAL)
599 601
600 def checkSignal(modem): 602 def checkSignal(modem):
601 logger.info('Signal: {0}'.format(modem.signalStrength)) 603 logger.info('Signal: {0}'.format(modem.signalStrength))
602 try: 604 try:
603 redis_client.set(CHIPINFO + '.signal', modem.signalStrength) 605 redis_client.set(CHIPINFO + '.signal', modem.signalStrength)
604 redis_client.expire(CHIPINFO + '.signal', 3600*24) 606 redis_client.expire(CHIPINFO + '.signal', 3600*24)
605 except: 607 except:
606 logger.warning("Can not save signal strength to redis") 608 logger.warning("Can not save signal strength to redis")
607 609
608 def checkAccount(modem): 610 def checkAccount(modem):
609 try: 611 try:
610 ussd_string = '*123*120*8*3#' 612 ussd_string = '*123*120*8*3#'
611 response = modem.sendUssd(ussd_string, 30) 613 response = modem.sendUssd(ussd_string, 30)
612 logger.info('Account Info: {0}'.format(response.message)) 614 logger.info('Account Info: {0}'.format(response.message))
613 615
614 if response.sessionActive: 616 if response.sessionActive:
615 response.cancel() 617 response.cancel()
616 except: 618 except:
617 logger.warning('Error when requesting account info') 619 logger.warning('Error when requesting account info')
618 return False 620 return False
619 621
620 def checkBalance(modem, do_not_update = False, return_result = False): 622 def checkBalance(modem, do_not_update = False, return_result = False):
621 global BALANCE 623 global BALANCE
622 624
623 _BALANCE = 0 625 _BALANCE = 0
624 626
625 try: 627 try:
626 628
627 ussd_string = '*123*120#' 629 ussd_string = '*123*120#'
628 response = modem.sendUssd(ussd_string, 30) 630 response = modem.sendUssd(ussd_string, 30)
629 _BALANCE = xltunai.getBalanceFromUSSDResponse(response.message) 631 _BALANCE = xltunai.getBalanceFromUSSDResponse(response.message)
630 632
631 if not do_not_update: 633 if not do_not_update:
632 BALANCE = _BALANCE 634 BALANCE = _BALANCE
633 saveBalanceToRedis(BALANCE) 635 saveBalanceToRedis(BALANCE)
634 636
635 logger.info('Balance: {0}'.format(_BALANCE)) 637 logger.info('Balance: {0}'.format(_BALANCE))
636 if response.sessionActive: 638 if response.sessionActive:
637 response.cancel() 639 response.cancel()
638 640
639 if _BALANCE != 0 and _BALANCE < MIN_BALANCE: 641 if _BALANCE != 0 and _BALANCE < MIN_BALANCE:
640 logger.info('Disabling pull, balance {0} < {1}'.format(_BALANCE, MIN_BALANCE)) 642 logger.info('Disabling pull, balance {0} < {1}'.format(_BALANCE, MIN_BALANCE))
641 disablePull() 643 disablePull()
642 644
643 except: 645 except:
644 logger.warning('Error when requesting BALANCE by USSD') 646 logger.warning('Error when requesting BALANCE by USSD')
645 if return_result: 647 if return_result:
646 return 0 648 return 0
647 else: 649 else:
648 return False 650 return False
649 651
650 try: 652 try:
651 redis_client.set(CHIPINFO + '.balance', BALANCE) 653 redis_client.set(CHIPINFO + '.balance', BALANCE)
652 except: 654 except:
653 logger.warning('Failed to save balance to redis') 655 logger.warning('Failed to save balance to redis')
654 656
655 if return_result: 657 if return_result:
656 return _BALANCE 658 return _BALANCE
657 else: 659 else:
658 return True 660 return True
659 661
660 def getPulsaInfo(modem): 662 def getPulsaInfo(modem):
661 global PULSA 663 global PULSA
662 global MASA_AKTIF 664 global MASA_AKTIF
663 665
664 try: 666 try:
665 ussd_string = "*123#" 667 ussd_string = "*123#"
666 response = modem.sendUssd(ussd_string) 668 response = modem.sendUssd(ussd_string)
667 669
668 message = response.message.strip() 670 message = response.message.strip()
669 logger.info('PULSA: {0}'.format(message)) 671 logger.info('PULSA: {0}'.format(message))
670 if response.sessionActive: 672 if response.sessionActive:
671 response.cancel() 673 response.cancel()
672 674
673 PULSA = xltunai.getPulsaFromUssdResponseMessage(message) 675 PULSA = xltunai.getPulsaFromUssdResponseMessage(message)
674 MASA_AKTIF =xltunai.getMasaAktifFromUssdResponseMessage(message) 676 MASA_AKTIF =xltunai.getMasaAktifFromUssdResponseMessage(message)
675 logger.info('PULSA: {0} -- MASA AKTIF: {1}'.format(PULSA, MASA_AKTIF)) 677 logger.info('PULSA: {0} -- MASA AKTIF: {1}'.format(PULSA, MASA_AKTIF))
676 678
677 return message 679 return message
678 680
679 except: 681 except:
680 logger.warning('Error when requesting pulsa info by USSD') 682 logger.warning('Error when requesting pulsa info by USSD')
681 return '' 683 return ''
682 684
683 def getSIMCardInfo(modem): 685 def getSIMCardInfo(modem):
684 try: 686 try:
685 ussd_string = xltunai.getSIMCardInfoUSSDCommand() 687 ussd_string = xltunai.getSIMCardInfoUSSDCommand()
686 response = modem.sendUssd(ussd_string) 688 response = modem.sendUssd(ussd_string)
687 689
688 message = response.message.strip() 690 message = response.message.strip()
689 logger.info('SIM INFO: {0}'.format(message)) 691 logger.info('SIM INFO: {0}'.format(message))
690 if response.sessionActive: 692 if response.sessionActive:
691 response.cancel() 693 response.cancel()
692 694
693 return message 695 return message
694 696
695 except: 697 except:
696 logger.warning('Error when requesting SIM card info by USSD') 698 logger.warning('Error when requesting SIM card info by USSD')
697 return '' 699 return ''
698 700
699 def updateChipInfo(msisdn): 701 def updateChipInfo(msisdn):
700 global BASE_CHIPINFO 702 global BASE_CHIPINFO
701 global CHIPINFO 703 global CHIPINFO
702 global MSISDN 704 global MSISDN
703 705
704 MSISDN = msisdn 706 MSISDN = msisdn
705 if CHIPINFO.find(msisdn) == -1: 707 if CHIPINFO.find(msisdn) == -1:
706 CHIPINFO = BASE_CHIPINFO + '-' + msisdn 708 CHIPINFO = BASE_CHIPINFO + '-' + msisdn
707 709
708 logger.info('CHIPINFO: {0}'.format(CHIPINFO)) 710 logger.info('CHIPINFO: {0}'.format(CHIPINFO))
709 711
710 def main(): 712 def main():
711 global logger 713 global logger
712 714
713 log_format = '%(asctime)s %(levelname)s: %(message)s' 715 log_format = '%(asctime)s %(levelname)s: %(message)s'
714 716
715 logging.basicConfig(format=log_format, level=logging.INFO) 717 logging.basicConfig(format=log_format, level=logging.INFO)
716 logger = logging.getLogger(__name__) 718 logger = logging.getLogger(__name__)
717 719
718 logger_formatter = logging.Formatter(log_format) 720 logger_formatter = logging.Formatter(log_format)
719 logger_handler = TimedRotatingFileHandler('logs/log', when='midnight') 721 logger_handler = TimedRotatingFileHandler('logs/log', when='midnight')
720 logger_handler.setFormatter(logger_formatter) 722 logger_handler.setFormatter(logger_formatter)
721 logger.addHandler(logger_handler) 723 logger.addHandler(logger_handler)
722 724
723 requests_logger = logging.getLogger('requests') 725 requests_logger = logging.getLogger('requests')
724 requests_logger.setLevel(logging.WARNING) 726 requests_logger.setLevel(logging.WARNING)
725 727
726 logger.info('Initializing modem...') 728 logger.info('Initializing modem...')
727 729
728 modem = GsmModem(PORT, BAUDRATE, smsReceivedCallbackFunc=handleSms) 730 modem = GsmModem(PORT, BAUDRATE, smsReceivedCallbackFunc=handleSms)
729 modem.smsTextMode = True 731 modem.smsTextMode = True
730 modem.connect(PIN) 732 modem.connect(PIN)
731 733
732 logger.info('Waiting for network coverage...') 734 logger.info('Waiting for network coverage...')
733 modem.waitForNetworkCoverage(10) 735 modem.waitForNetworkCoverage(10)
734 736
735 logger.info('Modem ready') 737 logger.info('Modem ready')
736 738
737 getPulsaInfo(modem) 739 getPulsaInfo(modem)
738 sleep(2) 740 sleep(2)
739 741
740 simcard_info = getSIMCardInfo(modem) 742 simcard_info = getSIMCardInfo(modem)
741 msisdn = xltunai.getMSISDNFromSIMCardInfo(simcard_info) 743 msisdn = xltunai.getMSISDNFromSIMCardInfo(simcard_info)
742 744
743 if not msisdn: 745 if not msisdn:
744 logger.warning('Gagal mendapatkan msisdn, terminating') 746 logger.warning('Gagal mendapatkan msisdn, terminating')
745 sleep(5) 747 sleep(5)
746 sys.exit(2) 748 sys.exit(2)
747 749
748 imsi = modem.imsi 750 imsi = modem.imsi
749 logger.info('MSISDN: {0} -- IMSI: {1}'.format(msisdn, imsi)) 751 logger.info('MSISDN: {0} -- IMSI: {1}'.format(msisdn, imsi))
750 752
751 updateChipInfo(msisdn) 753 updateChipInfo(msisdn)
752 saveSimCardInfo(imsi, msisdn) 754 saveSimCardInfo(imsi, msisdn)
753 755
754 sleep(2) 756 sleep(2)
755 757
756 saveSignalStrengthToRedis(modem.signalStrength) 758 saveSignalStrengthToRedis(modem.signalStrength)
757 759
758 logger.info('Process stored SMS') 760 logger.info('Process stored SMS')
759 try: 761 try:
760 modem.processStoredSms() 762 modem.processStoredSms()
761 except: 763 except:
762 logger.warning('Failed on Process stored SMS') 764 logger.warning('Failed on Process stored SMS')
763 765
764 logger.info('Delete stored SMS') 766 logger.info('Delete stored SMS')
765 try: 767 try:
766 modem.deleteMultipleStoredSms() 768 modem.deleteMultipleStoredSms()
767 except: 769 except:
768 #logger.warning('Failed on delete SMS') 770 #logger.warning('Failed on delete SMS')
769 pass 771 pass
770 772
771 sleep(2) 773 sleep(2)
772 774
773 checkAccount(modem) 775 checkAccount(modem)
774 sleep(5) 776 sleep(5)
775 777
776 enablePull() 778 enablePull()
777 779
778 checkBalance(modem) 780 checkBalance(modem)
779 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP) 781 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP)
780 782
781 pullLoop(modem) 783 pullLoop(modem)
782 logger.info('Waiting for SMS message...') 784 logger.info('Waiting for SMS message...')
783 try: 785 try:
784 modem.rxThread.join(2**31) # Specify a (huge) timeout so that it essentially blocks indefinitely, but still receives CTRL+C interrupt signal 786 modem.rxThread.join(2**31) # Specify a (huge) timeout so that it essentially blocks indefinitely, but still receives CTRL+C interrupt signal
785 finally: 787 finally:
786 modem.close(); 788 modem.close();
787 789
788 def saveSimCardInfo(imsi, msisdn): 790 def saveSimCardInfo(imsi, msisdn):
789 logger.info('Save sim card info to redis') 791 logger.info('Save sim card info to redis')
790 792
791 data = { 793 data = {
792 'gw': BASE_CHIPINFO, 794 'gw': BASE_CHIPINFO,
793 'imsi': imsi, 795 'imsi': imsi,
794 'msisdn': msisdn, 796 'msisdn': msisdn,
795 'pulsa': PULSA, 797 'pulsa': PULSA,
796 'masa_aktif': MASA_AKTIF 798 'masa_aktif': MASA_AKTIF
797 } 799 }
798 800
799 json_data = json.dumps(data) 801 json_data = json.dumps(data)
800 802
801 with open('simcardinfo.txt', 'w') as f: 803 with open('simcardinfo.txt', 'w') as f:
802 f.write(json_data) 804 f.write(json_data)
803 f.closed 805 f.closed
804 806
805 807
806 map_data = { 808 map_data = {
807 BASE_CHIPINFO + '.simcardinfo': json_data, 809 BASE_CHIPINFO + '.simcardinfo': json_data,
808 'simcardinfo.gw:' + BASE_CHIPINFO: json_data, 810 'simcardinfo.gw:' + BASE_CHIPINFO: json_data,
809 'simcardinfo.imsi:' + imsi: json_data, 811 'simcardinfo.imsi:' + imsi: json_data,
810 'simcardinfo.msisdn:' + msisdn: json_data 812 'simcardinfo.msisdn:' + msisdn: json_data
811 } 813 }
812 814
813 logger.info(map_data) 815 logger.info(map_data)
814 816
815 redis_pipe = redis_client.pipeline() 817 redis_pipe = redis_client.pipeline()
816 818
817 try: 819 try:
818 redis_pipe.mset(map_data) 820 redis_pipe.mset(map_data)
819 821
820 for k in data: 822 for k in data:
821 redis_pipe.expire(k, 3600 * 24 * 60) 823 redis_pipe.expire(k, 3600 * 24 * 60)
822 824
823 except: 825 except:
824 logger.warning('Failed to save simcardinfo to redis') 826 logger.warning('Failed to save simcardinfo to redis')
825 finally: 827 finally:
826 redis_pipe.execute() 828 redis_pipe.execute()
827 829
828 if __name__ == '__main__': 830 if __name__ == '__main__':
829 pidfile = open('pid.txt', 'w') 831 pidfile = open('pid.txt', 'w')
830 pidfile.write(str(getpid())) 832 pidfile.write(str(getpid()))
831 pidfile.close() 833 pidfile.close()
832 834
833 # trap CTRL-C 835 # trap CTRL-C
834 signal.signal(signal.SIGINT, signalHandler) 836 signal.signal(signal.SIGINT, signalHandler)
835 # trap supervisor stop 837 # trap supervisor stop
836 signal.signal(signal.SIGTERM, signalHandler) 838 signal.signal(signal.SIGTERM, signalHandler)
837 839
838 main() 840 main()
839 841