Commit df1a2f6777709fbeefb5eab3b9819aa44ed8fd7a

Authored by Adhidarma Hadiwinoto
1 parent cda18aea3f
Exists in master

penanganan saldo kurang

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