Commit 66c0728bbfe6ea712e85dce2e321d59a674f30f2

Authored by Adhidarma Hadiwinoto
1 parent e9104fb873
Exists in master

handling maintenance di xl

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