Python sending sms via usb serial huawei dongle - python

I'm currently sending sms in python using this code, but sometimes it is unstable. It went straight to "send successfully" but the other party did not receive any message. Is there any other ways to send sms through the dongle? Much appreciated.
This is the code.
class TextMessage:
def __init__(self, recipient="XXXXXXXX", message="TextMessage.content not set."):
self.recipient = recipient
self.content = message
def setRecipient(self, number):
self.recipient = number
def setContent(self, message):
self.content = message
def connectPhone(self):
self.ser = serial.Serial('/dev/ttyUSBSMS', 460800, timeout=5)
time.sleep(1)
def sendMessage(self):
self.ser.write('ATZ\r')
time.sleep(1)
self.ser.write('AT+CMGF=1\r')
time.sleep(1)
self.ser.write('''AT+CMGS="''' + self.recipient + '''"\r''')
time.sleep(1)
self.ser.write(self.content + "\r")
time.sleep(1)
self.ser.write(chr(26))
time.sleep(1)
def disconnectPhone(self):
self.ser.close()
sms = TextMessage("XXXXXXXX","This is the message to send.")
sms.connectPhone()
sms.sendMessage()
sms.disconnectPhone()
print "sent successfully"

Good python gsm modem library:
https://github.com/faucamp/python-gsmmodem

You say that sometimes it is unstable, so I assume that it does sometimes send correctly. On that basis, I imagine that the code is fine. The answer at Python sending many sms via usb serial uses slightly different arguments, which may be worth investigating.
Unless you have a commercial plan, SMS is not guaranteed to arrive in any particular hurry. You can send two messages a minute apart, and have the second one arrive immediately and the first one arrive 5 hours later. Have you waited for a 24 hour period to see if the messages ever arrive?

Related

Using Python to Automate SMS reply using Raspberry pi w/ Quectel EC25

I made a 4g hotspot last year with a Quectel ec25 and raspberry pi, it has worked just fine for this purpose. Earlier this year I wanted to expand its capabilities to automatically reply to text messages with status updates for certain systems. I was able to figure out sending and receiving a text message with AT commands just fine but I am having trouble getting python to recognize and respond to a text message with key words. I found this code,
http://www.python-exemplary.com/index_en.php?inhalt_links=navigation_en.inc.php&inhalt_mitte=raspi/en/gsm.inc.php, and have modified it slightly to make the EC25 work with the USB serial.
I have 2 SSH sessions going at once, one with the command line up and the other with a minicom session to monitor serial. the EC25 is sending indications to the Pi that it is receiving a message, its output when a message is received is "+CMTI: "ME",0" but the pi has no response to it. The code seems to be unresponsive on this part. it will print "listening for incoming SMS..." but then it will never go beyond that, even when it receives text messages.
reply = ser.read(ser.inWaiting())# Clean buf
print "Listening for incoming SMS..."
while True:
reply = ser.read(ser.inWaiting())
if reply != "":
I have tried it with just ser.read() and ser.inWaiting() but that sends it into a bad feedback loop.
Here is my code.
# SIMSMS1.py
# pip install pyserial
import RPi.GPIO as GPIO
import serial
import time, sys
import datetime
P_BUTTON = 24 # Button, adapt to your wiring
def setup():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(P_BUTTON, GPIO.IN, GPIO.PUD_UP)
SERIAL_PORT = "/dev/ttyUSB3" # Raspberry Pi 3
ser = serial.Serial(SERIAL_PORT, baudrate = 115200, timeout = 5)
setup()
ser.write("AT+CMGF=1\r") # set to text mode
time.sleep(1)
ser.write('AT+QURCCFG="urcport","usbmodem"\r') #set URC Indication
time.sleep(1)
ser.write('AT+CPMS="ME","ME","ME"\r') #set memory to Mobile equipment message storage
time.sleep(1)
ser.write('AT+CMGD=1,4\r') # delete all SMS
time.sleep(1)
reply = ser.read(ser.inWaiting())# Clean buf
print "Listening for incoming SMS..."
while True:
reply = ser.read(ser.inWaiting())
if reply != "":
ser.write("AT+CMGR=1\r") # read message
time.sleep(3)
reply = [ser.read(ser.inWaiting())]
print "SMS received. Content:"
print reply
if "getStatus" in reply:
t = str(datetime.datetime.now())
if GPIO.input(P_BUTTON) == GPIO.HIGH:
state = "Button released"
else:
state = "Button pressed"
ser.write('AT+CMGS="+1xxxxxxxxxx"\r') #designate phone number
time.sleep(3)
msg = "Sending status at " + t + ":--" + state
print "Sending SMS with status info:" + msg
ser.write(msg + chr(26))
time.sleep(3)
ser.write('AT+CMGD=1,4\r') # delete all messages
time.sleep(3)
ser.read(ser.inWaiting()) # Clear buf
time.sleep(5)
this is the output of on the serial, the last line is a message being received
AT+CMGF=1
OK
AT+QURCCFG="urcport","usbmodem"
OK
AT+CPMS="ME","ME","ME"
+CPMS: 0,255,0,255,0,255
OK
AT+CMGD=1,4
OK
+CMTI: "ME",0
I know it has something to do with the "reply = ser.read(ser.inWaiting())" but i cant figure out what to write to make it work. Thank you in advance
The easiest way might be polling the message received.
Maybe the EC25 has some possible gpio. Once any message comes, the gpio would generate a pulse signal.

