diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6cafae2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 jack + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 66c2be4..6feb951 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,60 @@ -# domotik +# Raspberry Pi sim800l gsm module +- connecting the raspberry pi to sim8ool gsm module to send, receive sms, delete sms etc. -Automatic door project \ No newline at end of file +>> 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 is warranted. + +## Requirements +- Raspberry pi 3 with Raspbian OS installed. +- Sim800L GSM module +- external power supply for the Sim800L (5v 1A worked for our case, use the correct one for your module) +- A bunch of jumper wires. + +## References +- https://github.com/vshymanskyy/TinyGSM +- https://lastminuteengineers.com/sim800l-gsm-module-arduino-tutorial/ +- [AT Datasheet](https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf) + +## setup +### Hardware connection + + + +### Disable serial console +We will start by disabling serial console to enable communication between the pi and sim800l via 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. + + +## Usage examples + +```python +from sim800l import SIM800L +sim800l=SIM800L('/dev/serial0') +``` +#### send sms +```python +sms="Hello there" +#sim800l.send_sms(dest.no,sms) +sim800l.send_sms('2547xxxxxxxx',sms) +``` +#### read sms +```python +#sim800l.read_sms(id) +sim800l.read_sms(id) +``` + +#### callback action +```python +def print_delete(): + #assuming the sim has no sms initially + sms=sim800l.read_sms(1) + print(sms) + sim800l.delete_sms(1) + +sim800l.callback_msg(print_delete) + +while True: + sim800l.check_incoming() +``` diff --git a/README_.md b/README_.md new file mode 100644 index 0000000..66c2be4 --- /dev/null +++ b/README_.md @@ -0,0 +1,3 @@ +# domotik + +Automatic door project \ No newline at end of file diff --git a/commands_executor.py b/commands_executor.py index 621860d..a7c8570 100644 --- a/commands_executor.py +++ b/commands_executor.py @@ -38,13 +38,9 @@ def into_thread(): @app.route("/open") def open_command_function(): - """for _ in range(7): - switch_on() - switch_off() - switch_off()""" command_applier = threading.Thread(target=into_thread) command_applier.start() - return "Pull the door ;)" + return "Pull the door ;)\n" diff --git a/images/sim-800l-rpi3.jpg b/images/sim-800l-rpi3.jpg new file mode 100644 index 0000000..b97f837 Binary files /dev/null and b/images/sim-800l-rpi3.jpg differ diff --git a/images/sim-800l-rpi31.jpg b/images/sim-800l-rpi31.jpg new file mode 100644 index 0000000..d49ef31 Binary files /dev/null and b/images/sim-800l-rpi31.jpg differ diff --git a/sim800l.py b/sim800l.py new file mode 100644 index 0000000..93f4559 --- /dev/null +++ b/sim800l.py @@ -0,0 +1,124 @@ + +import os,time,sys +import serial + +def convert_to_string(buf): + try: + tt = buf.decode('utf-8').strip() + return tt + except UnicodeError: + tmp = bytearray(buf) + for i in range(len(tmp)): + if tmp[i]>127: + tmp[i] = ord('#') + return bytes(tmp).decode('utf-8').strip() + +class SIM800L: + def __init__(self,ser): + try: + self.ser=serial.Serial("/dev/serial0", baudrate=9600, timeout=1) + except Exception as e: + sys.exit("Error: {}".format(e)) + self.incoming_action = None + self.no_carrier_action = None + self.clip_action = None + self._clip = None + self.msg_action = None + self._msgid = 0 + self.savbuf = None + + def setup(self): + self.command('ATE0\n') # command echo off + self.command('AT+CLIP=1\n') # caller line identification + self.command('AT+CMGF=1\n') # plain text SMS + self.command('AT+CLTS=1\n') # enable get local timestamp mode + self.command('AT+CSCLK=0\n') # disable automatic sleep + + def callback_incoming(self,action): + self.incoming_action = action + + def callback_no_carrier(self,action): + self.no_carrier_action = action + + def get_clip(self): + return self._clip + + def callback_msg(self,action): + self.msg_action = action + + def get_msgid(self): + return self._msgid + + def command(self, cmdstr, lines=1, waitfor=500, msgtext=None): + while self.ser.in_waiting: + self.ser.readline() + self.ser.write(cmdstr.encode()) + if msgtext: + self.ser.write(msgtext.encode()) + if waitfor>1000: + time.sleep((waitfor-1000)/1000) + buf=self.ser.readline() #discard linefeed etc + #print(buf) + buf=self.ser.readline() + if not buf: + return None + result = convert_to_string(buf) + if lines>1: + self.savbuf = '' + for i in range(lines-1): + buf=self.ser.readline() + if not buf: + return result + buf = convert_to_string(buf) + if not buf == '' and not buf == 'OK': + self.savbuf += buf+'\n' + return result + + def send_sms(self,destno,msgtext): + result = self.command('AT+CMGS="{}"\n'.format(destno),99,5000,msgtext+'\x1A') + if result and result=='>' and self.savbuf: + params = self.savbuf.split(':') + if params[0]=='+CUSD' or params[0] == '+CMGS': + return 'OK' + return 'ERROR' + + def read_sms(self,id): + result = self.command('AT+CMGR={}\n'.format(id),99) + if result: + params=result.split(',') + if not params[0] == '': + params2 = params[0].split(':') + if params2[0]=='+CMGR': + number = params[1].replace('"',' ').strip() + date = params[3].replace('"',' ').strip() + time = params[4].replace('"',' ').strip() + return [number,date,time,self.savbuf] + return None + + def delete_sms(self,id): + self.command('AT+CMGD={}\n'.format(id),1) + + def check_incoming(self): + if self.ser.in_waiting: + buf=self.ser.readline() + # print(buf) + buf = convert_to_string(buf) + params=buf.split(',') + + if params[0][0:5] == "+CMTI": + self._msgid = int(params[1]) + if self.msg_action: + self.msg_action() + + elif params[0] == "NO CARRIER": + self.no_carrier_action() + + elif params[0] == "RING" or params[0][0:5] == "+CLIP": + #@todo handle + pass + + def read_and_delete_all(self): + try: + return self.read_sms(1) + finally: + self.command('AT+CMGDA="DEL ALL"\n',1)