Commit f6176dd53b379bdcdfae699225d4e129f63a29c7

Authored by Adhidarma Hadiwinoto
1 parent 66c0728bbf
Exists in master

sleep 60 if not pull

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

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