├── dbSetup.py ├── templates └── index_ws.html ├── README.md ├── DHT_Sensor_data_SENDER.py └── WS_Reciever.py /dbSetup.py: -------------------------------------------------------------------------------- 1 | import sqlite3 2 | 3 | try: 4 | conn = sqlite3.connect("ws_db.db") 5 | cur = conn.cursor() 6 | cur.execute("CREATE TABLE dataTable_losant (" 7 | "id INTEGER PRIMARY KEY AUTOINCREMENT, humidity TEXT(5), timestamps TEXT(5))") 8 | 9 | conn.commit() 10 | cur.close() 11 | conn.close() 12 | print("Table Successfully Created!") 13 | except Exception as e: 14 | print("An error occurred!\n", 15 | "Reason : ",e) 16 | -------------------------------------------------------------------------------- /templates/index_ws.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome|Dashboard 5 | 6 | 7 | 12 | 13 | 14 |
15 |
16 |
17 |

Welcome {{user}}!

18 |

19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | {% for row in rows %} 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | {% endfor %} 44 | 45 |
SNoTimeHumiditytemperatureLatitudeLongitude
{{row["id"]}} {{ row["timestamps"]}}{{row["humidity"]}}{{row["temperature"]}} {{ row["lat"]}} {{ row["lng"]}}
46 |
47 | 48 |
49 |

