Commit 5b4a1904aa2d5cfac122806d0219d7e258153013

Authored by Adhidarma Hadiwinoto
1 parent 5a4cb4ae41
Exists in master

manajemen signal

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

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