Commit 6f184db816f1dc034a0cb8f26a140807dfd8e663

Authored by Adhidarma Hadiwinoto
1 parent f6176dd53b
Exists in master

log last sn override on cash in

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