50 | 51 | 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Weather-Station 2 | > Using Onion Omega 2+ and DHT-11 3 | 4 | This is a Prototype model for IoT. This model is suitable for any IoT device that supports Python. The system can be integrated 5 | to send data from the device to the cloud using MQTT protocol, which is a lightweight protocol for machine to machine communication. 6 | On the other end, the system can be integrated for receiving the data over cloud for further analysis. 7 | 8 | ## How the system works : 9 | The sender.py file is flashed into any micro controller like Arduino/Raspberry/Onion.
10 | The sender.py file is responsible for sending/publishing the data/values/parameter as a payload to cloud/broker.
11 | This data can collection of data fetched from the sensors. Broker is responsible for forwarding the same to all the subscribed listeners. The receiver.py is one of the subscribed listener. Once the receiver receives this payload/data, it can manage this data as per its needs like for just storing into data or for further analysis and machine learning and many more purposes. 12 | 13 | ## FILE LIST : 14 | 15 | ...|- templates 16 | 17 | >- index.html 18 | |- dbSetup.py 19 | |- README.txt 20 | |- mydb.db 21 | |- receiver.py 22 | |- sender.py 23 | 24 | ## Dependencies in receiving server :- 25 | 1. python v3 26 | 2. flask 27 | 3. flask-mqtt 28 | 4. flask-socketio 29 | 5. eventlet 30 | 31 | ## Dependencies in Sending equipment :- 32 | 1. python v3 33 | 2. paho-mqtt 34 | 35 | ## Suitable Public Brokers for MQTT :- 36 | 1. Eclipse - iot.eclipse.org 37 | 2. Mosquitto - test.mosquitto.org 38 | 3. Hive - broker.hivemq.com 39 | 40 | You can also create your own private Broker for MQTT by using the software provided by hive at https://www.hivemq.com/downloads/ 41 | 42 | 43 | The project is still under its initial stages of development and we welcome any kind of suggestions or improvements. -------------------------------------------------------------------------------- /DHT_Sensor_data_SENDER.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | 4 | How this file works : 5 | sender.py is flashed into the micro controller along with the required code for fetching data from necessary sensors. 6 | This file then publishes(sends) the data to the broker. Broker can be a public broker like iot.eclipse.org or 7 | test.mosquitto.org or broker.hivemq.com. Or it can be a custom server that supports MQTT protocols. 8 | 9 | Required libraries (dependencies): 10 | python v3 11 | paho-mqtt 12 | """ 13 | # currently this test file sends a toggle value of on/off along with a timestamp. This can be changed with your sensor values 14 | 15 | import subprocess 16 | import paho.mqtt.client as mqtt #import the client1 17 | import time,json,string 18 | 19 | 20 | # broker_address="192.168.1.184" 21 | broker_address="iot.eclipse.org" 22 | print("creating new instance") 23 | client = mqtt.Client("akrdClient") # create new instance 24 | try: 25 | print("connecting to broker") 26 | client.connect(broker_address) # connect to broker 27 | client.loop_start() # start the loop 28 | i=0 29 | while i<25: 30 | pinNumber = 0 31 | sensorModel = 'DHT11' 32 | proc = subprocess.Popen(['dht-sensor ' + str(pinNumber) + ' ' + sensorModel], stdout=subprocess.PIPE, shell=True) 33 | (out, err) = proc.communicate() 34 | sensor_data = out.split('\n') 35 | humidity = sensor_data[0] 36 | temperature = sensor_data[1] 37 | proc_loc = subprocess.Popen(['ubus call gps info'], stdout=subprocess.PIPE, shell=True) 38 | (output, error) = proc_loc.communicate() 39 | w=string.replace(str(output),"\n\t"," ") 40 | json_acceptable_string = w.replace("'", "\"") 41 | loc_data=json.loads(json_acceptable_string) 42 | # print "Humidity:" 43 | print str(humidity) + "%" 44 | # print "Temperature:" 45 | print str(temperature) + "°C\n" 46 | data = json.dumps({'humidity':humidity,'temperature':temperature,'timestamp':time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), 47 | 'lat':loc_data['latitude'], 'lng':loc_data['longitude']}) # json is a recommended data format 48 | 49 | print("Publishing message to topic","sigmaway/akrd/db1") 50 | client.publish("sigmaway/akrd/db1" 51 | "",data) 52 | print('data = ',data,i+1) 53 | time.sleep(3.5) # wait 54 | i+=1 55 | except Exception as e: 56 | print("Error occured : ", e) 57 | 58 | client.loop_stop() #stop the loop 59 | -------------------------------------------------------------------------------- /WS_Reciever.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file, along with the HTML page, needs to be uploaded on cloud service which supports web sockets like AWS. 3 | 4 | How this file works : 5 | This file first subscribes to a topic when the HTML page is opened. Then it will receive any message with same topic 6 | over the MQTT broker. Once the message is received, this file stored the value into the SQLite3 Database. Every time 7 | the page is reloaded, the displayed data is refreshed(again fetched from the database). 8 | 9 | Required python libraries(dependencies): (use pip install) 10 | python v3 11 | flask 12 | flask-mqtt 13 | flask-socketio 14 | eventlet 15 | 16 | References : 17 | MQTT - https://mqtt.org/tag/paho (lightweight connectivity protocol for M2M communication) 18 | flask - http://flask.pocoo.org/ (Micro web framework written in python) 19 | flask-socket - https://flask-socketio.readthedocs.io/en/latest/ (web sockets compatible with flask) 20 | SQLite3 - https://www.sqlite.org/index_ws.html (lightweight relational database) 21 | custom broker - https://www.hivemq.com/downloads/ (Creating your own custom broker) 22 | """ 23 | 24 | # this is a test program which receives the the timestamp when the light is turned on or off and stores it into the database 25 | 26 | from flask import Flask, render_template, redirect 27 | from flask_socketio import SocketIO 28 | from flask_mqtt import Mqtt 29 | import eventlet, sqlite3 as sql,json 30 | 31 | # initialising flask 32 | app = Flask(__name__, static_url_path='') 33 | eventlet.monkey_patch() 34 | 35 | # configuring app for required MQTT parameters 36 | app.secret_key = 'anantranajoykey' #keep it secret 37 | app.config['SECRET'] = '121202' #keep it secret 38 | app.config['TEMPLATES_AUTO_RELOAD'] = True 39 | app.config['MQTT_BROKER_URL'] = 'iot.eclipse.org' # suitable free brokers - iot.eclipse.org / test.mosquitto.org / broker.hivemq.com 40 | app.config['MQTT_BROKER_PORT'] = 1883 41 | app.config['MQTT_USERNAME'] = 'Ranajoy' 42 | app.config['MQTT_PASSWORD'] = '123456' 43 | app.config['MQTT_KEEPALIVE'] = 10 44 | app.config['MQTT_TLS_ENABLED'] = False 45 | app.config['MQTT_LAST_WILL_TOPIC'] = 'sigmaway/akrd/lastwill' 46 | app.config['MQTT_LAST_WILL_MESSAGE'] = 'bye' 47 | app.config['MQTT_LAST_WILL_QOS'] = 2 48 | 49 | 50 | # initialising MQTT 51 | mqtt = Mqtt(app) 52 | 53 | # initialising socket 54 | socketio = SocketIO(app) 55 | 56 | # Function for storing data into database table 57 | def toDatabase(data): 58 | try: 59 | conn = sql.connect('ws_db.db') # connecting to database 60 | cur = conn.cursor() # setting the cursor 61 | # SQL query for insertion into table 62 | cur.execute("INSERT INTO dataTable (humidity,temperature,timestamps,lat,lng) VALUES ('%s','%s','%s','%s','%s')"%(data['humidity'], 63 | data['temperature'],data['timestamp'], data['lat'], data['lng'])) 64 | conn.commit() # saving the changes 65 | cur.close() # closing cursor 66 | conn.close() # closing the connection 67 | # print("Successfully stored into Database") 68 | except Exception as e: 69 | print("An error occurred\n" 70 | "Error : ", e) 71 | 72 | # function for fetching data from database table 73 | def al(): 74 | con = sql.connect("ws_db.db") # creating connection with database 75 | con.row_factory = sql.Row 76 | cur = con.cursor() # setting the cursor 77 | cur.execute("select * from dataTable") # SQL query for fetching all of the data from the table 78 | rows = cur.fetchall(); # fetching the data and storing it into a variable 79 | cur.close() # closing the cursor 80 | con.close() # closing the connection 81 | return rows 82 | 83 | # routing home page (HTML page) 84 | @app.route('/') 85 | def index(): 86 | handle_subscribe() # Function Call to subscribe to the topic 87 | rows = al() # function call to fetch values from the Table (Database) 88 | return render_template('index_ws.html', rows = rows) # rendering the HTML page and passing the fetched values 89 | 90 | # function to subscribe to the topic 91 | @socketio.on('subscribe') 92 | def handle_subscribe(): 93 | topic = 'sigmaway/akrd/db1' # topic name, must be same as the topic name of publisher 94 | qos = 0 95 | mqtt.subscribe(topic, qos) # MQTT function call to subscribe to the topic 96 | # print("*********Susbscibed !! *************") 97 | 98 | # function to print the log data 99 | @mqtt.on_log() 100 | def handle_logging(client, userdata, level, buf): 101 | print(level, buf) 102 | 103 | # function to receive the message from the broker 104 | @mqtt.on_message() # triggered when any message is sent from publisher (prior subscription is must) 105 | def handle_mqtt_message(client, userdata, message): 106 | payload=message.payload.decode() # decoding the message 107 | # print("***** message received = \n", payload, "*****") 108 | if payload != "": # if payload is not empty 109 | json_acceptable_string = payload.replace("'", "\"") 110 | data = json.loads(json_acceptable_string) # converting data into json format 111 | toDatabase(data) # function call for storing data into database 112 | 113 | # function to clear the data in table (triggered on button click from the HTML page) 114 | @app.route('/clearData') 115 | def clearData(): 116 | try: 117 | conn = sql.connect('ws_db.db') 118 | cur = conn.cursor() 119 | cur.execute("DELETE FROM dataTable") 120 | cur.execute("DELETE FROM sqlite_sequence WHERE name = 'dataTable';") # resetting the autoincrement field 121 | conn.commit() 122 | cur.close() 123 | conn.close() 124 | # print("Database Cleared") 125 | except Exception as e: 126 | print("An error occurred\n" 127 | "Error : ", e) 128 | finally: 129 | return redirect('/') # return Home Page 130 | 131 | # running the main thread 132 | if __name__ == '__main__': 133 | # running the socket at localhost at port 5000 134 | # set debug = False before deploying it for commercial use 135 | socketio.run(app, host='127.0.0.1', port=5000, use_reloader=True, debug=True) 136 | --------------------------------------------------------------------------------