Commit d66608f59749835f40909a80503eff28fff76ec1

Authored by Adhidarma Hadiwinoto
1 parent dbfe755b5d
Exists in master

penanganan handle log binary sms

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