Commit b89af83d862aff94528f919f8c9b54858beb85b5

Authored by Adhidarma Hadiwinoto
1 parent 9f368b7fce
Exists in master

verbose before remove product

Showing 1 changed file with 1 additions and 0 deletions Inline Diff

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