zabsalahid / serialport-gsm

SerialPort-GSM is a simplified plugin for communicating with gsm modems. (Primarily for sms) (Focused in PDU mode)
MIT License
90 stars 47 forks source link

modem.executeCommand returns only "OK" #45

Closed Xsmael closed 4 years ago

Xsmael commented 4 years ago

Hi there!

When am trying to run AT commands i only "OK" as a response

example:

modem.executeCommand('AT+CIMI',(result) => { log.debug(result); });

OUTPUT:

{
   "status": "success",
   "request": "executeCommand",
   "data": {
      "result": "OK"
   }
}

how can i get the actual data?, in this case iwas requesting for the IMSI number.

Thanks again!

zabsalahid commented 4 years ago

Hi @Xsmael !

Since not all commands were made a function, you'll be using executeCommand. And requesting for the IMSI number returns a multi line repsonse, so you need your own parsing logic.

// execute a complex custom command - multi line responses needs own parsing logic
          const commandParser = gsmModem.executeCommand('AT^SETPORT=?', (result, err) => {
            if (err) {
              console.log(`Error - ${err}`);
            } else {
              console.log(`Result ${JSON.stringify(result)}`);
            }
          });
          const portList = {};
          commandParser.logic = (dataLine) => {
            if (dataLine.startsWith('^SETPORT:')) {
              const arr = dataLine.split(':');
              portList[arr[1]] = arr[2].trim();
            }
            else if (dataLine.includes('OK')) {
              return {
                resultData: {
                  status: 'success',
                  request: 'executeCommand',
                  data: { 'result': portList }
                },
                returnResult: true
              }
            }
            else if (dataLine.includes('ERROR') || dataLine.includes('COMMAND NOT SUPPORT')) {
              return {
                resultData: {
                  status: 'ERROR',
                  request: 'executeCommand',
                  data: `Execute Command returned Error: ${dataLine}`
                },
                returnResult: true
              }
            }
          };

You can refer to the example file.

Xsmael commented 4 years ago

OK, but i still don't know what i have to do with commandParser.logic() function, where am I supposed to run it so i can supply the dataLine parameter? And how do i get the actual response of AT command?

zabsalahid commented 4 years ago

@Xsmael you may assign executeCommand to a variable and add the logic function to it.

Here, hope this helps.

        let commandParser = modem.executeCommand('AT+CIMI', (result, err) => {
        if (err) {
            console.log(`Error`, err);
        } else {
            console.log(`Result`, result);
        }
    });
    commandParser.dataResult = {};
    commandParser.logic = dataLine => {
        if (dataLine) {
            if (dataLine === 'AT+CIMI') {
                commandParser.dataResult.command = dataLine.trim();
            } else if (/^\d+$/.test(dataLine)) {
                commandParser.dataResult.imsi = dataLine.trim();
            } else {
                commandParser.dataResult.response = dataLine.trim();
            }
        }
        if (dataLine.includes('OK')) {
            return {
                resultData: {
                    status: 'success',
                    request: 'executeCommand',
                    data: { result: commandParser.dataResult },
                },
                returnResult: true,
            };
        } else if (dataLine.includes('ERROR') || dataLine.includes('COMMAND NOT SUPPORT')) {
            return {
                resultData: {
                    status: 'ERROR',
                    request: 'executeCommand',
                    data: `Execute Command returned Error: ${dataLine}`,
                },
                returnResult: true,
            };
        }
    };
Xsmael commented 4 years ago

@zabsalahid Thanks a lot. While this works I would like to understand one thing:

When and where is the logic function executed ? it's not really clear in my mind from this code. with the second code you provided i understood more but still don't get what's up with the logic function.

zabsalahid commented 4 years ago

@Xsmael No problem.

I'm sorry, the logic functions wasn't really explained or included in the documentation, only in the example file.

What it's supposed to do is, when you declare a function on .logic, which should have a single parameter, all data that is being received by the executed command will be passed on to it. So you can do whatever you want with the data being passed on, and do your own logic on it and eventually should have a return object to avoid timeout. The logic function will only work on the command it's assigned to.

Like in your case, you needed to execute the command AT+CIMI, which returns multiple lines of result, so we need a parsing logic to it.

Xsmael commented 4 years ago

@zabsalahid Thanks, got your explanation

but what still seems blurry to me is that you are assigning the logic function after the execution of the command and not before (which would have not been possible either since commandParser itself comes from the result of running the command)

let commandParser = modem.executeCommand('AT+CIMI', (result, err) => {
...
});
commandParser.dataResult = {};
commandParser.logic = ....

this is purely for my understanding, everything is working fine. Also sorry for my obsession for understanding :sweat_smile:, but i like to see clearly in my code.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.