Commit cf4cacd78f39c1b3abe956eef1d317cd65a73403

Authored by Adhidarma Hadiwinoto
1 parent 6ceba60f58
Exists in master

remove overlimit products

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