Commit 724c1428a0bbf3d647ceda2b6584ef1757c108b2

Authored by Adhidarma Hadiwinoto
1 parent d283cc10d5
Exists in master

bf

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