Commit 4a065542a06cb41dff7e3c8a87b4c557ec0b4510

Authored by Adhidarma Hadiwinoto
1 parent 7f4bf40722
Exists in master

another debug

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

1 "use strict"; 1 "use strict";
2 2
3 const fs = require('fs'); 3 const fs = require('fs');
4 const EventEmitter = require('events'); 4 const EventEmitter = require('events');
5 const os = require('os'); 5 const os = require('os');
6 6
7 const moment = require('moment'); 7 const moment = require('moment');
8 8
9 const SerialPort = require('serialport'); 9 const SerialPort = require('serialport');
10 const Readline = require('@serialport/parser-readline'); 10 const Readline = require('@serialport/parser-readline');
11 const Delimiter = require('@serialport/parser-delimiter'); 11 const Delimiter = require('@serialport/parser-delimiter');
12 const jsesc = require('jsesc'); 12 const jsesc = require('jsesc');
13 13
14 const logger = require('komodo-sdk/logger'); 14 const logger = require('komodo-sdk/logger');
15 15
16 const smsParser = require('./sms-parser'); 16 const smsParser = require('./sms-parser');
17 17
18 const SIGNAL_STRENGTH_INTERVAL_MS = 60 * 1000; 18 const SIGNAL_STRENGTH_INTERVAL_MS = 60 * 1000;
19 19
20 fs.existsSync('logs/') || fs.mkdirSync('logs/'); 20 fs.existsSync('logs/') || fs.mkdirSync('logs/');
21 const debugLogWriter = process.env.KOMODO_DEBUG_MODEM ? fs.createWriteStream('logs/log-debug-modem.txt', { flags: 'a' }) : null; 21 const debugLogWriter = process.env.KOMODO_DEBUG_MODEM ? fs.createWriteStream('logs/log-debug-modem.txt', { flags: 'a' }) : null;
22 22
23 function debugLog(msg) { 23 function debugLog(msg) {
24 if (debugLogWriter) { 24 if (debugLogWriter) {
25 debugLogWriter.write(msg + os.EOL); 25 debugLogWriter.write(msg + os.EOL);
26 } 26 }
27 } 27 }
28 28
29 29
30 class Modem extends EventEmitter { 30 class Modem extends EventEmitter {
31 constructor(portName) { 31 constructor(portName) {
32 super(); 32 super();
33 this.portName = portName; 33 this.portName = portName;
34 } 34 }
35 35
36 open(cb) { 36 open(cb) {
37 const self = this; 37 const self = this;
38 38
39 debugLog('MODEM: opening ' + this.portName); 39 debugLog('MODEM: opening ' + this.portName);
40 this.port = new SerialPort(this.portName); 40 this.port = new SerialPort(this.portName);
41 41
42 this.port.on('error', function(err) { 42 this.port.on('error', function(err) {
43 debugLog('MODEM: error opening ' + this.portName);
43 if (cb) cb(err); 44 if (cb) cb(err);
44 }); 45 });
45 46
46 this.port.on('open', function() { 47 this.port.on('open', function() {
47 self.resetModem(function() { 48 self.resetModem(function() {
48 self.getIMSI(function() { 49 self.getIMSI(function() {
49 self.emit('open'); 50 self.emit('open');
50 self.getSignalStrength(cb); 51 self.getSignalStrength(cb);
51 52
52 setInterval(function() { 53 setInterval(function() {
53 self.getSignalStrength(); 54 self.getSignalStrength();
54 }, SIGNAL_STRENGTH_INTERVAL_MS) 55 }, SIGNAL_STRENGTH_INTERVAL_MS)
55 56
56 }) 57 })
57 }); 58 });
58 59
59 }); 60 });
60 61
61 62
62 } 63 }
63 64
64 resetParserToDefault() { 65 resetParserToDefault() {
65 const self = this; 66 const self = this;
66 //this.port.unpipe(this.parser); 67 //this.port.unpipe(this.parser);
67 if (this.parser) { this.port.unpipe(this.parser)}; 68 if (this.parser) { this.port.unpipe(this.parser)};
68 this.parser = this.port.pipe(new Readline()); 69 this.parser = this.port.pipe(new Readline());
69 70
70 this.parser.on('data', function(data) { 71 this.parser.on('data', function(data) {
71 if (!data) return; 72 if (!data) return;
72 73
73 debugLog('PARSER-DEFAULT: ' + data); 74 debugLog('PARSER-DEFAULT: ' + data);
74 75
75 if (data.indexOf('+CMTI:') === 0) { 76 if (data.indexOf('+CMTI:') === 0) {
76 self.onSMS(data); 77 self.onSMS(data);
77 } 78 }
78 else if (data.indexOf('+CUSD:') === 0) { 79 else if (data.indexOf('+CUSD:') === 0) {
79 self.onUSSDResponse(data); 80 self.onUSSDResponse(data);
80 } 81 }
81 if (data.indexOf('+CSQ:') === 0) { 82 if (data.indexOf('+CSQ:') === 0) {
82 debugLog('*** Got CSQ signal strength response'); 83 debugLog('*** Got CSQ signal strength response');
83 self.onSignalStrength(data); 84 self.onSignalStrength(data);
84 } 85 }
85 86
86 }); 87 });
87 } 88 }
88 89
89 _write(...args) { 90 _write(...args) {
90 debugLog('COMMAND: ' + args[0]); 91 debugLog('COMMAND: ' + args[0]);
91 this.port.write(...args); 92 this.port.write(...args);
92 this.port.drain(); 93 this.port.drain();
93 } 94 }
94 95
95 write(data) { 96 write(data) {
96 debugLog('COMMAND: ' + data); 97 debugLog('COMMAND: ' + data);
97 this.port.write(data); 98 this.port.write(data);
98 this.port.drain(); 99 this.port.drain();
99 } 100 }
100 101
101 getPort() { 102 getPort() {
102 return this.port; 103 return this.port;
103 } 104 }
104 105
105 onUSSDResponse(data) { 106 onUSSDResponse(data) {
106 debugLog('USSD-RESPONSE: ' + data); 107 debugLog('USSD-RESPONSE: ' + data);
107 this.emit('ussd response', data); 108 this.emit('ussd response', data);
108 } 109 }
109 110
110 onSMS(data) { 111 onSMS(data) {
111 const self = this; 112 const self = this;
112 const port = this.port; 113 const port = this.port;
113 114
114 const matches = data.match(/,(\d+)\s*$/); 115 const matches = data.match(/,(\d+)\s*$/);
115 if (!matches || matches.length < 2) { 116 if (!matches || matches.length < 2) {
116 return; 117 return;
117 } 118 }
118 119
119 const slot = matches[1]; 120 const slot = matches[1];
120 //console.log('*** Ada SMS masuk di slot ' + slot); 121 //console.log('*** Ada SMS masuk di slot ' + slot);
121 122
122 if (!slot) { 123 if (!slot) {
123 debugLog('*** Gagal deteksi slot sms') 124 debugLog('*** Gagal deteksi slot sms')
124 return; 125 return;
125 } 126 }
126 127
127 if (this.parser) { this.port.unpipe(this.parser)}; 128 if (this.parser) { this.port.unpipe(this.parser)};
128 const parser = this.port.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' })) 129 const parser = this.port.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' }))
129 130
130 parser.on('data', function(data) { 131 parser.on('data', function(data) {
131 self.parseSMS(data); 132 self.parseSMS(data);
132 self.port.unpipe(parser); 133 self.port.unpipe(parser);
133 self.resetParserToDefault(); 134 self.resetParserToDefault();
134 135
135 self.write('AT+CMGD=' + slot + '\r'); 136 self.write('AT+CMGD=' + slot + '\r');
136 }) 137 })
137 138
138 this.write('AT+CMGR=' + slot + '\r'); 139 this.write('AT+CMGR=' + slot + '\r');
139 } 140 }
140 141
141 parseSMS(data) { 142 parseSMS(data) {
142 data = data.toString().trim(); 143 data = data.toString().trim();
143 //debugLog(jsesc(data, {wrap: true})); 144 //debugLog(jsesc(data, {wrap: true}));
144 debugLog('SMS-READ: ' + data); 145 debugLog('SMS-READ: ' + data);
145 const sms = smsParser.parseModemResponse(data); 146 const sms = smsParser.parseModemResponse(data);
146 this.emit('incoming sms', sms); 147 this.emit('incoming sms', sms);
147 } 148 }
148 149
149 resetModem(cb) { 150 resetModem(cb) {
150 const self = this; 151 const self = this;
151 152
152 if (this.parser) { this.port.unpipe(this.parser)}; 153 if (this.parser) { this.port.unpipe(this.parser)};
153 const parser = this.port.pipe(new Delimiter({ delimiter: '\nOK\r\n' })); 154 const parser = this.port.pipe(new Delimiter({ delimiter: '\nOK\r\n' }));
154 155
155 parser.on('data', function(data) { 156 parser.on('data', function(data) {
156 const value = data.toString().replace(/^\s+/, '').replace(/\s+$/, ''); 157 const value = data.toString().replace(/^\s+/, '').replace(/\s+$/, '');
157 158
158 debugLog('PARSER-RESETMODEM: modem reseted'); 159 debugLog('PARSER-RESETMODEM: modem reseted');
159 160
160 self.port.unpipe(parser); 161 self.port.unpipe(parser);
161 self.resetParserToDefault(); 162 self.resetParserToDefault();
162 163
163 if (cb) { 164 if (cb) {
164 cb(null, value); 165 cb(null, value);
165 } 166 }
166 }) 167 })
167 168
168 this.write('AT &F Z E0\r'); 169 this.write('AT &F Z E0\r');
169 } 170 }
170 171
171 getIMSI(cb) { 172 getIMSI(cb) {
172 const self = this; 173 const self = this;
173 const port = this.port; 174 const port = this.port;
174 175
175 if (this.parser) { this.port.unpipe(this.parser)}; 176 if (this.parser) { this.port.unpipe(this.parser)};
176 const parser = this.port.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' })) 177 const parser = this.port.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' }))
177 178
178 parser.on('data', function(data) { 179 parser.on('data', function(data) {
179 self.imsi = data.toString().replace(/^\s+/, '').replace(/\s+$/, ''); 180 self.imsi = data.toString().replace(/^\s+/, '').replace(/\s+$/, '');
180 debugLog('PARSER-IMSI: ' + self.imsi); 181 debugLog('PARSER-IMSI: ' + self.imsi);
181 182
182 self.port.unpipe(parser); 183 self.port.unpipe(parser);
183 self.resetParserToDefault(); 184 self.resetParserToDefault();
184 185
185 self.emit('imsi', self.imsi); 186 self.emit('imsi', self.imsi);
186 187
187 if (cb) { 188 if (cb) {
188 cb(null, self.imsi); 189 cb(null, self.imsi);
189 } 190 }
190 }) 191 })
191 192
192 this.write('AT+CIMI\r'); 193 this.write('AT+CIMI\r');
193 } 194 }
194 195
195 getCOPS(cb) { 196 getCOPS(cb) {
196 const self = this; 197 const self = this;
197 198
198 /* 199 /*
199 const parser = this.port.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' })) 200 const parser = this.port.pipe(new Delimiter({ delimiter: '\r\nOK\r\n' }))
200 201
201 parser.on('data', function(data) { 202 parser.on('data', function(data) {
202 const value = data.toString().replace(/^\s+/, '').replace(/\s+$/, ''); 203 const value = data.toString().replace(/^\s+/, '').replace(/\s+$/, '');
203 debugLog('PARSER-COPS: ' + value); 204 debugLog('PARSER-COPS: ' + value);
204 self.port.unpipe(parser); 205 self.port.unpipe(parser);
205 if (cb) { 206 if (cb) {
206 cb(null, value); 207 cb(null, value);
207 } 208 }
208 }) 209 })
209 */ 210 */
210 211
211 //console.log('MODEM: sending AT+COPS?'); 212 //console.log('MODEM: sending AT+COPS?');
212 this.write('AT+COPS?\r'); 213 this.write('AT+COPS?\r');
213 } 214 }
214 215
215 sendUSSD(cmd, cb) { 216 sendUSSD(cmd, cb) {
216 const self = this; 217 const self = this;
217 const port = this.port; 218 const port = this.port;
218 219
219 //console.log('MODEM: ' + moment().format('HH:mm:ss') + ' *** Sending USSD command ' + cmd); 220 //console.log('MODEM: ' + moment().format('HH:mm:ss') + ' *** Sending USSD command ' + cmd);
220 this.write('AT+CUSD=1,"' + cmd + '",15\r'); 221 this.write('AT+CUSD=1,"' + cmd + '",15\r');
221 } 222 }
222 223
223 onSignalStrength(data) { 224 onSignalStrength(data) {
224 if (typeof data !== 'string') { 225 if (typeof data !== 'string') {
225 debugLog('*** onSignalStrength data is not a string'); 226 debugLog('*** onSignalStrength data is not a string');
226 return; 227 return;
227 } 228 }
228 const matches = data.match(/: (\d+),/); 229 const matches = data.match(/: (\d+),/);
229 if (matches.length < 2) return; 230 if (matches.length < 2) return;
230 231
231 this.emit('signal strength', Number(matches[1])); 232 this.emit('signal strength', Number(matches[1]));
232 } 233 }
233 234
234 getSignalStrength(cb) { 235 getSignalStrength(cb) {
235 this.write('AT+CSQ\r'); 236 this.write('AT+CSQ\r');
236 237
237 if (cb) { cb() }; 238 if (cb) { cb() };
238 } 239 }
239 } 240 }
240 241
241 module.exports = Modem; 242 module.exports = Modem;
242 243