Commit dbfe755b5d9864fdc4558b4803b5105c7d701dba

Authored by Adhidarma Hadiwinoto
1 parent defd7a9765
Exists in master

create a file when limit found

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