GSM modem sends SMS including some AT command in the text

In our SMS server we have an old GSM modem(Siemens iRZ ES75iT) connected by COM port.
We have a python script which allows to send SMS messages.
Here is the code of sms sender function:
def sendsms(to, message):
message = message.replace('#', '\0')
if (len(message) > 140 ):
message = message[0:140]
print "Connecting phone"
ser = serial.Serial('/dev/ttyS0', 115200, timeout=12)
time.sleep(1)
ser.write('AT\r')
time.sleep(1)
print "AT"
ser.write('AT+CMGD="ALL"\r')
time.sleep(2)
print "AT+CMGDA=DEL ALL"
ser.write('AT+CMGF=1\r')
time.sleep(1)
print "AT+CMGF=1, text mode"
ser.write('''AT+CMGS="''' + to + '''"\r''')
time.sleep(2)
ser.write(message + "\r")
time.sleep(3)
ser.write(chr(26))
time.sleep(1)
print message
print "disconnecting"
ser.flush()
ser.close()
The script usually working as expected but sometimes we get SMS containing "AT" string in the text, like
"**AT** <text we expect to see>"
or
"<text we expect to see> **AT**"
The question is why we are getting such text in the message and how to avoid it? Thanks in advance.
This is an issue related to at command echo, every time you send an AT command it is echoed on serial. We have python scripts for sending sms.
what we normally do is disable the echo before sending any AT command.
send this command
ser.write('ATE0\r')
This command will turn off the echo
before sending
ser.write('AT')
Hope this helps

Pubsub Ack'd messages continuously re-deliver every 10s (Python beta client)

Working with the beta Google Pub/Sub client (v0.28.3)
Has anyone seen a scenario where the same message is constantly redelivered every 10s, even after acking it?
This goes beyond the at-least-once nature of Pub/Sub. It happens sporadically, but when it does occur we see the same message continuously for several hours.
I suspect it's because we process incoming messages in a background thread from the subscriber; but haven't yet been able to consistently reproduce it. Is that not kosher for some reason?
If a bug, happy to file it but operating on the assumption we're doing something wrong. Has anyone dealt with similar issues?
With debug logging we see something like:
D 13:51:46.000 Received response: received_messages { ... message_id: "155264162517414" ... }
D 13:51:46.000 New message received from Pub/Sub: %r
I 13:51:46.000 Processing Message: 155264162517414
I 13:51:48.000 Acking Message: 155264162517414
D 13:51:48.000 Sending request: ack_ids: "LDR..."
D 13:51:50.000 Snoozing lease management for 4.009431 seconds.
D 13:51:50.000 Renewing lease for 0 ack IDs.
D 13:51:50.000 The current p99 value is 10 seconds.
...
D 13:51:59.000 Received response: received_messages { ... message_id: "155264162517414" ... }
D 13:51:59.000 New message received from Pub/Sub: %r
I 13:51:59.000 Processing Message: 155264162517414
Here's a toy version of code that shows how we are threading and this sometimes triggers the issue running locally:
import Queue
import logging
import threading
import random
import time
from google.cloud import pubsub
SUBSCRIPTION_PATH = ...
class Worker(threading.Thread):
"""Background thread to consume incoming messages."""
def __init__(self, name):
threading.Thread.__init__(self, name=name)
self.queue = Queue.Queue()
def run(self):
while True:
message = self.queue.get()
self.process(message)
print '<< Acking :', message.message_id
message.ack()
self.queue.task_done()
def process(self, message):
"""Fake some work by sleeping for 0-15s. """
s = random.randint(0, 15)
print '>> Worker sleeping for ', s, message.message_id
for i in range(s):
time.sleep(1)
print i
class Subscriber(threading.Thread):
"""Handles the subscription to pubsub."""
def __init__(self):
threading.Thread.__init__(self, name='Subscriber')
self.subscriber = pubsub.SubscriberClient()
self.worker = Worker('FakeWorker')
self.worker.daemon = True
def run(self):
self.worker.start()
flow_control = pubsub.types.FlowControl(max_messages=10)
policy = self.subscriber.subscribe(SUBSCRIPTION_PATH,
flow_control=flow_control,
callback=self._consume)
print 'Sub started, thread', threading.current_thread()
def _consume(self, message):
self.worker.queue.put(message)
if __name__ == '__main__':
subscriber = Subscriber()
subscriber.start()
while 1:
pass
Thank you!
In addition to the at-least-once nature of Pub/Sub, acks in Pub/Sub are best effort. This means that there are two potential ways that an ack can "mess up".
The message can be successfully acked by Pub/Sub, and redelivered once (presumably due to a race condition).
The message can fail to be successfully acked.
In a world where the second situation obtains, the client library will not give you any kind of error (because the client library itself is not given one), and you will start seeing the message on a cadence (and this will be 10 seconds if your process times are short).
The solution to this is to simply ack the message again when you receive it. I assume (it is not clear from the toy code, so I am guessing) that you are simply ignoring repeat messages, but if you ack the repeat, you should stop getting it.
If you are re-acking the message, then please open an issue against the client library.

