Commit caaf6687dce46b0820cfbf604020c63ec1903dae

Authored by Adhidarma Hadiwinoto
1 parent 3deb84a9dc
Exists in master

upper

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 logger.info('Monthly limit for "{0}" detected, removing from product list'.format(LAST_PRODUCT)) 122 logger.info('Monthly limit for "{0}" detected, removing from product list'.format(LAST_PRODUCT))
123 PRODUCTS = sate24.removeProduct(PRODUCTS, LAST_PRODUCT) 123 PRODUCTS = sate24.removeProduct(PRODUCTS, LAST_PRODUCT)
124 logger.warning('Monthly limit for "{0}" exceeded. New active products: "{1}"'.format(LAST_PRODUCT, PRODUCTS)) 124 logger.warning('Monthly limit for "{0}" exceeded. New active products: "{1}"'.format(LAST_PRODUCT, PRODUCTS))
125 return 125 return
126 126
127 elif sms.text.find('Maaf, transaksi Anda masih dalam proses') >= 0: 127 elif sms.text.find('Maaf, transaksi Anda masih dalam proses') >= 0:
128 pushTopupStatus(LAST_REQUEST_ID, '68', sms.text) 128 pushTopupStatus(LAST_REQUEST_ID, '68', sms.text)
129 return 129 return
130 130
131 destination = xltunai.getDestinationFromMessage(sms.text) 131 destination = xltunai.getDestinationFromMessage(sms.text)
132 if destination == '': 132 if destination == '':
133 logger.warning('handleSms: gagal parsing nomor tujuan') 133 logger.warning('handleSms: gagal parsing nomor tujuan')
134 return 134 return
135 135
136 nominal = xltunai.getNominalFromMessage(sms.text) 136 nominal = xltunai.getNominalFromMessage(sms.text)
137 if nominal == '': 137 if nominal == '':
138 logger.warning('handleSms: gagal parsing nominal') 138 logger.warning('handleSms: gagal parsing nominal')
139 return 139 return
140 140
141 sn = xltunai.getSNFromMessage(sms.text) 141 sn = xltunai.getSNFromMessage(sms.text)
142 if sn == '': 142 if sn == '':
143 logger.warning('handleSms: gagal parsing SN') 143 logger.warning('handleSms: gagal parsing SN')
144 144
145 145
146 DISABLE_SEM = 0 146 DISABLE_SEM = 0
147 147
148 response_code = xltunai.getResponseCodeByMessage(sms.text) 148 response_code = xltunai.getResponseCodeByMessage(sms.text)
149 149
150 request_id = getRequestIdByNominalDestination(nominal, destination) 150 request_id = getRequestIdByNominalDestination(nominal, destination)
151 if not request_id: 151 if not request_id:
152 logger.info('Unknown request id for nominal:{0} destination:{1}'.format(nominal, destination)) 152 logger.info('Unknown request id for nominal:{0} destination:{1}'.format(nominal, destination))
153 return 153 return
154 154
155 pushTopupStatus(request_id, response_code, sms.text) 155 pushTopupStatus(request_id, response_code, sms.text)
156 try: 156 try:
157 deleteMultipleStoredSms(2) 157 deleteMultipleStoredSms(2)
158 except: 158 except:
159 #logger.warning('Failed on delete SMS') 159 #logger.warning('Failed on delete SMS')
160 pass 160 pass
161 161
162 162
163 def getRequestIdByNominalDestination(nominal, destination): 163 def getRequestIdByNominalDestination(nominal, destination):
164 redis_key = sate24.keyByNominalDestination(CHIPINFO, nominal, destination) 164 redis_key = sate24.keyByNominalDestination(CHIPINFO, nominal, destination)
165 #return redis_client.spop(redis_key) 165 #return redis_client.spop(redis_key)
166 return redis_client.rpop(redis_key) 166 return redis_client.rpop(redis_key)
167 167
168 def pushTopupStatus(request_id, response_code, _message, dontparsesn = False): 168 def pushTopupStatus(request_id, response_code, _message, dontparsesn = False):
169 global BALANCE 169 global BALANCE
170 global CHIPINFO 170 global CHIPINFO
171 171
172 redis_key = sate24.keyByRequestId(CHIPINFO, request_id) + '.response_code' 172 redis_key = sate24.keyByRequestId(CHIPINFO, request_id) + '.response_code'
173 if response_code == '00': 173 if response_code == '00':
174 redis_client.set(redis_key, response_code) 174 redis_client.set(redis_key, response_code)
175 else: 175 else:
176 redis_response_code = redis_client.get(redis_key) 176 redis_response_code = redis_client.get(redis_key)
177 if redis_response_code == '00': 177 if redis_response_code == '00':
178 logger.info('Ignoring message from success trx ') 178 logger.info('Ignoring message from success trx ')
179 return 179 return
180 180
181 message = "{0} -- Prev balance: {1}".format(_message, BALANCE) 181 message = "{0} -- Prev balance: {1}".format(_message, BALANCE)
182 182
183 timestamp = strftime('%Y%m%d%H%M%S') 183 timestamp = strftime('%Y%m%d%H%M%S')
184 184
185 if response_code == '00' and not dontparsesn: 185 if response_code == '00' and not dontparsesn:
186 sn = xltunai.getSNFromMessage(message) 186 sn = xltunai.getSNFromMessage(message)
187 LAST_SN = sn 187 LAST_SN = sn
188 message = 'SN={0};{1}. Signal Strength: {2}'.format(sn, message, modem.signalStrength) 188 message = 'SN={0};{1}. Signal Strength: {2}'.format(sn, message, modem.signalStrength)
189 189
190 push_message = CHIPINFO + '$' + message 190 push_message = CHIPINFO + '$' + message
191 191
192 payload = { 192 payload = {
193 'trans_id': request_id, 193 'trans_id': request_id,
194 'trans_date': timestamp, 194 'trans_date': timestamp,
195 'resp_code': response_code, 195 'resp_code': response_code,
196 'ussd_msg': push_message 196 'ussd_msg': push_message
197 } 197 }
198 198
199 url = AAA_HOST + '/topup' 199 url = AAA_HOST + '/topup'
200 200
201 try: 201 try:
202 logger.info('Sending topup status to AAA') 202 logger.info('Sending topup status to AAA')
203 logger.info(payload) 203 logger.info(payload)
204 r = requests.get(url, params=payload) 204 r = requests.get(url, params=payload)
205 except: 205 except:
206 logger.warning('Error sending topup status to AAA') 206 logger.warning('Error sending topup status to AAA')
207 207
208 try: 208 try:
209 # publish echi topup report ke redis 209 # publish echi topup report ke redis
210 echi_key = 'echi.topup_report.gw:' + BASE_CHIPINFO 210 echi_key = 'echi.topup_report.gw:' + BASE_CHIPINFO
211 211
212 redis_client.publish(echi_key + '.json', json.dumps(payload)) 212 redis_client.publish(echi_key + '.json', json.dumps(payload))
213 213
214 echi_message = timestamp + ' - ' + response_code + ' - ' + message 214 echi_message = timestamp + ' - ' + response_code + ' - ' + message
215 redis_client.publish(echi_key + '.message', echi_message) 215 redis_client.publish(echi_key + '.message', echi_message)
216 except: 216 except:
217 logger.warning('Error publishing topup report to redis') 217 logger.warning('Error publishing topup report to redis')
218 218
219 def getIsDisableRedisKey(): 219 def getIsDisableRedisKey():
220 return CHIPINFO + '.pulldisable' 220 return CHIPINFO + '.pulldisable'
221 221
222 def isPullEnable(): 222 def isPullEnable():
223 redis_key = getIsDisableRedisKey() 223 redis_key = getIsDisableRedisKey()
224 result = 'FALSE' 224 result = 'FALSE'
225 225
226 try: 226 try:
227 result = redis_client.get(redis_key) 227 result = redis_client.get(redis_key)
228 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL) 228 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL)
229 except: 229 except:
230 return False 230 return False
231 231
232 if not result: 232 if not result:
233 return True 233 return True
234 234
235 return result == 'FALSE' 235 return result == 'FALSE'
236 236
237 def enablePull(): 237 def enablePull():
238 logger.info('Enabling Pull on products {0}'.format(PRODUCTS)) 238 logger.info('Enabling Pull on products {0}'.format(PRODUCTS))
239 redis_key = getIsDisableRedisKey() 239 redis_key = getIsDisableRedisKey()
240 try: 240 try:
241 redis_client.set(redis_key, 'FALSE') 241 redis_client.set(redis_key, 'FALSE')
242 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL) 242 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL)
243 except: 243 except:
244 return 244 return
245 245
246 def disablePull(): 246 def disablePull():
247 global DISABLE_SEM 247 global DISABLE_SEM
248 global DISABLE_SEM_ON_TRX 248 global DISABLE_SEM_ON_TRX
249 249
250 logger.info('Disabling Pull') 250 logger.info('Disabling Pull')
251 redis_key = getIsDisableRedisKey() 251 redis_key = getIsDisableRedisKey()
252 try: 252 try:
253 redis_client.set(redis_key, 'TRUE') 253 redis_client.set(redis_key, 'TRUE')
254 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL) 254 redis_client.expire(redis_key, REDIS_DISABLE_PULL_TTL)
255 except: 255 except:
256 return 256 return
257 257
258 def adviceLastSN(requestId, modem): 258 def adviceLastSN(requestId, modem):
259 global DISABLE_SEM 259 global DISABLE_SEM
260 global LAST_SN 260 global LAST_SN
261 global TOPUP_USSD_TIMEOUT 261 global TOPUP_USSD_TIMEOUT
262 262
263 if not LAST_SN: 263 if not LAST_SN:
264 message = 'Tidak ada trx sebelumnya untuk perbandingan SN. Silahkan bandingkan prev balance dengan trx berikutnya di chip yang sama' 264 message = 'Tidak ada trx sebelumnya untuk perbandingan SN. Silahkan bandingkan prev balance dengan trx berikutnya di chip yang sama'
265 pushTopupStatus(requestId, '68', message) 265 pushTopupStatus(requestId, '68', message)
266 DISABLE_SEM = 0 266 DISABLE_SEM = 0
267 return 267 return
268 268
269 ussd_command = xltunai.getHistoryUSSDCommand() 269 ussd_command = xltunai.getHistoryUSSDCommand()
270 270
271 logger.info(u'Executing advice {0}'.format(ussd_command)) 271 logger.info(u'Executing advice {0}'.format(ussd_command))
272 try: 272 try:
273 response = modem.sendUssd(ussd_command, TOPUP_USSD_TIMEOUT) 273 response = modem.sendUssd(ussd_command, TOPUP_USSD_TIMEOUT)
274 274
275 message = response.message.strip() 275 message = response.message.strip()
276 logger.info(u'USSD response: {0}'.format(message)) 276 logger.info(u'USSD response: {0}'.format(message))
277 277
278 lastSNFromHistory = xltunai.getLastSNFromHistoryMessage(message) 278 lastSNFromHistory = xltunai.getLastSNFromHistoryMessage(message)
279 279
280 if response.sessionActive: 280 if response.sessionActive:
281 response.cancel() 281 response.cancel()
282 282
283 if not lastSNFromHistory: 283 if not lastSNFromHistory:
284 if DISABLE_SEM: 284 if DISABLE_SEM:
285 logger.info('Failed to get last sn from history, retrying in 15 secs') 285 logger.info('Failed to get last sn from history, retrying in 15 secs')
286 sleep(15) 286 sleep(15)
287 adviceLastSN(requestid, modem) 287 adviceLastSN(requestid, modem)
288 288
289 elif lastSNFromHistory == LAST_SN: 289 elif lastSNFromHistory == LAST_SN:
290 topupMessage = "Topup gagal berdasarkan advice. {0} = {1}. {2}".format(lastSNFromHistory, LAST_SN, message) 290 topupMessage = "Topup gagal berdasarkan advice. {0} = {1}. {2}".format(lastSNFromHistory, LAST_SN, message)
291 pushTopupStatus(requestId, '40', topupMessage) 291 pushTopupStatus(requestId, '40', topupMessage)
292 DISABLE_SEM = 0 292 DISABLE_SEM = 0
293 293
294 294
295 else: 295 else:
296 topupMessage = "SN={0}; Topup berhasil berdasarkan advice. {1}".format(lastSNFromHistory, message) 296 topupMessage = "SN={0}; Topup berhasil berdasarkan advice. {1}".format(lastSNFromHistory, message)
297 LAST_SN = lastSNFromHistory 297 LAST_SN = lastSNFromHistory
298 pushTopupStatus(requestId, '00', topupMessage, True) 298 pushTopupStatus(requestId, '00', topupMessage, True)
299 DISABLE_SEM = 0 299 DISABLE_SEM = 0
300 300
301 except: 301 except:
302 message = "USSD Error: Something wrong when executing USSD advice. Signal strength: {0}".format(modem.signalStrength) 302 message = "USSD Error: Something wrong when executing USSD advice. Signal strength: {0}".format(modem.signalStrength)
303 logger.warning(message) 303 logger.warning(message)
304 pushTopupStatus(requestId, '68', message) 304 pushTopupStatus(requestId, '68', message)
305 305
306 sleep(60) 306 sleep(60)
307 adviceLastSN(requestId, modem) 307 adviceLastSN(requestId, modem)
308 #waitForResultSmsAfterUssdError(modem, task['requestId'], message) 308 #waitForResultSmsAfterUssdError(modem, task['requestId'], message)
309 return 309 return
310 310
311 311
312 312
313 def topupTask(task, modem): 313 def topupTask(task, modem):
314 global LAST_REQUEST_ID 314 global LAST_REQUEST_ID
315 315
316 if not task: 316 if not task:
317 return 317 return
318 318
319 if task['status'] != 'OK': 319 if task['status'] != 'OK':
320 return 320 return
321 321
322 LAST_REQUEST_ID = task['requestId'] 322 LAST_REQUEST_ID = task['requestId']
323 LAST_PRODUCT = task['product'] 323 LAST_PRODUCT = task['product'].upper()
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. Signal strength: {0}".format(modem.signalStrength) 362 message = "USSD Error: Timeout when executing USSD topup. Signal strength: {0}".format(modem.signalStrength)
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. Signal strength: {0}".format(modem.signalStrength) 370 message = "USSD Error: Something wrong when executing USSD topup. Signal strength: {0}".format(modem.signalStrength)
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', 15 * 60) 458 redis_client.expire('balance.gw:' + BASE_CHIPINFO + '.signal', 15 * 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 TERMINATING 536 global TERMINATING
537 537
538 while True: 538 while True:
539 signalStrength = modem.signalStrength 539 signalStrength = modem.signalStrength
540 saveSignalStrengthToRedis(signalStrength) 540 saveSignalStrengthToRedis(signalStrength)
541 541
542 if TERMINATING: 542 if TERMINATING:
543 logger.info('Terminated by request signal') 543 logger.info('Terminated by request signal')
544 sys.exit(0) 544 sys.exit(0)
545 545
546 pull(modem) 546 pull(modem)
547 547
548 sleep(PULL_INTERVAL) 548 sleep(PULL_INTERVAL)
549 549
550 def checkSignal(modem): 550 def checkSignal(modem):
551 logger.info('Signal: {0}'.format(modem.signalStrength)) 551 logger.info('Signal: {0}'.format(modem.signalStrength))
552 try: 552 try:
553 redis_client.set(CHIPINFO + '.signal', modem.signalStrength) 553 redis_client.set(CHIPINFO + '.signal', modem.signalStrength)
554 redis_client.expire(CHIPINFO + '.signal', 3600*24) 554 redis_client.expire(CHIPINFO + '.signal', 3600*24)
555 except: 555 except:
556 logger.warning("Can not save signal strength to redis") 556 logger.warning("Can not save signal strength to redis")
557 557
558 def checkAccount(modem): 558 def checkAccount(modem):
559 try: 559 try:
560 ussd_string = '*123*120*8*3#' 560 ussd_string = '*123*120*8*3#'
561 response = modem.sendUssd(ussd_string, 30) 561 response = modem.sendUssd(ussd_string, 30)
562 logger.info('Account Info: {0}'.format(response.message)) 562 logger.info('Account Info: {0}'.format(response.message))
563 563
564 if response.sessionActive: 564 if response.sessionActive:
565 response.cancel() 565 response.cancel()
566 except: 566 except:
567 logger.warning('Error when requesting account info') 567 logger.warning('Error when requesting account info')
568 return False 568 return False
569 569
570 def checkBalance(modem, do_not_update = False, return_result = False): 570 def checkBalance(modem, do_not_update = False, return_result = False):
571 global BALANCE 571 global BALANCE
572 572
573 _BALANCE = 0 573 _BALANCE = 0
574 574
575 try: 575 try:
576 576
577 ussd_string = '*123*120#' 577 ussd_string = '*123*120#'
578 response = modem.sendUssd(ussd_string, 30) 578 response = modem.sendUssd(ussd_string, 30)
579 _BALANCE = xltunai.getBalanceFromUSSDResponse(response.message) 579 _BALANCE = xltunai.getBalanceFromUSSDResponse(response.message)
580 580
581 if not do_not_update: 581 if not do_not_update:
582 BALANCE = _BALANCE 582 BALANCE = _BALANCE
583 saveBalanceToRedis(BALANCE) 583 saveBalanceToRedis(BALANCE)
584 584
585 logger.info('Balance: {0}'.format(_BALANCE)) 585 logger.info('Balance: {0}'.format(_BALANCE))
586 if response.sessionActive: 586 if response.sessionActive:
587 response.cancel() 587 response.cancel()
588 588
589 if _BALANCE != 0 and _BALANCE < MIN_BALANCE: 589 if _BALANCE != 0 and _BALANCE < MIN_BALANCE:
590 logger.info('Disabling pull, balance {0} < {1}'.format(_BALANCE, MIN_BALANCE)) 590 logger.info('Disabling pull, balance {0} < {1}'.format(_BALANCE, MIN_BALANCE))
591 disablePull() 591 disablePull()
592 592
593 except: 593 except:
594 logger.warning('Error when requesting BALANCE by USSD') 594 logger.warning('Error when requesting BALANCE by USSD')
595 if return_result: 595 if return_result:
596 return 0 596 return 0
597 else: 597 else:
598 return False 598 return False
599 599
600 try: 600 try:
601 redis_client.set(CHIPINFO + '.balance', BALANCE) 601 redis_client.set(CHIPINFO + '.balance', BALANCE)
602 except: 602 except:
603 logger.warning('Failed to save balance to redis') 603 logger.warning('Failed to save balance to redis')
604 604
605 if return_result: 605 if return_result:
606 return _BALANCE 606 return _BALANCE
607 else: 607 else:
608 return True 608 return True
609 609
610 def getPulsaInfo(modem): 610 def getPulsaInfo(modem):
611 global PULSA 611 global PULSA
612 global MASA_AKTIF 612 global MASA_AKTIF
613 613
614 try: 614 try:
615 ussd_string = "*123#" 615 ussd_string = "*123#"
616 response = modem.sendUssd(ussd_string) 616 response = modem.sendUssd(ussd_string)
617 617
618 message = response.message.strip() 618 message = response.message.strip()
619 logger.info('PULSA: {0}'.format(message)) 619 logger.info('PULSA: {0}'.format(message))
620 if response.sessionActive: 620 if response.sessionActive:
621 response.cancel() 621 response.cancel()
622 622
623 PULSA = xltunai.getPulsaFromUssdResponseMessage(message) 623 PULSA = xltunai.getPulsaFromUssdResponseMessage(message)
624 MASA_AKTIF =xltunai.getMasaAktifFromUssdResponseMessage(message) 624 MASA_AKTIF =xltunai.getMasaAktifFromUssdResponseMessage(message)
625 logger.info('PULSA: {0} -- MASA AKTIF: {1}'.format(PULSA, MASA_AKTIF)) 625 logger.info('PULSA: {0} -- MASA AKTIF: {1}'.format(PULSA, MASA_AKTIF))
626 626
627 return message 627 return message
628 628
629 except: 629 except:
630 logger.warning('Error when requesting pulsa info by USSD') 630 logger.warning('Error when requesting pulsa info by USSD')
631 return '' 631 return ''
632 632
633 def getSIMCardInfo(modem): 633 def getSIMCardInfo(modem):
634 try: 634 try:
635 ussd_string = xltunai.getSIMCardInfoUSSDCommand() 635 ussd_string = xltunai.getSIMCardInfoUSSDCommand()
636 response = modem.sendUssd(ussd_string) 636 response = modem.sendUssd(ussd_string)
637 637
638 message = response.message.strip() 638 message = response.message.strip()
639 logger.info('SIM INFO: {0}'.format(message)) 639 logger.info('SIM INFO: {0}'.format(message))
640 if response.sessionActive: 640 if response.sessionActive:
641 response.cancel() 641 response.cancel()
642 642
643 return message 643 return message
644 644
645 except: 645 except:
646 logger.warning('Error when requesting SIM card info by USSD') 646 logger.warning('Error when requesting SIM card info by USSD')
647 return '' 647 return ''
648 648
649 def updateChipInfo(msisdn): 649 def updateChipInfo(msisdn):
650 global BASE_CHIPINFO 650 global BASE_CHIPINFO
651 global CHIPINFO 651 global CHIPINFO
652 global MSISDN 652 global MSISDN
653 653
654 MSISDN = msisdn 654 MSISDN = msisdn
655 if CHIPINFO.find(msisdn) == -1: 655 if CHIPINFO.find(msisdn) == -1:
656 CHIPINFO = BASE_CHIPINFO + '-' + msisdn 656 CHIPINFO = BASE_CHIPINFO + '-' + msisdn
657 657
658 logger.info('CHIPINFO: {0}'.format(CHIPINFO)) 658 logger.info('CHIPINFO: {0}'.format(CHIPINFO))
659 659
660 def main(): 660 def main():
661 global logger 661 global logger
662 662
663 log_format = '%(asctime)s %(levelname)s: %(message)s' 663 log_format = '%(asctime)s %(levelname)s: %(message)s'
664 664
665 logging.basicConfig(format=log_format, level=logging.INFO) 665 logging.basicConfig(format=log_format, level=logging.INFO)
666 logger = logging.getLogger(__name__) 666 logger = logging.getLogger(__name__)
667 667
668 logger_formatter = logging.Formatter(log_format) 668 logger_formatter = logging.Formatter(log_format)
669 logger_handler = TimedRotatingFileHandler('logs/log', when='midnight') 669 logger_handler = TimedRotatingFileHandler('logs/log', when='midnight')
670 logger_handler.setFormatter(logger_formatter) 670 logger_handler.setFormatter(logger_formatter)
671 logger.addHandler(logger_handler) 671 logger.addHandler(logger_handler)
672 672
673 requests_logger = logging.getLogger('requests') 673 requests_logger = logging.getLogger('requests')
674 requests_logger.setLevel(logging.WARNING) 674 requests_logger.setLevel(logging.WARNING)
675 675
676 logger.info('Initializing modem...') 676 logger.info('Initializing modem...')
677 677
678 modem = GsmModem(PORT, BAUDRATE, smsReceivedCallbackFunc=handleSms) 678 modem = GsmModem(PORT, BAUDRATE, smsReceivedCallbackFunc=handleSms)
679 modem.smsTextMode = True 679 modem.smsTextMode = True
680 modem.connect(PIN) 680 modem.connect(PIN)
681 681
682 logger.info('Waiting for network coverage...') 682 logger.info('Waiting for network coverage...')
683 modem.waitForNetworkCoverage(10) 683 modem.waitForNetworkCoverage(10)
684 684
685 logger.info('Modem ready') 685 logger.info('Modem ready')
686 686
687 getPulsaInfo(modem) 687 getPulsaInfo(modem)
688 sleep(2) 688 sleep(2)
689 689
690 simcard_info = getSIMCardInfo(modem) 690 simcard_info = getSIMCardInfo(modem)
691 msisdn = xltunai.getMSISDNFromSIMCardInfo(simcard_info) 691 msisdn = xltunai.getMSISDNFromSIMCardInfo(simcard_info)
692 692
693 if not msisdn: 693 if not msisdn:
694 logger.warning('Gagal mendapatkan msisdn, terminating') 694 logger.warning('Gagal mendapatkan msisdn, terminating')
695 sleep(5) 695 sleep(5)
696 sys.exit(2) 696 sys.exit(2)
697 697
698 imsi = modem.imsi 698 imsi = modem.imsi
699 logger.info('MSISDN: {0} -- IMSI: {1}'.format(msisdn, imsi)) 699 logger.info('MSISDN: {0} -- IMSI: {1}'.format(msisdn, imsi))
700 700
701 updateChipInfo(msisdn) 701 updateChipInfo(msisdn)
702 saveSimCardInfoToRedis(imsi, msisdn) 702 saveSimCardInfoToRedis(imsi, msisdn)
703 703
704 sleep(2) 704 sleep(2)
705 705
706 saveSignalStrengthToRedis(modem.signalStrength) 706 saveSignalStrengthToRedis(modem.signalStrength)
707 707
708 logger.info('Process stored SMS') 708 logger.info('Process stored SMS')
709 try: 709 try:
710 modem.processStoredSms() 710 modem.processStoredSms()
711 except: 711 except:
712 logger.warning('Failed on Process stored SMS') 712 logger.warning('Failed on Process stored SMS')
713 713
714 logger.info('Delete stored SMS') 714 logger.info('Delete stored SMS')
715 try: 715 try:
716 modem.deleteMultipleStoredSms() 716 modem.deleteMultipleStoredSms()
717 except: 717 except:
718 #logger.warning('Failed on delete SMS') 718 #logger.warning('Failed on delete SMS')
719 pass 719 pass
720 720
721 sleep(2) 721 sleep(2)
722 722
723 checkAccount(modem) 723 checkAccount(modem)
724 sleep(5) 724 sleep(5)
725 725
726 enablePull() 726 enablePull()
727 727
728 checkBalance(modem) 728 checkBalance(modem)
729 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP) 729 sleep(SLEEP_BETWEEN_BALANCE_N_TOPUP)
730 730
731 pullLoop(modem) 731 pullLoop(modem)
732 logger.info('Waiting for SMS message...') 732 logger.info('Waiting for SMS message...')
733 try: 733 try:
734 modem.rxThread.join(2**31) # Specify a (huge) timeout so that it essentially blocks indefinitely, but still receives CTRL+C interrupt signal 734 modem.rxThread.join(2**31) # Specify a (huge) timeout so that it essentially blocks indefinitely, but still receives CTRL+C interrupt signal
735 finally: 735 finally:
736 modem.close(); 736 modem.close();
737 737
738 def saveSimCardInfoToRedis(imsi, msisdn): 738 def saveSimCardInfoToRedis(imsi, msisdn):
739 logger.info('Save sim card info to redis') 739 logger.info('Save sim card info to redis')
740 740
741 data = { 741 data = {
742 'gw': BASE_CHIPINFO, 742 'gw': BASE_CHIPINFO,
743 'imsi': imsi, 743 'imsi': imsi,
744 'msisdn': msisdn, 744 'msisdn': msisdn,
745 'pulsa': PULSA, 745 'pulsa': PULSA,
746 'masa_aktif': MASA_AKTIF 746 'masa_aktif': MASA_AKTIF
747 } 747 }
748 748
749 json_data = json.dumps(data) 749 json_data = json.dumps(data)
750 750
751 map_data = { 751 map_data = {
752 BASE_CHIPINFO + '.simcardinfo': json_data, 752 BASE_CHIPINFO + '.simcardinfo': json_data,
753 'simcardinfo.gw:' + BASE_CHIPINFO: json_data, 753 'simcardinfo.gw:' + BASE_CHIPINFO: json_data,
754 'simcardinfo.imsi:' + imsi: json_data, 754 'simcardinfo.imsi:' + imsi: json_data,
755 'simcardinfo.msisdn:' + msisdn: json_data 755 'simcardinfo.msisdn:' + msisdn: json_data
756 } 756 }
757 757
758 logger.info(map_data) 758 logger.info(map_data)
759 759
760 redis_pipe = redis_client.pipeline() 760 redis_pipe = redis_client.pipeline()
761 761
762 try: 762 try:
763 redis_pipe.mset(map_data) 763 redis_pipe.mset(map_data)
764 764
765 for k in data: 765 for k in data:
766 redis_pipe.expire(k, 3600 * 24 * 60) 766 redis_pipe.expire(k, 3600 * 24 * 60)
767 767
768 except: 768 except:
769 logger.warning('Failed to save simcardinfo to redis') 769 logger.warning('Failed to save simcardinfo to redis')
770 finally: 770 finally:
771 redis_pipe.execute() 771 redis_pipe.execute()
772 772
773 if __name__ == '__main__': 773 if __name__ == '__main__':
774 pidfile = open('pid.txt', 'w') 774 pidfile = open('pid.txt', 'w')
775 pidfile.write(str(getpid())) 775 pidfile.write(str(getpid()))
776 pidfile.close() 776 pidfile.close()
777 777
778 # trap CTRL-C 778 # trap CTRL-C
779 signal.signal(signal.SIGINT, signalHandler) 779 signal.signal(signal.SIGINT, signalHandler)
780 # trap supervisor stop 780 # trap supervisor stop
781 signal.signal(signal.SIGTERM, signalHandler) 781 signal.signal(signal.SIGTERM, signalHandler)
782 782
783 main() 783 main()
784 784