Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Most of vegatables and fruits have been grown on greenhouses except summer and autumn. Farmers take care of vegatable and fruits growing conditions. They want to know greenhouses temperature and humidty level.
Most of the greenhouse is not close to farmer's home. None of them is wifi available. So how can I follow greenhouse's temeperature and humidity level from away. Answer is RRV1.
This project was born from this thought.
Main parts are below:
ESP32-C3: It is cheap and tiny. Wifi and BT capabilities are not used. Only MCU feature is used.
Quectel M95 Gsm Module: Connectivity is provided over this module.
AHT10: Temperature and Humidty sensor
LM2576: Switching Regulator.
The schematic is below.
I design the schematic but made some revisions during pcb design. Design is same but second NTC sensor, SHT30 sensor is not used. Some ESP32 pins might be replaced between each other. If you care the revisions, you can make verification by investigating pinDef.py file. Transistors on the upper left side schematic is not placed on PCB. They are indicator of network connection.
ESP32-c3 is a new serie of ESP32 family. ESP32-C3 is capable of USB, I2C, SPI, Uart, CAN-BUS and many other protocols. I used I2C for accessing AHT10 temperature & humidity sensor and serial port for GSM module.
Project is based on inform using SMS service. I add some functions to access a flask service using GPRS connection.
There are some custom parameters for user. These parameters can be configured by SMS.
These modifications are:
1) Destination IP: RRV1 can request any ip accesible website.
Ip adress can be configure by sending SMS:
destip:123.456.789.123
When the text above is sent, new destination IP is written on ESP32 memory. RRV1 gives feedback when SMS is received succesfully.
2) Destination Port: RRV1 can request any port. Destination port can be modified by SMS.
destPort:5000
When the text above is sent, port 5000 is written on ESP32 memory for web request. RRV1 gives feedback when SMS is received succesfully.
3) reply: Check gsm is alive.
4) duration: RRV1 is design to inform farmer when temperature is critically low. If temperature goes below critical level, RRV1 makes voice call to phone number that previously stored on sim card. RRV1 makes periodic voice calls for snooze or unawareness. The duration is between voice calls is set with "duration" function. Value sholud be given as second. If you want 5 minutes between voice calls, duration value should be 300.
duration:300
5) ekle: Everybody can make voice call to a phone number or send an SMS. RRV1 should answer only authorized phone number. This authorized phone number is specified by an SMS. This format is below.
Ekle, 1, xxxxxx, Name
Ekle: command for adding phone number for authorized process.
1: order for location on sim card.
xxxxxx: Last six digits of sim card CCID number. It is for security. Nobody can guess this number. CCID number can be read over SIM card.
Name: a name for record on SIM card
6) critic: Command for specify critical temperature.
critic:3
This sms sets critical temperature to 3°C.
7) temp: RRV1 replies this message via text SMS. The text includes temperature, humidity level, NTC sensor value and battery value. Battery value and NTC value is not converted Celcius and Volt. But code can be developed to inform as celcius and voltage level.
8) act query: This message enables web request to destination ip and destination port periodically. Duration value between requests is 100 seconds. During I am writing this post, website was not ready. So I didn't give any query string. Only, I request a flask app by using "chk" function. This function is show whether connection is estabilished correctly.
9) deact query: This message disables web request.
RRV1 pcb and stencil are manifactured by PCBWAY. They supplied my project by manifacturing pcb and stencil. Thanks to PCBWAY for supporting my projects. RRV1 will be an "open source" project. Pcb can be ordered on PCBWAY.
class pinDef:
neoPixel = 8
neoPixelCount = 1
gsmRI = 2
gsmExtPower = 3
gsmTx = 7
gsmRx = 6
gsmCh = 1
baudrate = 115200
userLed0 = 2
aht10Sda = 4
aht10Scl = 5
gsmWakeUp = 10
extPowerADCIn = 1
ntcADCIn = 0
sw = 9
tracking=off;destIP=xxx.yyy.zz.mm;destPort=5000;makeQuery=on;duration=600;criticTemp=4;setName=Domates Tarla;smsC=off;
import os
file = "settings.txt"
def readSettings(setting):
with open(file, mode='r', encoding='utf-8') as f:
content = f.read()
data = content.split(";")
status = ""
for i in data:
if setting in i:
status = i.split("=")[1]
return status
def modifySettings(setting, value):
with open(file, mode='r', encoding='utf-8') as f:
content = f.read()
data = content.split(";")
newSettings = []
for i in data:
if setting in i:
text = setting + "=" + value
newSettings.append(text)
else:
newSettings.append(i)
with open(file, mode='w', encoding='utf-8') as f:
text = ""
for i in newSettings:
if i != "":
text += i + ";"
f.write(text)
file = "rst.txt"
def restartCount():
try:
with open(file, mode='r', encoding='utf-8') as f:
content = f.read()
except:
print("error on read")
return content
def restartInc():
count = 0
try:
with open(file, "r") as f:
raw = f.read()
content = raw.strip()
count = int(content)
with open(file, "w") as f:
count += 1
text = str(count)
f.write(text)
f.flush()
except:
print("error on access")
return "error"
return "ok"
if __name__ == "__main__":
print(restartCount())
print(restartInc())
import utime
from micropython import const
class AHT10:
"""Interface library for AHT10/AHT20 temperature+humidity sensors"""
AHTX0_I2CADDR_DEFAULT = const(0x38) # Default I2C address
AHTX0_CMD_INITIALIZE = 0xE1 # Initialization command
AHTX0_CMD_TRIGGER = const(0xAC) # Trigger reading command
AHTX0_CMD_SOFTRESET = const(0xBA) # Soft reset command
AHTX0_STATUS_BUSY = const(0x80) # Status bit for busy
AHTX0_STATUS_CALIBRATED = const(0x08) # Status bit for calibrated
def __init__(self, i2c, address=AHTX0_I2CADDR_DEFAULT):
utime.sleep_ms(20) # 20ms delay to wake up
self._i2c = i2c
self._address = address
self._buf = bytearray(6)
self.reset()
if not self.initialize():
raise RuntimeError("Could not initialize")
self._temp = None
self._humidity = None
def reset(self):
"""Perform a soft-reset of the AHT"""
self._buf[0] = self.AHTX0_CMD_SOFTRESET
self._i2c.writeto(self._address, self._buf[0:1])
utime.sleep_ms(20) # 20ms delay to wake up
def initialize(self):
"""Ask the sensor to self-initialize. Returns True on success, False otherwise"""
self._buf[0] = self.AHTX0_CMD_INITIALIZE
self._buf[1] = 0x08
self._buf[2] = 0x00
self._i2c.writeto(self._address, self._buf[0:3])
self._wait_for_idle()
if not self.status & self.AHTX0_STATUS_CALIBRATED:
return False
return True
@property
def status(self):
"""The status byte initially returned from the sensor, see datasheet for details"""
self._read_to_buffer()
# print("status: "+hex(self._buf[0]))
return self._buf[0]
@property
def relative_humidity(self):
"""The measured relative humidity in percent."""
self._perform_measurement()
self._humidity = (self._buf[1] << 12) | (self._buf[2] << 4) | (self._buf[3] >> 4)
self._humidity = (self._humidity * 100) / 0x100000
return self._humidity
@property
def temperature(self):
"""The measured temperature in degrees Celcius."""
self._perform_measurement()
self._temp = ((self._buf[3] & 0xF) << 16) | (self._buf[4] << 8) | self._buf[5]
self._temp = ((self._temp * 200.0) / 0x100000) - 50
return self._temp
def _read_to_buffer(self):
self._i2c.readfrom_into(self._address, self._buf)
def _trigger_measurement(self):
"""Internal function for triggering the AHT to read temp/humidity"""
self._buf[0] = self.AHTX0_CMD_TRIGGER
self._buf[1] = 0x33
self._buf[2] = 0x00
self._i2c.writeto(self._address, self._buf[0:3])
def _wait_for_idle(self):
while self.status & self.AHTX0_STATUS_BUSY:
utime.sleep_ms(5)
def _perform_measurement(self):
self._trigger_measurement()
self._wait_for_idle()
self._read_to_buffer()
#bismillahirrahmanirrahim
from machine import Pin, UART, SoftI2C, ADC
from neopixel import NeoPixel
from time import sleep
import aht10
import machine, neopixel
from machine import Timer
from pinDef import pinDef
from settings import readSettings, modifySettings
from collections import namedtuple
from rst import restartCount, restartInc
#namedTuple defines
atCmd = namedtuple("atcmd", ("text", "timeout", "response"))
# gsm Commands
at = atCmd("AT\r", 300, ["OK", "ERROR"])
atA = atCmd("ATA\r", 300, ["OK", "ERROR"])
atD = atCmd("ATD", 1000, ["OK", "ERROR"])
atH = atCmd("ATH\r", 1000, ["OK", "ERROR"])
atS0 = atCmd("ATS0=4\r", 300, ["OK", "ERROR"])
atQMOSTAT = atCmd("AT+QMOSTAT=1\r", 300, ["OK", "ERROR"])
atQAUDCH = atCmd("AT+QAUDCH=0\r", 300, ["OK", "ERROR"])
atQMIC = atCmd("AT+QMIC=0,5\r", 300, ["OK", "ERROR"])
atCRSL = atCmd("AT+CRSL=90\r", 300, ["OK", "ERROR"])
atE0 = atCmd("ATE0\r", 300, ["OK", "ERROR"])# Command Echo
atL3 = atCmd("ATL3\r", 300, ["OK", "ERROR"])# Ses Seviyesi (en yksekte)
atCLVL = atCmd("AT+CLVL=40\r", 300, ["OK", "ERROR"])# Ses Seviyesi (en yksekte)
atCLIP1 = atCmd("AT+CLIP=1\r", 300, ["OK", "ERROR"])# Calling Id presentation
atCPIN = atCmd("ATCPIN?\r", 300, ["OK", "ERROR"])# Command Echo
atQGSN = atCmd("AT+QGSN\r", 3000, ["OK", "ERROR"]) # Gsm Serial Number
atCCID = atCmd("AT+CCID\r", 300, ["OK", "ERROR"]) # Sim Abone No
atQNITZ = atCmd("AT+QNITZ=1\r", 3000, ["OK", "ERROR"]) # Network Time Sync Enable
atCTZU = atCmd("AT+CTZU=3\r", 3000, ["OK", "ERROR"]) # Localized Time Sync
atCTZR = atCmd("AT+CTZR=1\r", 3000, ["OK", "ERROR"]) # Time Sync Bildirimi
atCCLK = atCmd("AT+CCLK?\r", 1000, ["OK", "ERROR"]) # Saat?
#atQGNSSC = atCmd("AT+QGNSSC=1\r", 300, ["OK", "ERROR"]) # GNSS Power On
#atQGNSS = atCmd("AT+QGNSS=0\r", 300, ["OK", "ERROR", "+CME ERROR:"]) # GNSS NMEA Tipi
atCMGF = atCmd("AT+CMGF=1\r", 300, ["OK", "ERROR", "+CME ERROR:"]) # SMS Format
atCNMI = atCmd("AT+CNMI=2, 1\r", 300, ["OK", "ERROR", "+CME ERROR:"]) # SMS Notification Type
atQNSTATUS = atCmd("AT+QNSTATUS\r", 1000, ["OK", "ERROR"]) # Network Status
atCSQ = atCmd("AT+CSQ\r", 300, ["OK", "ERROR", "+CME ERROR:"]) # Signal Quality
atCREG = atCmd("AT+CREG?\r", 300, ["OK", "ERROR", "+CME ERROR:", "+CREG:"]) # Signal Quality
atCOPS = atCmd("AT+COPS?\r", 300, ["OK", "ERROR"]) # Operator Names
atCMGL = atCmd('AT+CMGL="REC UNREAD"\r', 3000, ["OK", "ERROR"])
atCMGD = atCmd("AT+CMGD=1, 4\r", 3000, ["OK", "ERROR"])
atQMGDA = atCmd("""AT+QMGDA="DEL ALL"\r""", 3000, ["OK", "ERROR"]) #Btn SMSleri sil
atCMGS = atCmd("AT+CMGS=", 5000, ["OK", "ERROR"])
atCSCS = atCmd("""AT+CSCS="GSM"\r""", 5000, ["OK", "ERROR"])
#atQGNSSRD = atCmd("AT+QGNSSRD?\r", 3000, ["OK", "ERROR"])
atCSMP = atCmd("AT+CSMP=17, 167, 0, 0\r", 1000, ["OK", "ERROR"])
atCSCS = atCmd('AT+CSCS="GSM"\r', 1000, ["OK", "ERROR"])
atQIFGCNT = atCmd("AT+QIFGCNT=0\r", 1000, ["OK", "ERROR"])
atQICSGP = atCmd('AT+QICSGP=1, "INTERNET"\r', 1000, ["OK", "ERROR"])
atQIREGAPP=atCmd("AT+QIREGAPP\r", 5000, ["OK", "ERROR"])
atCGATT = atCmd("AT+CGATT?\r", 5000, ["OK", "ERROR"])
atQIACT = atCmd("AT+QIACT\r", 5000, ["OK", "ERROR"])
atQLOCCFG = atCmd("AT+QLOCCFG?\r", 5000, ["OK", "ERROR"])
atQCELLLOC = atCmd("AT+QCELLLOC\r", 5000, ["OK", "ERROR"])
atCPBS = atCmd("""AT+CPBS="SM"\r""", 5000, ["OK", "ERROR"])
atCPBW = atCmd("""AT+CPBW={},"{}",145,"{}"\r""", 5000, ["OK", "ERROR"])
atCPBR = atCmd("AT+CPBR={}\r", 30000, ["OK", "ERROR"])
atCNUM = atCmd("AT+CNUM\r", 3000, ["OK", "ERROR"])
atQIMUX = atCmd("AT+QIMUX=0\r", 50000, ["OK", "ERROR"])
atQIMODE = atCmd("AT+QIMODE=0\r", 50000, ["OK", "ERROR"])
atQIDNSIP = atCmd("AT+QIDNSIP=0\r", 50000, ["OK", "ERROR"])
atQILOCIP = atCmd("AT+QILOCIP\r", 50000, ["OK", "ERROR"])
atQIOPEN = atCmd("""AT+QIOPEN="TCP","{}",{}\r""", 50000, ["OK", "ERROR"])
atQISEND = atCmd("""AT+QISEND\r""", 50000, ["OK", "ERROR"])
atQISACK = atCmd("AT+QISACK\r", 50000, ["OK", "ERROR"])
atQICLOSE = atCmd("AT+QICLOSE\r", 5000, ["OK", "ERROR"])
atQIDEACT = atCmd("AT+QIDEACT\r", 5000, ["OK", "ERROR"])
atQHTTPURL = atCmd("AT+QHTTPURL={},{}\r", 50000, ["OK", "ERROR"])
atQHTTPGET = atCmd("AT+QHTTPGET={}\r", 3000, ["OK", "ERROR"])
atQHTTPREAD = atCmd("AT+QHTTPREAD=30\r", 3000, ["OK", "ERROR"])
atQHTTPPOST = atCmd("AT+QHTTPPOST={},{},{}\r", 3000, ["OK", "ERROR"])
#variables
sayac = 0
makeQuery = False
tickTock = False
suspendedAt = 0
duration = 3000
annoation = False
gsn = "" # GSM serial Number
ccid = "" # Caller Id
enableWDT = False
wdt = None
authUsers = []
bckspc = bytes([26])
bigger = ">"
np = None
pinNtc = ADC(Pin(pinDef.ntcADCIn))
pinNtc.atten(ADC.ATTN_11DB)
pinBatt = ADC(Pin(pinDef.extPowerADCIn))
pinBatt.atten(ADC.ATTN_11DB)
i2c = SoftI2C(scl = Pin(pinDef.aht10Scl), sda = Pin(pinDef.aht10Sda))
sensor = aht10.AHT10(i2c)
gsmWakeUpPin = Pin(pinDef.gsmWakeUp, Pin.OUT)
gsmRiPin = Pin(pinDef.gsmRI, Pin.IN)
gsmPOutPin = Pin(pinDef.gsmExtPower, Pin.IN)
sw = Pin(pinDef.sw, Pin.IN)
ledA = Pin(pinDef.userLed0, Pin.OUT) # define user LedA
gsm = UART(pinDef.gsmCh, baudrate = pinDef.baudrate, tx = pinDef.gsmTx, rx = pinDef.gsmRx)
np = neopixel.NeoPixel(machine.Pin(pinDef.neoPixel), pinDef.neoPixelCount)
#definitions
def readNtc():
ntcVal = pinNtc.read_u16()
return ntcVal
def readBattLevel():
battLevel = pinBatt.read_u16()
return battLevel
def neopixelLed(r = 0, g = 0 , b = 0):
global np
np[0] = (r, g, b)
np.write()
def info(text, sender = "", title = ""):
raw = "<info: {}".format(text)
if sender !="":
raw = raw + " sender: {}".format(sender)
if title !="":
raw = raw + " title: {}".format(title)
raw = raw + ">\r\n"
print(raw)
def holdOn(duration):
global enableWDT
raw = duration / 0.001
counter = int(raw)
#info(counter, "counter")
for i in range(counter):
sleep(1/1000)
if enableWDT == True:
wdt.feed()
def chkGSMIsOn():
extPower = gsmPOutPin.value()
info(extPower, "extPower")
holdOn(1)
if extPower == 0:
gsmWakeUpPin.on()
holdOn(1)
gsmWakeUpPin.off()
holdOn(10)
info("gsm Module is turned on \r\n", "chkGSMIsOn")
else:
info("gsm Module is already on \r\n")
def shutDownGsm():
extPower = gsmPOutPin.value()
if extPower == 1:
info("GSM Module is now on and will be shut down", title = "shutDownGsm")
gsmWakeUpPin.on()
holdOn(1)
gsmWakeUpPin.off()
holdOn(5)
extPower = gsmPOutPin.value()
if extPower == 0:
info("GSM Module is power down", title = "shutDownGsm")
else:
info("GSM Module is still on", title = "shutDownGsm")
else:
info("GSM Module is already off", title = "shutDownGsm")
def getAuthUsers():
global authUsers
phonebook = []
authUsers = []
raw = sendCmd(atCPBR, 1)
if raw[1] != "":
authUsers.append(raw[1])
phonebook.append(raw)
raw = sendCmd(atCPBR, 2)
if raw[1] != "":
authUsers.append(raw[1])
phonebook.append(raw)
info(authUsers, title = "AuthUsers")
return phonebook
def receiveData(timeout):
sayac = 0
prev = 1
resp = ""
act = 0
while(sayac < timeout):
sayac += 1
if sayac % 100 == 0 and gsm.any() > 0:
prev = act
holdOn(1/100)
act = gsm.any()
if prev == act:
text = "prev: {}, sayac: {}".format(prev, sayac)
info(text, "sendCmd", "getText")
sayac = timeout
holdOn(0.2)
raw = gsm.read(gsm.any())
info(raw, title = "receiveData")
data = raw.decode("utf-8")
return data
def sendCmd(cmd = "", param = ""):
global ccid
global gsn
global timeData
global authUsers
global makeQuery
raw = ""
global destIP
global destPort
global duration
global criticTemp
global setName
if cmd != "":
raw = cmd.text
if raw == "ATD":
raw = "ATD{};\r".format(param)
if "AT+CMGS=" in raw:
raw = """AT+CMGS="{}"\r""".format(param)
if "AT+CPBW" in raw:
raw = cmd.text.format(param[0], param[1], param[2])
if "AT+CPBR" in raw:
raw = cmd.text.format(param)
if "AT+QHTTPURL" in raw:
raw = raw.format(param[0], param[1])
info(raw, title = "AT+QHTTPURL")
if "AT+QIOPEN" in raw:
raw = raw.format(param[0], param[1])
info(raw, title = "AT+QIOPEN")
text = raw.encode("utf-8")
info(text, "sendCmd", "cmd")
gsm.write(text)
timeout = cmd.timeout
else:
timeout = 100
if "AT+QIOPEN" in raw:
data = receiveData(20000)
if "CONNECT" not in data:
data = receiveData(20000)
return data
sayac = 0
prev = 1
resp = ""
act = 0
while(sayac < timeout):
sayac += 1
if sayac % 100 == 0 and gsm.any() > 0:
prev = act
holdOn(1/1000)
act = gsm.any()
if prev == act:
text = "prev: {}, sayac: {}".format(prev, sayac)
info(text, "sendCmd", "getText")
sayac = timeout
if (sayac == timeout) and (gsm.any() == 0):
info("cevap Yok")
else:
holdOn(0.2)
raw = gsm.read(gsm.any())
info(raw, "sendCmd", "resp")
resp = raw.decode("utf-8")
if bigger in resp:
info("sms bigger chk", title = "SMS")
if "MO RING" in resp:
#ap4890EnPin.on()
info("begin Calling")
elif "MO CONNECTED" in resp:
info("Connected")
elif "+CLIP:" in resp:
dialer = resp.split('"')[1]
info(dialer, "CID")
elif "NO CARRIER" in resp:
info("end Calling")
elif "BUSY" in resp:
info("cancel Calling")
elif "+QISACK:" in resp:
rawA = resp.split(":")[1]
rawB = rawA.split(",")
sent = rawB[0]
ack = rawB[1]
dAck = rawB[2]
qiasckResp = receiveData(30000)
info(qiasckResp, title = "QISACK")
data = qiasckResp.split("\r\n")
httpOK = False
respLen = 0
indexBegin = 0
indexEnd = 0
webResponse = ""
for i in data:
if "HTTP/1.1" in i:
httpOk = True
if "Content-Length:" in i:
respLen = int(i.split(" ")[1])
if i == "":
indexBegin = data.index(i)
if "CLOSED" in i:
indexEnd = data.index(i)
if indexBegin > 0 and indexEnd > 0:
webResponse = data[indexBegin + 1 : indexEnd]
print("len: {}, httpOK: {}, indexBegin: {}, indexEnd {}\r\n".format(respLen, httpOK, indexBegin, indexEnd))
print("resp: {}\r\n".format(webResponse))
return webResponse
elif "+CMTI:" in resp: #SMS mesaj var
sendCmd(atCMGL)
elif "QGSN" in resp:
raw = resp.split("\r\n")[1]
gsn = raw.split('"')[1]
info(gsn, title = "QGSN")
elif "CCID" in resp:
ccid = resp.split(':')[1].split("\r\n")[0].strip(' ').strip('"')
info(ccid, title = "CCID")
return ccid
elif "+CCLK" in resp:
"""AT+CCLK?\r\r\n+CCLK: "22/12/22,10:57:13+12"\r\n\r\nOK\r\n"""
currTime = resp.split('"')[1].split(",")[1].split("+")[0]
clck = currTime[:2]
mnts = currTime[3:5]
scnds = currTime[6:]
currDate = resp.split('"')[1].split(",")[0]
year = currDate[:2]
month = currDate[3:5]
day = currDate[6:]
#print(f"year:{year}, month:{month}, day:{day}, clck: {clck}, mnts: {mnts}, sec:{scnds} \r\n")
timeData = [year, month, day, clck, mnts, scnds]
info(timeData, "sendCmd", "currTime")
elif "CMGL" in resp:
"""AT+CMGL="REC UNREAD"\r\r\n+CMGL: 11,"REC UNREAD","+90xxxxxxxx","","2022/12/25 01:37:40+12"\r\nMerhaba \r\n\r\nOK\r\n"""
smsContainer = resp.split("\r\n")
if len(smsContainer) > 3:
owner = smsContainer[1].split(",")[2].strip('"')
smsTime = smsContainer[1].split(",")[4].strip('"')
smsBody = smsContainer[2]
smsYear = smsTime[:4]
smsMonth = smsTime[5:7]
smsDay = smsTime[8:10]
smsHour = smsTime[11:13]
smsMinute = smsTime[14:16]
smsSecond = smsTime[17:19]
sms = [owner, smsBody, smsYear, smsMonth, smsDay, smsHour, smsMinute, smsSecond]
info(sms, "SMS")
smsSmallLetter = smsBody.lower()
#Sms ile ilgili ilemler buradan devam edecek
if smsSmallLetter.startswith("ekle"):
info("Ekle Rutinine giri yapld", "Ekle")
raw = smsBody.split(",")
key = raw[1]
index = raw[2]
text = raw[3]
if key == ccid[14:]:
saveToSIM(index, owner, text)
info("Added to SIM", title = "saveToSIM")
pb = getAuthUsers()
info(pb, title = "pb")
holdOn(1)
user1 = ""
user2 = ""
try:
user1 = f" {pb[0][2]}, {pb[0][1]} "
user2 = f" {pb[1][2]}, {pb[1][1]} "
except:
pass
text = "{} number saved at order {}\r\n AuthUsers: \r\n1->:{} \r\n 2->: {}\r\n".format(owner, index, user1, user2)
sendSMS(owner, text)
else:
text = "CCID last 6 key is invalid"
sendSMS(owner, text)
elif owner in authUsers:
if smsSmallLetter.startswith("reply"):
smsText = "this SMS is generated by RRV1"
info(smsText, "sendCmd")
sendSMS(owner, smsText)
elif "destip:" in smsBody.lower():
raw = smsBody.split(":")[1]
modifySettings("destIP", raw)
text = f"Destination IP is {raw}"
sendSMS(owner, text)
destIP = readSettings("destIP")
info(destIP, title = "destIP")
elif "destport:" in smsBody.lower():
raw = smsBody.split(":")[1]
modifySettings("destPort", raw)
text = f"Destination Port is {raw}"
sendSMS(owner, text)
destPort = readSettings("destPort")
info(destPort, title = "destPort")
elif smsSmallLetter.startswith("set:"):
raw = smsBody.split(":")[1].strip()
modifySettings("setName", raw)
text = f"Name is set to: {raw}"
sendSMS(owner, text)
setName = readSettings("setName")
info(setName, title = "setName")
elif "duration:" in smsBody.lower():
raw = smsBody.split(":")[1]
modifySettings("duration", raw)
text = f"Duration is {raw}"
sendSMS(owner, text)
duration = readSettings("duration")
info(duration, title = "duration")
elif "critic:" in smsBody.lower():
raw = smsBody.split(":")[1]
modifySettings("criticTemp", raw)
text = f"criticTemp is {raw}"
sendSMS(owner, text)
criticTemp = readSettings("criticTemp")
info(criticTemp, title = "criticTemp")
elif smsSmallLetter.startswith("deact query"):
makeQuery = False
modifySettings("makeQuery", "off")
info("off", "makeQuery")
elif smsSmallLetter.startswith("act query"):
makeQuery = True
modifySettings("makeQuery", "on")
info("on", "makeQuery")
elif smsSmallLetter.startswith("temp"):
values = readSensor()
temp = values[0]
humid = values[1]
ntc = values[2]
batt = values[3]
text = f"Konum: {setName}\r\n Sicaklik: {temp:2.2f}\r\n nem: {humid:2.2f}\r\n ntc: {ntc}\r\n batt: {batt}"
info(text, "temp")
sendSMS(owner, text)
else:
text = "Unauthorized user!!!"
info(text, title = "SMS User")
#sendSMS(owner, "Unauthorized user!!!")
# i bittikten sonra gelen smsleri silecek bir rutin ekle
sendCmd(atQMGDA)
elif "+CPBR" in resp:
"""AT+CPBR=1\r\r\n+CPBR: 1,"+90xxxxxxx",145,"Fxxx"\r\n\r\nOK\r\n"""
raw = resp.split(":")[1].split("\r\n")
loc = raw[0].split(",")[0].strip()
number = raw[0].split(",")[1].strip('"')
text = raw[0].split(",")[3].strip('"')
pB = [loc, number, text]
info(pB, title = "phoneBook")
return pB
else:
return resp
def request(address, port, query):
sendCmd(atQIFGCNT)
sendCmd(atQICSGP)
sendCmd(atQIMUX)
sendCmd(atQIMODE)
sendCmd(atQIDNSIP)
sendCmd(atQIREGAPP)
sendCmd(atQIACT)
sendCmd(atQILOCIP)
port = 5000
stat = sendCmd(atQIOPEN, [address, port])
info(stat, title = "ATQIOPEN")
if "CONNECT" in stat:
resp = sendCmd(atQISEND)
info(resp, "> wait for this")
if ">" in resp:
text = "GET /{} HTTP/1.1\r\n\r\n".format(query)
info("send Query", "ATQISEND")
gsm.write(text.encode('utf-8'))
gsm.write(bckspc)
resp = sendCmd(atQISACK)
info(resp, title = "ATQISACK")
sendCmd(atQICLOSE)
sendCmd(atQIDEACT)
def saveToSIM(index, nr, text):
params = [index, nr, text]
sendCmd(atCPBW, params)
def sendSMS(num,text):
resp = sendCmd(atCMGS, num)
info(resp ," '>' waiting")
if bigger in resp:
gsm.write(text.encode('utf-8'))
gsm.write(bckspc)
info(text, "smsGonder")
def readSensor():
temp = float(sensor.temperature)
humid = float(sensor.relative_humidity)
ntc = pinNtc.read_u16() # read a raw analog value in the range 0-65535
batt = pinBatt.read_u16()
#info(f"temp: {temp:2.2f}, humid: {humid:2.2f}, ntc: {ntc}, batt: {batt}") # humid:{humid:2.2f}, ntc: {ntc}")
#info(type(temp), "type-temp")
return [temp, humid, ntc, batt]
def chkSIMCard():
resp = sendCmd(atCCID)
info(resp, "CCID")
if "00000000000000000000" in resp:
return "absent"
else:
return resp
def makeCall(telNum):
info(telNum, "makeCall")
sendCmd(atD, telNum)
def bootCmd():
sendCmd(atQNITZ)
sendCmd(atCTZU)
sendCmd(atCTZR)
sendCmd(atCCLK)
sendCmd(atCLIP1)
sendCmd(atS0)
sendCmd(atQMOSTAT)
sendCmd(atCRSL)
sendCmd(atL3)
sendCmd(atCLVL)
sendCmd(atQAUDCH)
sendCmd(atQMIC)
sendCmd(atCMGF)
sendCmd(atCNMI)
sendCmd(atCMGL)
sendCmd(atCSCS)
sendCmd(atCPBS)
sendCmd(atQMGDA)
response = sendCmd(atCNUM)
print(response)
getAuthUsers()
rstCount = restartCount()
info(rstCount, "!!restartCount!!")
restartInc()
destIP = readSettings("destIP")
info(destIP, title = "destIP")
destPort = readSettings("destPort")
info(destPort, title = "destPort")
setName = readSettings("setName")
info(setName, title = "setName")
duration = int(readSettings("duration"))
info(duration, title = "duration")
criticTemp = float(readSettings("criticTemp"))
info(criticTemp, "criticTemp")
makeQueryState = readSettings("makeQuery")
info(makeQueryState, "makeQuery")
if makeQueryState == "off":
makeQuery = False
if makeQueryState == "on":
makeQuery = True
holdOn(2)
#boot GSM Module
chkGSMIsOn()
response = sendCmd(at)
print(response)
#wait for access SIM
sendCmd(atQGSN)
resp = chkSIMCard()
if resp == "absent":
while(sw.value() == 1):
neopixelLed(r = 25)
sleep(1/5)
neopixelLed(b = 25)
sleep(1/5)
else:
bootCmd()
holdOn(1)
sayac = 0
sayac2 = 0
if __name__ == "__main__":
while(sw.value() == 1):
sayac += 1
if sayac > 50000 :
sayac = 0
sayac2 +=1
sleep(1/10)
#Arama erteleme rutini
if (sayac > (suspendedAt + duration)):
annoation = False
if (sayac % 5) == 0:# 1sn/20
if gsm.any() >0:
sendCmd()
if (sayac % 10) == 0: # 1sn/1
tickTock = not tickTock
info(sayac, "sayac")
if tickTock == True:
neopixelLed(b = 25)
else:
neopixelLed()
if (sayac % 300) == 0: # 30sn/1
values = readSensor()
temp = float(values[0])
criticTemp = float(criticTemp)
if temp < criticTemp:
if (annoation == False):
annoation = True
telNum = sendCmd(atCPBR,1)[1]
makeCall(telNum)
suspendedAt = sayac
humid = values[1]
ntc = values[2]
batt = values[3]
text = f"Alarm\r\n Konum: {setName}\r\n Sicaklik: {temp:2.2f}\r\n nem: {humid:2.2f}\r\n ntc: {ntc}\r\n batt: {batt}"
sendSMS(telNum, text)
if ((sayac % 1000) == 0) and (makeQuery == True):#100sn/1
info(makeQuery, "query")
query = "chk"
request(destIP, destPort, query)
#query = "chk"
#request(destIP, destPort, query)
Comments