Commit 44033b6250eb62d4be5e2ebe9c5ce61896c8744e

Authored by Adhidarma Hadiwinoto
1 parent 8ff5b06b3a
Exists in master

bugfix

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