Skip to content

SIM800L, SIM800C and SIM800H GSM module library for the Raspberry Pi to send, receive, delete SMS messages, perform HTTP GET/POST requests and many additional queries

License

Notifications You must be signed in to change notification settings

Ircama/sim800l-gsm-module

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Raspberry Pi SIM800L, SIM800C and SIM800H GSM module

Raspberry Pi PyPI Python Versions PyPI download month GitHub license

SIM800L GSM module library for Linux systems like the Raspberry Pi. This library was also successfully tested with SIM800C and should also support SIM800H.

This library provides a driver for SIMCom GSM modules (SIM800L, SIM800C, SIM800H) via AT commands over a serial interface. It supports SMS (including multipart), HTTP/HTTPS GET and POST requests, DNS resolution, RTC synchronization, and access to module information. SMS messaging can be done in TEXT, HEX, or PDU mode (default: PDU). Possibly the driver is also compatible with newer modules like SIM7100 and SIM5300.

Key features include:

  • send_sms(): Sends SMS messages, automatically handling multipart when necessary.
  • read_next_message(): Retrieves the next SMS, abstracting message type and reassembling multipart content.
  • http(): Executes HTTP and HTTPS GET/POST requests, returning response status and payload.
  • dns_query(): Resolves domain names to IPs via the module’s DNS functionality.
  • ping(): ICMP ping of a domain name or IP address.
  • internet_sync_time(): syncronize the RTC time with the NTP time server and returns the current NTP time.

The library also exposes over 30 methods to configure and query the SIM module.

AT Protocol issues

The SIMCom SIM800 series (including models such as SIM800L, SIM800C, SIM800H and others) supports a broad set of cellular and Internet features, all accessible through a proprietary AT command set over the module’s asynchronous serial interface. This software utilizes only a limited subset of these extensive set of AT commands.

The AT command protocol is fundamentally inadequate for reliable and verifiable communication and presents intrinsic limitations when employed for robust operations: it is inherently textual and lacks the formal structure of communication protocols that utilize packetized data exchange.

AT commands are plain-text strings without explicit framing mechanisms. Unlike packet-based protocols, AT messages do not encapsulate data within headers that define payload length, type, or integrity information such as checksums or CRCs. Consequently, parsing and verifying the completeness and correctness of messages becomes error-prone.

Moreover, AT-based communication lacks a standardized state machine or signaling mechanisms to indicate distinct phases of a connection lifecycle. Commands that initiate, maintain, or terminate connections must be issued and interpreted in a predefined order, but the protocol itself does not return the transition between these states. This absence of inherent session management results in brittle implementations, where the client must continually probe the status of operations.

In addition, vendor-specific instructions introduce proprietary connection setup sequences requiring polling or conditional branching based on context-sensitive responses, and may also include asynchronous "Unsolicited Result Codes" within the textual communication that needs special processing while managing the workflow. Without structured feedback or flags denoting session phases, the client application must rely on loosely coupled responses to maintain protocol correctness.

Through an accurately tested heuristic approach, this software attempts to handle all supported operations via the AT protocol as robustly as possible, with the goal of automatically recovering from errors whenever feasible.

Setup

This module only installs on Linux (not on Windows).

Hw Requirements

  • Linux system with a UART serial port, or Raspberry Pi with Raspberry Pi OS (this library has been tested with Buster and Bullseye).
  • External power supply for the SIM800L (using the Raspberry Pi 5V power supply, a standard diode (1N4007) with voltage drop of about 0.6 volts and a 1 F capacitor might work). A stable power supply with adequate power is crucial for the correct operation of the module.

Installation

Check that the Python version is 3.6 or higher (python3 -V), then install the sim800l-gsm-module with the following command:

python3 -m pip install sim800l-gsm-module

Prerequisite components: pyserial, gsm0338. All needed prerequisites are automatically installed with the package.

Alternatively to the above mentioned installation method, the following steps allow installing the latest version from GitHub.

  • Optional preliminary configuration (if not already done):

    sudo apt-get update
    sudo apt-get -y upgrade
    sudo add-apt-repository universe # this is only needed if "sudo apt install python3-pip" fails
    sudo apt-get update
    sudo apt install -y python3-pip
    python3 -m pip install --upgrade pip
    sudo apt install -y git
  • Run this command:

    python3 -m pip install git+https://github.com/Ircama/sim800l-gsm-module

