Commit c8812a9bfb82c4cb4c6c94b3c623a2794d24a379

Authored by Adhidarma Hadiwinoto
1 parent eab32ea271
Exists in master

Modem port based on config

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