|
@@ -0,0 +1,124 @@
|
|
1
|
+
|
|
2
|
+import os,time,sys
|
|
3
|
+import serial
|
|
4
|
+
|
|
5
|
+def convert_to_string(buf):
|
|
6
|
+ try:
|
|
7
|
+ tt = buf.decode('utf-8').strip()
|
|
8
|
+ return tt
|
|
9
|
+ except UnicodeError:
|
|
10
|
+ tmp = bytearray(buf)
|
|
11
|
+ for i in range(len(tmp)):
|
|
12
|
+ if tmp[i]>127:
|
|
13
|
+ tmp[i] = ord('#')
|
|
14
|
+ return bytes(tmp).decode('utf-8').strip()
|
|
15
|
+
|
|
16
|
+class SIM800L:
|
|
17
|
+ def __init__(self,ser):
|
|
18
|
+ try:
|
|
19
|
+ self.ser=serial.Serial("/dev/serial0", baudrate=9600, timeout=1)
|
|
20
|
+ except Exception as e:
|
|
21
|
+ sys.exit("Error: {}".format(e))
|
|
22
|
+ self.incoming_action = None
|
|
23
|
+ self.no_carrier_action = None
|
|
24
|
+ self.clip_action = None
|
|
25
|
+ self._clip = None
|
|
26
|
+ self.msg_action = None
|
|
27
|
+ self._msgid = 0
|
|
28
|
+ self.savbuf = None
|
|
29
|
+
|
|
30
|
+ def setup(self):
|
|
31
|
+ self.command('ATE0\n') # command echo off
|
|
32
|
+ self.command('AT+CLIP=1\n') # caller line identification
|
|
33
|
+ self.command('AT+CMGF=1\n') # plain text SMS
|
|
34
|
+ self.command('AT+CLTS=1\n') # enable get local timestamp mode
|
|
35
|
+ self.command('AT+CSCLK=0\n') # disable automatic sleep
|
|
36
|
+
|
|
37
|
+ def callback_incoming(self,action):
|
|
38
|
+ self.incoming_action = action
|
|
39
|
+
|
|
40
|
+ def callback_no_carrier(self,action):
|
|
41
|
+ self.no_carrier_action = action
|
|
42
|
+
|
|
43
|
+ def get_clip(self):
|
|
44
|
+ return self._clip
|
|
45
|
+
|
|
46
|
+ def callback_msg(self,action):
|
|
47
|
+ self.msg_action = action
|
|
48
|
+
|
|
49
|
+ def get_msgid(self):
|
|
50
|
+ return self._msgid
|
|
51
|
+
|
|
52
|
+ def command(self, cmdstr, lines=1, waitfor=500, msgtext=None):
|
|
53
|
+ while self.ser.in_waiting:
|
|
54
|
+ self.ser.readline()
|
|
55
|
+ self.ser.write(cmdstr.encode())
|
|
56
|
+ if msgtext:
|
|
57
|
+ self.ser.write(msgtext.encode())
|
|
58
|
+ if waitfor>1000:
|
|
59
|
+ time.sleep((waitfor-1000)/1000)
|
|
60
|
+ buf=self.ser.readline() #discard linefeed etc
|
|
61
|
+ #print(buf)
|
|
62
|
+ buf=self.ser.readline()
|
|
63
|
+ if not buf:
|
|
64
|
+ return None
|
|
65
|
+ result = convert_to_string(buf)
|
|
66
|
+ if lines>1:
|
|
67
|
+ self.savbuf = ''
|
|
68
|
+ for i in range(lines-1):
|
|
69
|
+ buf=self.ser.readline()
|
|
70
|
+ if not buf:
|
|
71
|
+ return result
|
|
72
|
+ buf = convert_to_string(buf)
|
|
73
|
+ if not buf == '' and not buf == 'OK':
|
|
74
|
+ self.savbuf += buf+'\n'
|
|
75
|
+ return result
|
|
76
|
+
|
|
77
|
+ def send_sms(self,destno,msgtext):
|
|
78
|
+ result = self.command('AT+CMGS="{}"\n'.format(destno),99,5000,msgtext+'\x1A')
|
|
79
|
+ if result and result=='>' and self.savbuf:
|
|
80
|
+ params = self.savbuf.split(':')
|
|
81
|
+ if params[0]=='+CUSD' or params[0] == '+CMGS':
|
|
82
|
+ return 'OK'
|
|
83
|
+ return 'ERROR'
|
|
84
|
+
|
|
85
|
+ def read_sms(self,id):
|
|
86
|
+ result = self.command('AT+CMGR={}\n'.format(id),99)
|
|
87
|
+ if result:
|
|
88
|
+ params=result.split(',')
|
|
89
|
+ if not params[0] == '':
|
|
90
|
+ params2 = params[0].split(':')
|
|
91
|
+ if params2[0]=='+CMGR':
|
|
92
|
+ number = params[1].replace('"',' ').strip()
|
|
93
|
+ date = params[3].replace('"',' ').strip()
|
|
94
|
+ time = params[4].replace('"',' ').strip()
|
|
95
|
+ return [number,date,time,self.savbuf]
|
|
96
|
+ return None
|
|
97
|
+
|
|
98
|
+ def delete_sms(self,id):
|
|
99
|
+ self.command('AT+CMGD={}\n'.format(id),1)
|
|
100
|
+
|
|
101
|
+ def check_incoming(self):
|
|
102
|
+ if self.ser.in_waiting:
|
|
103
|
+ buf=self.ser.readline()
|
|
104
|
+ # print(buf)
|
|
105
|
+ buf = convert_to_string(buf)
|
|
106
|
+ params=buf.split(',')
|
|
107
|
+
|
|
108
|
+ if params[0][0:5] == "+CMTI":
|
|
109
|
+ self._msgid = int(params[1])
|
|
110
|
+ if self.msg_action:
|
|
111
|
+ self.msg_action()
|
|
112
|
+
|
|
113
|
+ elif params[0] == "NO CARRIER":
|
|
114
|
+ self.no_carrier_action()
|
|
115
|
+
|
|
116
|
+ elif params[0] == "RING" or params[0][0:5] == "+CLIP":
|
|
117
|
+ #@todo handle
|
|
118
|
+ pass
|
|
119
|
+
|
|
120
|
+ def read_and_delete_all(self):
|
|
121
|
+ try:
|
|
122
|
+ return self.read_sms(1)
|
|
123
|
+ finally:
|
|
124
|
+ self.command('AT+CMGDA="DEL ALL"\n',1)
|