Page 1 of 1

[ANSWERED]: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 6:40 am
by lochnesz
Hi,

I have a issue with a script that is supposed to check the balance for my mobile pre-paid SIM card. The command is ATD*111# and it works okay with "screen".
When I use it in a script, I get this error:

Error XML Parse Error: not well-formed (invalid token)
Error On character 256 of line number 1.


Here is the script:
Code: Select all
#!/usr/bin/env python

import serial
import time

indigo.server.log ("Starting...") #indigo log message

ser = serial.Serial('/dev/tty.GI505 Modem', 115200, timeout=2) #serial port is /dev/tty.GI505 Modem, baudrate 115200
ser.write('ATD*111# \r')
time.sleep(.5)
res = ser.read(size=100) #read result from modem
time.sleep(1)
ser.close()

indigo.server.log ("Modem result codes: " + "\r" + res) #indigo log message


However, the strange thing is that it works when I add another 0 in the AT command. The modem doesn't give the correct output since the AT command is incorrect, but the script works.

Code: Select all
#!/usr/bin/env python

import serial
import time

indigo.server.log ("Starting...") #indigo log message

ser = serial.Serial('/dev/tty.GI505 Modem', 115200, timeout=2) #serial port is /dev/tty.GI505 Modem, baudrate 115200
ser.write('ATD*1110# \r')
time.sleep(.5)
res = ser.read(size=100) #read result from modem
time.sleep(1)
ser.close()

indigo.server.log ("Modem result codes: " + "\r" + res) #indigo log message


The modem then reports:
ATD*1110#
+CUSD: 2,"Unexpected Data Value",15

Which is expected since there is a zero that shouldn't be there.

Any ideas why the script doesn't work with ATD*111# but it works with ATD*1110# ? Did I miss something?

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 7:00 am
by lochnesz
Okay, a brief update. If I change the read size to 43 it works, but I don't get all the output that I need. 44+ doesn't work.
So changing either the AT command or read size makes the script go through...strange?

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 8:25 am
by matt (support)
Do you get the original "XML Parse Error" when trying to compile the script? I just copy/pasted your original (first) script and it compiled fine. The XML Parse error may not be related to this problem. It is strange that changing the arguments to those calls would change the behavior in that regards.

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 8:32 am
by lochnesz
Compiling is fine, running the script result in the errors.
Yes, really strange how those changes makes the script run successfully or not.
I just upgraded to latest Indigo release, still the same. :(

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 8:35 am
by lochnesz
Hm...if I remove the last line
indigo.server.log ("Modem result codes: " + "\r" + res) #indigo log message
the script runs without errors but I can't see the result.

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 8:37 am
by matt (support)
Comment out the indigo.server.log() call. I'll bet the serial data being returned isn't getting encoded correctly for logging, and the XML error is actually coming from the script API call to do the log.

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 8:38 am
by lochnesz
Yes that works. Any idea how I can see the result? I am new to python.

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 8:41 am
by lochnesz
This is the actual output when I use "screen":
atd*111#
+CUSD: 0,"SMS:a 05GB till 133 s� kan du surfa 0,5GB i 30 dagar f�r endast 30 kr.
SALDO: 29,71 kr
Prisplan: Standard",1

OK


May be something with the character set?

Re: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 8:59 am
by matt (support)
Yeah, I'm not sure what encoding it is using. You can convert it to a string of hex data via:

Code: Select all
import binascii
reshexstr = binascii.hexlify(res)

Or to try to strip the funny characters use:

Code: Select all
resstripped = res.decode('ascii', 'replace')

Re: [ANSWERED]: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 9:05 am
by lochnesz
It worked, thanks! Used resstripped = res.decode('ascii', 'replace') and the message is now in the log:

Modem result codes:
ATD*111#

+CUSD: 0,"SMS:a 05GB till 133 s� kan du surfa 0,5GB i 30 dagar f�r endast 30 kr.
SALDO: 29,71 kr
Prisplan: Standard",1

OK


I am really only interested in the amount after the text SALDO. Is there a way to strip to only the 8 bytes after the word SALDO, and maybe also get that into a Indigo variable?

Re: [ANSWERED]: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 9:37 am
by autolog
Something like:
Code: Select all
balance = modemOutput.split('SALDO: ')[1][0:8]
indigo.variable.updateValue(12345678, value=balance)
Replace 12345678 with your variable Id and modemOutput with whatever you called your output from the modem.

Only partially tested - hope it helps :)

Re: [ANSWERED]: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 10:10 am
by lochnesz
It helped a a lot, thanks! One last very basic question I guess, but I get the error message that my Indigo "global name" variable is not defined. How do I do that? The variable exists in Indigo, but I need it defined in the python script?

Re: [ANSWERED]: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 10:22 am
by autolog
Not quite enough info to fully understand the error but as a starter for 10 - Are you referencing the variable value correctly (which I assume you have already setup)?
It is referenced like this (or similar):
Code: Select all
indigo.variables[12345678].value
If this doesn't solve the issue, post your script and the full error message :)

Re: [ANSWERED]: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 10:28 am
by lochnesz
Oh no, I just forgot the quotation marks as I used the variable name, not the ID.
It works now!
Many thanks! :D

Re: [ANSWERED]: Checking mobile balance with python

PostPosted: Tue Jan 06, 2015 10:41 am
by lochnesz
Here is the final result. :D
The variables "mob_balance_value" and "mob_balance_updated" needs to be created in Indigo and will be updated by the script.

Code: Select all
#!/usr/bin/env python
#check mobile balance from indigo v. 1.0
#uses pyserial

import serial
import time

indigo.server.log ("Starting script requesting mobile balance...") #indigo log message

ser = serial.Serial('/dev/tty.GI505 Modem', 115200, timeout=2) #serial port is /dev/tty.GI505 Modem, baudrate 115200, timeout 2
ser.write('ATD*111#\r') #request balance from telco (syntax for swedish operator comviq)
time.sleep(.5)
res = ser.read(size=256) #read result from modem
time.sleep(1)
ser.close()

resstripped = res.decode('ascii', 'replace') # convert/strip unknown characters to ascii

indigo.server.log ("Modem result output: " + "\r" + resstripped) #indigo log message

balance = resstripped.split('SALDO: ')[1][0:8] # cutting out the actual balance value
indigo.server.log ("Balance: " + balance) #indigo log message

localtime = time.asctime( time.localtime(time.time()) )

indigo.variable.updateValue("mob_balance_value", value=balance)
indigo.variable.updateValue("mob_balance_updated", value=localtime)

indigo.server.log ("Mobile balance script completed on: " + localtime) #indigo log message