Python: socket.recv() doesn't receive push messages

Python: socket.recv() doesn't receive push messages
Hello,
I'm coding a socket based IMAP client in Python3 which successfully establishes a connection to the server, succussfully transmits the IDLE command but then fails to receive incoming data from the server.
If you are wondering why I do not use libimap or sth., the answer is easy: I just want to implement an IDLE command-supporting python client which must be written without that library.
An extract:
import socket
def runIMAPPeek():
#socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(29 * 60)
#connection
s.connect((IMAP_SERVER , 443))
#login
data = b"a1 LOGIN " + USER + b" " + PASSWORD + b"\n"
s.sendall(data)
reply = read(s)
#Idle loop
#As in RFC 3501 connection will be reinitialized every 29 minutes
while True:
# Idle command
print("#Sending IDLE...")
data = b"a2 IDLE\n"
s.sendall(data)
reply = read(s)
if reply.startswith("+ idling"):
print(" #idling.")
else:
print(" #Unexpected answer: {}".format(reply))
#sys.exit()
# waiting for incoming mails ----------------------------------
try:
push_msg = read(s)
# got push message = new message arrived
getNewEnvelope(s, push_msg)
except socket.timeout:
# timeout
print(" #timeout. Reinitializing IDLE...")
#TODO: except (KeyboardInterrupt, SystemExit)
# Quit Idle
data = b"DONE\n"
write(s, data)
reply = read(s)
if reply.startswith(prefix_str + " OK"):
print(" #quit idling.")
else:
print(" #Unexpected answer: {}".format(reply))
#sys.exit()
def read(s):
"""Read socket data, print it, convert to string, replace new lines
and return it.
"""
print("#Receiving...", end=" ")
reply = s.recv(4096)
reply = str(reply)[2:-1] #convert and remove byte indicators
reply = reply.replace("\\r\\n", "\n")
print(reply)
return reply
The problem is marked with the "----". Although messages are received in the mailbox, python does not react but remains in the idling/receiving state. In fact, the print line above the s.recv() command isn't even printed.
I tried everything successfully with Telnet, so there is no server problem.
In addition to my comment above, you have never selected INBOX. You will not receive any push messages, because you haven't told it what folder you want. Technically, IDLE is not valid in the unselected state.
Constructs like this one:
if reply.startswith("+ idling"):
are completely non-compliant. The IDLE RFC specifies that the client shall expect a continuation request, not this particular string (which also happens to be a continuation request).

handle client disconnect with openfire server If the client is idle for 5mins

I wrote a demo about chatting with other clients with pyxmpp2,but when the client is idle for about 5 minutes the server would disconnect with the client,openfire cannot config the timeout,so I decide to send a presence message in 5 minutes ,the problem puzzling me is when to send the prensense message?
import pyxmpp2
class EchoBot(EventHandler, XMPPFeatureHandler):
"""Echo Bot implementation."""
def __init__(self, my_jid, settings):
version_provider = VersionProvider(settings)
self.client = Client(my_jid, [self, version_provider], settings)
#event_handler(AuthorizedEvent)
def handle_authorized(self,event):
presence = Presence(to_jid ="....",stanza_type = "available")
self.client.stream.send(presence)
def run(self):
"""Request client connection and start the main loop."""
self.client.connect()
self.client.run()
def disconnect(self):
""""""
self.client.disconnect()
def keepconnect(self):
presence = Presence(to_jid ="....",stanza_type = "available")
self.client.stream.send(presence)
print "send presence"
....
bot = McloudBot(JID(mcloudbotJID), settings)
try:
bot.run()
t = threading.Thread(target=bot.run())
timer=threading.Timer(5,bot.keepconnect())
t.start()
timer.start()
except KeyboardInterrupt:
bot.disconnect()
but it seems not work...
Check out
http://community.igniterealtime.org/docs/DOC-2053
This details the dissconnect idle property in OF that you can set to a value in milli seconds
Dissconnecting idle clients is something that's important in session based comms. It has more to do with the client closing unexpectedly rather than just neing idle though.
You can implement ping or heartbeat packet sending in your client as you mention above. Maybe check out the pidgin implementation of whitespace IQ requests.
Hope this steers you in the right direction.
James

Categories