To uninstall:

python3 -m pip uninstall -y sim800l-gsm-module

Hardware connection

sim800l

Disabling the serial console login

Disabling the serial console login is needed in order to enable communication between the Raspberry Pi and SIM800L via /dev/serial0.

  • Open the terminal on your pi and run sudo raspi-config
  • Select Interfaces → Serial
  • Select No to the 1st prompt and Yes for the 2nd one.

Basic use

Check Usage examples. Basic program:

from sim800l import SIM800L
sim800l = SIM800L()
sim800l.setup()
print("Unit Name:", sim800l.get_unit_name())

API Documentation

For debugging needs, logs can be set to the maximum level (verbose mode, tracing each request/response) with the following command:

import logging
logging.getLogger().setLevel(5)`

Main Commands

sim800l = SIM800L(port="/dev/serial0", baudrate=115000, timeout=3.0, write_timeout=300, inter_byte_timeout=10, mode="PDU")

Class instantiation (using pySerial)

Parameters:

  • port (str): Serial port (e.g., /dev/serial0).
  • baudrate (int): Baud rate (default: 115000).
  • timeout (float): Read timeout in seconds.
  • write_timeout (int): Write timeout in seconds.
  • inter_byte_timeout (int): Timeout between bytes during read.
  • mode (str): SMS mode (TEXT, HEX, or PDU).

setup(disable_netlight=False)

Run setup strings for the initial configuration of the SIM800 module

  • disable_netlight: True if the Net Light LED has to be disabled (default is to enable it).

return: True if setup is successfully completed; None in case of module error.


SMS

read_next_message(all_msg=False, index=0, delete=True, tuple=False, concatenate=False, delta_min=15)

Check messages, read one message and then delete it. This function can be repeatedly called to read all stored/received messages one by one and delete them.

  • all_msg: True if no filter is used (read and unread messages). Otherwise only the unread messages are returned. return: retrieved message text (string), otherwise: None = no messages to read; False = read error (module error)

Aggregate multipart PDU messages. Only delete messages if there are no errors.

  • all_msg: True if no filter is used (return both read and non read messages). Otherwise, only the non read messages are returned.
  • index: read index message in processed array; default is the first one.
  • delete: delete the message after reading it.
  • tuple: returns a tuple instead of the plain text. Tuple: [MSISDN origin number, SMS date string, SMS time string, SMS text]
  • concatenate: concatenate text messages (text mode) when read message is > 150 chars. Not reliable (suggest using PDU mode)
  • delta_min: max time in minutes to keep uncompleted multipart undecoded (allowing to wait for its completion)

return: retrieved message text (string), otherwise: None = no messages to read; False = read error (module error)

As an example of usage, this is a trivial continuous SMS message monitor showing all incoming messages for 10 minutes (it also includes a recovery operation that resets the device in case of fault, that should never occur in normal conditions):

import time
import threading
from sim800l import SIM800L

RESET_GPIO = 24

def reset_and_setup(sim800l, disable_netlight):
    """Perform hard reset and attempt setup."""
    time.sleep(1)
    sim800l.hard_reset(RESET_GPIO)
    time.sleep(20)
    return sim800l.setup(disable_netlight=disable_netlight)

def sms_listener():
    sim800l = SIM800L()
    net_light_disabled = not sim800l.get_netlight()

    if not sim800l.setup(disable_netlight=net_light_disabled):
        if not reset_and_setup(sim800l, net_light_disabled):
            return

    print("Message monitor started")
    while True:
        msg = sim800l.read_next_message(all_msg=True)
        if msg is False:
            if not reset_and_setup(sim800l, net_light_disabled):
                return
            continue
        if msg is not None:
            print("Received SMS message:", repr(msg))

# Usage Example: Start SMS Message Monitor
listener_thread = threading.Thread(target=sms_listener, daemon=True)
listener_thread.start()

print("Sample running for 10 minutes and printing any received message.")
time.sleep(600)
print("Terminated.")

send_sms(destno, msgtext, ...)

Sends an SMS.

It includes sending multipart SMS messages (long SMS) if mode is PDU.

Parameters:

  • destno (str): Destination phone number.
  • msgtext (str): Message content.
  • validity (int): SMS validity period (PDU mode).
  • smsc (str): SMSC number (PDU mode).
  • requestStatusReport (bool): Request delivery report.
  • rejectDuplicates (bool): Reject duplicate messages.
  • sendFlash (bool): Send as flash SMS.

Returns:

  • True: SMS sent successfully.
  • False: Failed to send.

read_and_delete_all(index_id=0, delete=True)

Reads and deletes all SMS messages.

Read the message at position 1, otherwise delete all SMS messages, regardless the type (read, unread, sent, unsent, received). If the message is succesfully retrieved, no deletion is done. (Deletion only occurs in case of retrieval error.) Notice that, while generally message 1 is the first to be read, it might happen that no message at position 1 is available, while other positions might still include messages; for those cases (missing message at position 1, but other messages available at other positions), the whole set of messages is deleted.

Parameters:

  • index_id: Starting index
  • delete: Whether to delete after reading

Returns:

  • str: Message text
  • None: No messages
  • False: Error

read_sms(index_id)

Reads an SMS by index.

Parameters:

  • index_id (int): SMS storage index (1-based).

Returns:

  • tuple: (origin, date, time, text).
  • None: No message.
  • False: Read error.

delete_sms(index_id)

Deletes an SMS by index.

Parameters:

  • index_id (int): SMS storage index.

GPRS

dns_query(apn=None, domain=None, timeout=10)

Perform a DNS query.

Parameters:

  • apn (str): The APN string required for network context activation.
  • domain (str): The domain name to resolve.
  • timeout (int): Maximum duration in seconds to wait for responses (default: 10).

Returns:

  • dict: On success, returns a dictionary with keys:

    • 'domain': resolved domain name
    • 'ips': list of resolved IP addresses
    • 'local_ip': the device's IP address
    • 'primary_dns': Primary DNS server used for the query
    • 'secondary_dns': Secondary DNS server used for the query
  • False: On failure due to command error, timeout, or unexpected responses.

  • None: If the DNS query completes but no result is found (domain not resolved).


ping(apn=None, domain=None, timeout=10)

Perform a ICMP ping.

Parameters:

  • apn (str): The APN string required for network context activation.
  • domain (str): The domain name to ping.
  • timeout (int): Maximum duration in seconds to wait for responses (default: 10).

Returns: dict or False

  • dict: On success, returns a dictionary summarizing the ICMP ping results with keys:

    • 'local_ip': the device's IP address

    • 'ip': the target IP address that was pinged (not available if the ping failed)

    • 'results': (not available is the ping failed) a list of dictionaries, one per ping response, each with:

      • 'seq': sequence number of the ping response
      • 'ttl': time-to-live value returned in the ICMP response
      • 'time': round-trip time (RTT) in milliseconds
  • False: On failure due to command error, timeout, or unexpected responses.


http(url, data=None, apn=None, ...)

Run the HTTP GET method or the HTTP POST method and return retrieved data.

Automatically perform the full PDP context setup and close it at the end (use keep_session=True to keep the IP session active). Reuse the IP session if an IP address is found active.

Automatically open and close the HTTP session, resetting errors.

Parameters:

  • url (str): Target URL.
  • data (bytes): Payload for POST requests.
  • apn (str): APN for GPRS connection.
  • method (str): GET or POST (or PUT, same as POST).
  • use_ssl (bool): Use HTTPS.
  • content_type (str): HTTP Content-Type header.
  • http_timeout (int): Timeout in seconds.
  • keep_session (bool): Keep PDP context active.

Returns:

  • status, str/bytes: tuple including two values: HTTP status code (numeric, e.g., 200) and Response data (which can be text or binary).
  • False, None: Request failed.

While the Content type header field can be set, the Content encoding is always null.

Sending data with zlib is allowed:

import zlib
body = zlib.compress('hello world'.encode())
status, ret_data = sim800l.http("...url...", method="POST", content_type="zipped", data=body, apn="...")

Note on SSL: SIM800L does not support AT+HTTPSSL on firmware releases less than R14.18 (e.g., 1308B08SIM800L16, which is SIM800L R13.08 Build 08, 16 Mbit Flash, does not support SSL). Newer firmwares of SIM800L support SSL2, SSL3 and TLS 1.0, but not TLS 1.2 (this is for any SIM800L known firmwares including Revision 1418B06SIM800L24, which is SIM800L R14.18 Build 06, 24 Mbit Flash); old cryptographic protocols are deprecated for all modern backend servers and the connection will be generally denied by the server, typically leading to SIM800L error 605 or 606 when establishing an HTTPS connection. Nevertheless, SIM800C supports TLS 1.2 with recent firmwares and with this device you can use use_ssl=True. No known firmware supports TLS 1.3. Notice that most websites are progressively abandoning TLS 1.2 in favor of TLS 1.3, which offers improved security, performance, and reduced handshake overhead; a device that only supports up to TLS 1.2 risks future incompatibility, as an increasing number of sites will enforce TLS 1.3 exclusively.

Notice also that, depending on the web server, a specific SSL certificate could be needed for a successful HTTPS connection; the SIM800L module has a limited support of SSL certificates and installing an additional one is not straightforfard.

An additional problem is related to possible DNS errors when accessing endpoints. Using IP addresses is preferred.

Example of usage:

from sim800l import SIM800L
sim800l = SIM800L()
sim800l.setup()

print(sim800l.http("httpbin.org/ip", method="GET", apn="..."))

print(sim800l.http("https://www.google.com/", method="GET", apn="...", use_ssl=True))  # Only SIM800C with latest TLS1.2 firmware

internet_sync_time(time_server='193.204.114.232', time_zone_quarter=4, apn=None, http_timeout=10, keep_session=False)

Connect to the bearer, get the IP address and sync the internal RTC with the local time returned by the NTP time server (Network Time Protocol). Automatically perform the full PDP context setup. Disconnect the bearer at the end (unless keep_session = True) Reuse the IP session if an IP address is found active.

  • time_server: internet time server (IP address string)
  • time_zone_quarter: time zone in quarter of hour
  • http_timeout: timeout in seconds
  • keep_session: True to keep the PDP context active at the end return: False if error, otherwise the returned date (datetime.datetime)

Example: "2022-03-09 20:38:09"


get_ip(poll_timeout=4)

Get the IP address of the PDP context

Parameter:

  • poll_timeout: optional poll setting in seconds to wait for the IP address to return as +SAPBR: 1,1,"...".

Returns:

  • valid IP address string if the bearer is connected
  • None: Bearer not connected, no IP address
  • False: Error (e.g., module error)

connect_gprs(apn)

Activates GPRS PDP context.

Parameters:

  • apn (str): APN name for the carrier.

Returns:

  • str: Assigned IP address.
  • False: Connection error.

disconnect_gprs()

Deactivates GPRS PDP context.
Returns:

  • True: Success
  • False: Error

Query Commands

check_sim()

Checks if a SIM card is inserted.

Returns:

  • True: SIM inserted.
  • False: SIM not inserted.
  • None: Module error.

is_registered()

Checks if the SIM is registered on the home network.

Returns:

  • True: Registered.
  • False: Not registered.
  • None: Module error.

get_date()

Retrieves the module's internal clock date.

Returns:

  • datetime.datetime: Current date/time.
  • None: Module error.

get_operator()

Gets the current network operator.

Returns:

  • str: Operator name.
  • False: SIM error.
  • None: Module error.

get_battery_voltage()

Returns battery voltage in volts.

Example: 4.158

Returns:

  • float: Voltage.
  • None: Module error.

get_ccid()

Retrieves SIM ICCID.
Returns:

  • str: ICCID
  • None: Module error

Example: "1122334455667788990f"


get_flash_id()

Retrieves flash memory ID.
Returns:

  • str: Flash ID
  • None: Error

Example: "Device Name:SERIAL§FLASH§MTKSIP§6261§SF§24§01"


get_netlight()

Check the SIM800 Net Light Indicator. Returns:

  • 1: active,
  • 0: inactive,
  • False: error.

get_hw_revision(method=0)

Gets hardware/firmware version.
Parameters:

  • method:
    • 0 = Raw string
    • 1 = Parsed components
    • 2 = Alternate revision format

Returns:

  • str: Version info
  • None: Error

Example: "Revision:1418B05SIM800L24"


get_imsi()

Gets SIM IMSI number.
Returns:

  • str: IMSI
  • None: Error

Example: "112233445566778"


get_msgid()

Return the unsolicited notification of incoming SMS return: number


get_msisdn()

Get the MSISDN subscriber number return: string. None in case of module error.


get_operator_list()

Lists all available network operators.
Returns:

  • dict: {numeric_code: "Operator Name"}
  • None: Error

get_serial_number()

Retrieves module serial number.
Returns:

  • str: Serial
  • None: Error

Example: "866782042319455"


get_service_provider()

Get the Get Service Provider Name stored inside the SIM return: string. None in case of module error. False in case of SIM error.


get_signal_strength()

Gets signal strength (0-100%).
Returns:

  • int: Signal percentage
  • None: Error

Example: 40.625


get_temperature()

Gets module temperature.
Returns:

  • str: Temperature in Celsius
  • None: Error

Example: "24.21"


get_unit_name()

Get the SIM800 GSM module unit name return: string (e.g., "SIM800 R14.18"); None in case of module error.


serial_port()

Return the serial port (for direct debugging) return:


get_clip()

(legacy code, not used)


Configuration

hard_reset(reset_gpio)

Hardware reset via GPIO pin (RPi only).
Parameters:

  • reset_gpio: BCM GPIO pin number

Returns:

  • True: Reset successful
  • None: GPIO library unavailable

set_date()

Syncs the system clock with the module's time.

Returns:

  • datetime.datetime: Updated time.
  • None: Module error.

Utilities

command(cmdstr, lines=-1, waitfor=500, msgtext=None, msgpdu=None, flush_input=True, timeout=2)

Sends raw AT commands to the module.

Executes an AT command. A newline must be added at the end of the AT command (e.g., sim800l.command("AT+CCLK?\n", lines=-1)). Input is flushed before sending the command (flush_input=False disables flushing).

Parameters:

  • cmdstr: AT command string (e.g., "AT+CSQ")
  • lines: Number of response lines to read (-1=read until timeout)
  • msgtext: SMS text content (for SMS commands)
  • msgpdu: PDU-formatted SMS (binary)
  • flush_input: Clear input buffer before sending command
  • timeout: Response timeout in seconds

Returns:

  • str: Raw response ("OK", "ERROR", or data lines)
  • "ERROR" on serial write failure

If lines=0, terminates just after writing text to the device (no bytes read; no return code, e.g. None returned). Note: check_incoming() can be subsequently used to read data from the device (see subsequent example).

Example:

import time
from sim800l import SIM800L

sim800l=SIM800L('/dev/serial0')

# Send data and return the first line
print(sim800l.command("AT+CCLK?\n"))  # ...+CCLK...

# Same as before, but reading both lines
sim800l.command("AT+CCLK?\n", lines=0)  # send AT command without reading data
print("First read line:", sim800l.check_incoming())  # ...+CCLK...
print("Second read line:", sim800l.check_incoming())  # ...'OK'...

# Same as before, but more elaborated
sim800l.command("AT+CCLK?\n", lines=0)
expire = time.monotonic() + 2  # seconds
sequence = ""
s = sim800l.check_incoming()
date = None
while time.monotonic() < expire:
    if s[0] == 'GENERIC' and s[1] and s[1].startswith('+CCLK: "'):
        date = s[1].split('"')[1]
        sequence += "D"
    if s == ('OK', None):
        sequence += "O"
    if sequence == "DO":
        print("Date:", date)
        break
    time.sleep(0.1)
    s = sim800l.check_incoming()

if not date:
    print("Error")

command_data_ok(cmd, attempts=2)

Sends command and retrieves data before "OK".
Parameters:

  • cmd: AT command (without trailing newline)
  • attempts: Retry attempts before returning None or False

Returns:

  • str: Response data
  • None: Module error
  • False: Missing "OK"

command_ok(cmd, check_download=False, check_error=False, cmd_timeout=10, attempts=2)

Send AT command to the device and check that the return sting is OK. Newline must not be put at the end of the string.

  • cmd: AT command
  • check_download: True if the “DOWNLOAD” return sting has to be checked
  • check_error: True if the “ERROR” return sting has to be checked
  • cmd_timeout: timeout in seconds
  • attempts: number of attempts before returning False return: True = OK received, False = OK not received (or module error). If check_error, can return ERROR; if check_download, can return DOWNLOAD

check_incoming()

Internal function, used to check incoming data from the SIM800L module, decoding messages. It also fires the functions configured with callback_incoming(), callback_msg(), callback_clip() and callback_no_carrier(). return: tuple

Return values:

  • ('GENERIC', None): no data received
  • ('GENERIC', data): received data is returned (data is a string)
  • ("HTTPACTION_POST", False, size): invalid HTTP POST method, with return code different from 200
  • ("HTTPACTION_POST", True, size): valid HTTP POST method; size is the number of returned characters
  • ("HTTPACTION_PUT", False, size): invalid HTTP PUT method (same as POST, depending on the parameter to invoke http()), with return code different from 200
  • ("HTTPACTION_PUT", True, size): valid HTTP PUT method (same as POST, depending on the parameter to invoke http()); size is the number of returned characters
  • ("HTTPACTION_GET", False, size): invalid HTTP GET method, with return code different from 200
  • ("HTTPACTION_GET", True, size): valid HTTP GET method; size is the number of returned characters
  • ("IP", "ip address"): bearer connected, received IP address
  • ("IP", None): Disconnected
  • ("CMTI", index_id): received SMS message with index index_id
  • ("NOCARRIER", None): "NO CARRIER" message detected
  • ("RING", None): "RING" message detected
  • ("OK", None): "OK" message detected
  • ("DOWNLOAD", None): "DOWNLOAD" message detected
  • ("ERROR", None): "ERROR" message detected
  • ("DNS", dict): DNS data
  • ("NTP", None, error): NTP query error
  • ("NTP", date, 0): Successful NTP query; date is datetime.datetime format
  • ("COPN", numeric, name): Operator number and name
  • ("CREG", numeric): Registration status
  • ("CTZV", tz1, tz2): Time Zone
  • ("PSUTTZ", year, month, day, hour, minute, second, tz1, tz2): time and time zone
  • ("DST", dst): Daylight Saving Time
  • ("RDY", None): Power procedure completed
  • ("CFUN", numeric): Phone functionality indication
  • ("PIN", pin): PIN
  • ("MSG", "Call Ready): Call ready
  • ("MSG", "SMS Ready): SMS ready

Usage sample 1:

if self.check_incoming() != ("OK", None):
    print("Error")

Charset

set_charset_hex()

Sets HEX character encoding.

Set the module to the HEX character set (only hexadecimal values from 00 to FF)

Returns:

  • "OK" if successful, otherwise None in case of module error.

set_charset_ira()

Set the module to the International reference alphabet (ITU-T T.50) character set return: "OK" if successful, otherwise None in case of module error.


set_charset_gsm()

Sets GSM 03.38 encoding (default).
Returns:

  • "OK" if successful

Conversions

convert_to_string(buf)

Decode GSM 03.38 encoded bytes, returning a string.

Parameters:

  • buf (bytes): GSM 03.38 encoded data (bytes).

Returns:
str - Decoded UTF-8 string.


convert_gsm(string)

Encode string to bytes using the 3GPP TS 23.038 / ETSI GSM 03.38 codec.

Parameters:

  • string (str): Input string.

Returns:
bytes - Encoded GSM 03.38 data.


Callback actions

Unsolicited Result Codes can be optionally configured to fire respective functions.

Unsolicited Result Code Configuration method Corresponding fired function and argument
RING sim800l.callback_incoming(incoming_function) incoming_function()
NO CARRIER sim800l.callback_no_carrier(incoming_function) incoming_function()
+CMTI sim800l.callback_msg(message_function) message_function(message_index)
+CLIP sim800l.callback_clip(calling_function) calling_function(calling_msisdn_number)

Setup example:

def alert_new_message():
    print("Incoming SMS message")

sim800l.callback_msg(alert_new_message)

callback_incoming(action)

Sets a callback for incoming calls.

Parameters:

  • action (function): Function to trigger on incoming call.

callback_no_carrier(action)

Sets a callback for call disconnection.

Parameters:

  • action (function): Function to trigger on disconnect.

callback_msg(action)

Configure a callback function, fired when check_incoming() receives a message (+CMTI returned, indicating new message received).

Sets callback for incoming SMS.
Parameters:

  • action: Function to call on +CMTI alert

callback_clip(action)

Configure a callback function, fired when check_incoming() detects an incoming voice call (+CLIP returned, indicating incoming voice call detected).

Sets callback for incoming voice call.
Parameters:

  • action: Function to call on +CLIP alert

Notes

  • PDU Mode: Recommended for handling long SMS and multipart messages.
  • GPRS: Ensure correct APN settings for your carrier.
  • HTTP: SIM800L supports TLS 1.0 only (modern servers may reject connections); SIM800C supports TLS 1.2.

Usage examples

from sim800l import SIM800L
sim800l = SIM800L('/dev/serial0')

Return module information

from sim800l import SIM800L

sim800l = SIM800L()
sim800l.setup()

Sync time with internet

sim800l.internet_sync_time(apn="...", time_zone_quarter=...)

Send SMS

sms="Hello there"
#sim800l.send_sms(dest.no,sms)
sim800l.send_sms('2547xxxxxxxx',sms)

Read the next SMS message

msg = sim800l.read_next_message(all_msg=True)

HTTP GET samples

print(sim800l.http("httpbin.org/ip", method="GET", apn="..."))
print(sim800l.http("httpbin.org/get", method="GET", use_ssl=False, apn="..."))  # HTTP
print(sim800l.http("httpbin.org/get", method="GET", use_ssl=True, apn="..."))  # HTTPS

Note: time ago httpbin.org succeeded with HTTPS because supporting an old SSL version. Curently the test fails with HTTPS.

HTTP POST sample

print(sim800l.http("httpbin.org/post", data='{"name","abc"}'.encode(), method="POST", apn="..."))  # HTTPS
print(sim800l.http("httpbin.org/post", data='{"name","abc"}'.encode(), method="POST", use_ssl=False, apn="..."))  # HTTP

Read the n-th SMS

Read the SMS indexed by the index_id value [ref. also check_incoming()]
index_id=...  # e.g., 1
sim800l.read_sms(index_id)

Testing program:

from sim800l import SIM800L

MSISDN = "+..."
APN= "..."

# To improve the logging level:
#import logging
#logging.getLogger().setLevel(5)
 
sim800l=SIM800L()

ret = sim800l.setup()
if not ret:
    quit()

print("Result of get_netlight", sim800l.get_netlight())
print("Result of check_sim", sim800l.check_sim())
print("Result of get_date", sim800l.get_date())
print("Result of is_registered", sim800l.is_registered())
print("Result of get_operator", sim800l.get_operator())
print("Result of get_operator_list", sim800l.get_operator_list())
print("Result of get_service_provider", sim800l.get_service_provider())
print("Result of get_battery_voltage", sim800l.get_battery_voltage())
print("Result of get_msisdn", sim800l.get_msisdn())
print("Result of get_signal_strength", sim800l.get_signal_strength())
print("Result of get_unit_name", sim800l.get_unit_name())
print("Result of get_hw_revision", sim800l.get_hw_revision())
print("Result of get_serial_number", sim800l.get_serial_number())
print("Result of get_ccid", sim800l.get_ccid())
print("Result of get_imsi", sim800l.get_imsi())
print("Result of get_temperature", sim800l.get_temperature())
print("Result of get_flash_id", sim800l.get_flash_id())
print("Result of get_ip", sim800l.get_ip())

rec = sim800l.send_sms(MSISDN, "The quick brown fox jumps over the lazy dog.")
print("Result of sent short SMS:", repr(rec))

rec = sim800l.send_sms(MSISDN, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
print("Result of sent long SMS:", repr(rec))

rec = False
while rec is not None:
    rec = sim800l.read_next_message(all_msg=True)
    print("Received SMS message:", repr(rec))

rec = sim800l.http("httpbin.org/ip", method="GET", apn=APN, binary=True)
print("HTTP", repr(rec))

rec = sim800l.http("httpbin.org/post", data='{"name","abc"}'.encode(), method="POST", apn=APN)
print("HTTP", repr(rec))

rec = sim800l.http("https://httpbin.org/post", data='{"name","abc"}'.encode(), method="POST", apn=APN, use_ssl=True)
print("HTTP", repr(rec))

rec = sim800l.http("https://www.google.com/", method="GET", apn=APN, use_ssl=True)
print("HTTP", repr(rec))

References

Arduino:

History

This library is a fork of the original code https://github.com/jakhax/raspberry-pi-sim800l-gsm-module, totally refactored with a wide set of additions.

SIM900/SIM800 are 2G only modems, make sure your provider supports 2G as it is already being phased out in a lot of areas around the world, else a 3G/4G modem like the SIM7100 / SIM5300 has wider support.

About

SIM800L, SIM800C and SIM800H GSM module library for the Raspberry Pi to send, receive, delete SMS messages, perform HTTP GET/POST requests and many additional queries

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 84.7%
  • C 15.1%
  • Makefile 0.2%