Source code for crappy.inout.gsm

# coding: utf-8

from time import sleep

from .inout import InOut
from .._global import OptionalModule

try:
  from serial import Serial
  from serial.serialutil import SerialException
except (ModuleNotFoundError, ImportError):
  serial = OptionalModule("serial", "Please install the module serial to use "
                          "the Gsm InOut: pip install pyserial")


[docs]class Gsm(InOut): """Block for sending messages by SMS to given phone numbers. Important: This block should be associated with a modifier to manage the messages to send. """
[docs] def __init__(self, numbers: list, port: str = "/dev/ttyUSB0", baudrate: int = 115200) -> None: """Checks arguments validity. Args: numbers(:obj:`list`): The list of numbers the messages will be sent to. The syntax is the following : :: ["0611223344"] port (:obj:`str`, optional): Serial port the GSM is connected to. baudrate(:obj:`int`, optional): Serial baudrate, between 1200 and 115200. """ super().__init__() try: self._ser = Serial(port, baudrate) except SerialException: raise SerialException("GSM not connected or wrong port") # Change the type of numbers to bytes rather than string self._numbers = [number.encode('utf-8') for number in numbers]
[docs] def open(self) -> None: """Sends ``"AT"`` to the GSM and waits for the response : ``"OK"``. """ self._ser.write(b'AT' + b'\r\n') count = 0 while count <= 2: sleep(0.1) data = "" while self._ser.inWaiting() > 0: data += self._ser.read(self._ser.inWaiting()).decode() if "OK" in data: return count += 1 raise TimeoutError("GSM is not responding")
[docs] def set_cmd(self, *cmd: str) -> None: """Sends an SMS whose text is the :obj:`str` received as command to all the phone numbers. Doesn't send anything if the string is empty, and raises a :exc:`TypeError` if the command is not a :obj:`str`. """ if not isinstance(cmd[0], str): raise TypeError("Message should be a string") if cmd[0] != "": self._send_mess(cmd[0])
def _send_mess(self, message: str) -> None: """Commands the GSM to send a message to all the phone numbers. Args: message: The text message to send. """ for number in self._numbers: count = 0 self._ser.write(b'AT' + b'\r\n') w_buff = [b"AT+CMGF=1\r\n", b"AT+CMGS=\"" + number + b"\"\r\n", message.encode()] while count <= 2: data = "" while self._ser.inWaiting() > 0: data += self._ser.read(self._ser.inWaiting()).decode() # Get all the answers in Waiting if data: if count < 2: sleep(1) self._ser.write(w_buff[count]) # Put the message in text mode then enter the # number to contact if count == 2: sleep(0.5) self._ser.write(w_buff[2]) # Write the message self._ser.write(b"\x1a\r\n") # 0x1a : send 0x1b : Cancel send count += 1
[docs] def close(self) -> None: """Closes the serial port.""" self._ser.close()