Browse Source

Upload files to ''

atmos commit
master
cs171062 3 years ago
parent
commit
f5bc152a2d
  1. 116
      atmos-device.py
  2. 123
      atmos-server.py
  3. 3
      gmail_credentials.txt
  4. BIN
      logo.png
  5. 66
      webapp.html

116
atmos-device.py

@ -0,0 +1,116 @@
import math
import random
import sched, time
import socket, pickle
from threading import Timer
class Conditions:
def __init__(self):
self.temperature = random.uniform(25.0, 38.0)
self.air_humidity = random.uniform(0.2, 0.6)
self.soil_humidity = random.uniform(0.2, 0.6)
self.air_speed = random.randint(16, 30)
def new_conditions(self):
self.temperature = random.uniform(25.0, 38.0)
self.air_humidity = random.uniform(0.2, 0.6)
self.soil_humidity = random.uniform(0.2, 0.6)
self.air_speed = random.randint(16,30)
return self
#function that calculates if the differnce between the values exceeds 10%
def calculate_difference(previous, current):
if abs((previous - current) / previous) > 0.1:
return True
else:
return False
#function that decides if the new measurements need to be sent over the server
def needs_send(previous, current):
if (calculate_difference(previous.temperature, current.temperature) or
calculate_difference(previous.air_humidity, current.air_humidity) or
calculate_difference(previous.soil_humidity, current.soil_humidity) or
calculate_difference(previous.air_speed, current.air_speed)) :
return True
#copy function
def copy(obj1, obj2):
obj1.temperature = obj2.temperature
obj1.air_humidity = obj2.air_humidity
obj1.soil_humidity = obj2.soil_humidity
obj1.air_speed = obj2.air_speed
#function that checks if data has been sent in 5 minutes
def send_is_true(data_sent, current_conditions):
if data_sent == True:
pass
else:
print("Data has not been sent for 5 minutes\n")
print("Sending current data")
my_pickled_object = pickle.dumps(current_conditions)
s.send(my_pickled_object)
#socket connection
s = socket.socket()
port = 3125
s.connect(('localhost', port))
#initializing conditions objects
counter = 0
previous_conditions = Conditions()
current_conditions = Conditions()
#initializing scheduler
f = sched.scheduler(time.time, time.sleep)
#initializing data for time checker
data_sent = False
t = Timer(300.0, send_is_true)
t.start()
def send_data(sc, counter, previous_conditions, current_conditions, data_sent):
if counter == 0: #is this first time sending?
previous_conditions = previous_conditions.new_conditions()
elif counter == 1: #data sets are over 1
current_conditions = current_conditions.new_conditions()
else:
copy(previous_conditions, current_conditions)
current_conditions = current_conditions.new_conditions()
if counter != 0: #will print data to console when we have > 1 conditions
print("\n\n---" + str(counter) + "---")
print("\nPrevious temperature: " + str(int(previous_conditions.temperature)) + " Celcius")
print("Current temperature: " + str(int(current_conditions.temperature)) + " Celcius\n\n")
print(f"Previous soil humidity: " + str(int(previous_conditions.soil_humidity*100)) + " %")
print(f"Current soil humidity: " + str(int(current_conditions.soil_humidity*100)) + " %\n\n")
print(f"Previous air humidity: " + str(int(previous_conditions.air_humidity*100)) + "%")
print(f"Current air humidity: " + str(int(current_conditions.air_humidity*100)) + "%\n\n")
print("Previous air speed: " + str(previous_conditions.air_speed) + " km/h")
print("Current air speed: " + str(current_conditions.air_speed) + " km/h\n\n")
if needs_send(previous_conditions, current_conditions):
print("It needs to be send.")
my_pickled_object = pickle.dumps(current_conditions)
data_sent = True
s.send(my_pickled_object)
else:
print("It doesn't need to be send.")
counter += 1
f.enter(30, 1, send_data, (sc,counter, previous_conditions, current_conditions, data_sent))
f.enter(30, 1, send_data, (f,counter, previous_conditions, current_conditions, data_sent))
f.run()
s.close()

123
atmos-server.py

@ -0,0 +1,123 @@
import socket
import pickle
import time
import sys
from influxdb import InfluxDBClient
import yagmail
class Conditions:
def __init__(self):
self.temperature = None
self.air_humidity = None
self.soil_humidity = None
self.air_speed = None
def calculate_dif(temp, percentage):
temp.sort()
if (temp[4] - temp[0]) / temp[0] >= percentage:
return True
else:
return False
def gmail_send(code):
with open("gmail_credentials.txt") as f:
data = f.readlines()
username = data[0].strip('\n')
password = data[1].strip('\n')
receiver = data[2].strip('\n')
yag = yagmail.SMTP(username, password)
temperature_content = "Attention! Atmos weather device detected a radical change of temperature. Please check the enviroment."
humidity_content = "Attention! Atmos weather device detected a radical change of air humidity. Please check the enviroment."
subject = "Atmos Urgent Notification"
if code == 1:
yag.send(receiver, subject, temperature_content)
else:
yag.send(receiver, subject, humidity_content)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 3125
s.bind(('0.0.0.0', port))
print ('Socket binded to port 3125')
s.listen(3)
print ('socket is listening')
c, addr = s.accept()
print ('Got connection from ' + str(addr) + ' \n')
client = InfluxDBClient(host='localhost', port=8086)
databases = client.get_list_database()
exists = False
for i in databases:
if('atmos' in i['name']):
exists = True
if(exists):
client.switch_database('atmos')
print("Switched to 'atmos' database\n")
else:
client.create_database('atmos')
print("Created database 'atmos'\n")
client.switch_database('atmos')
received = 0
temperature_array = []
airhumidity_array = []
while True:
unpickled_object = pickle.loads(c.recv(4096))
received += 1
temperature_array.append(unpickled_object.temperature)
airhumidity_array.append(unpickled_object.air_humidity)
if(received == 5 ):
is_temp = calculate_dif(temperature_array, 0.4)
is_hum = calculate_dif(airhumidity_array, -0.5)
if is_temp:
print("\nTemperature critical difference!!!")
print("Will now send notification email.\n")
gmail_send(1)
if is_hum:
print("\nHumidity critical difference!!!")
print("Will now send notification email.\n")
gmail_send(2)
#resetting values
temperature_array.clear()
airhumidity_array.clear()
received = 0
json_body = [
{
"measurement": "tablePython",
"tags": {
"location": "Athens"
},
"fields": {
"temperature": str(int(unpickled_object.temperature)),
"soil_humidity": str(int(unpickled_object.soil_humidity*100)),
"air_humidity": str(int(unpickled_object.air_humidity*100)),
"air_speed": str(unpickled_object.air_speed)
}
}
]
client.write_points(json_body)
print("Current temperature: " + str(int(unpickled_object.temperature)) + " Celcius")
print("Current soil humidity: " + str(int(unpickled_object.soil_humidity*100)) + " %")
print("Current air humidity: " + str(int(unpickled_object.air_humidity*100)) + "%")
print("Current air speed: " + str(unpickled_object.air_speed) + " km/h\n")
c.close()

3
gmail_credentials.txt

@ -0,0 +1,3 @@
username
password
receiver's mail

BIN
logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

66
webapp.html

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<title>ATMOS</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body, h1,h2,h3,h4,h5,h6 {font-family: "Montserrat", sans-serif}
.w3-row-padding img {margin-bottom: 12px}
/* Set the width of the sidebar to 120px */
.w3-sidebar {width: 120px;background: rgb(255, 255, 255);}
/* Add a left margin to the "page content" that matches the width of the sidebar (120px) */
#main {margin-left: 120px}
/* Remove margins from "page content" on small screens */
@media only screen and (max-width: 600px) {#main {margin-left: 0}}
</style>
<body class="w3-black">
<!-- Icon Bar (Sidebar - hidden on small screens) -->
<nav class="w3-sidebar w3-bar-block w3-small w3-hide-small w3-center">
<!-- Avatar image in top left corner -->
<img src="logo.png" style="width:100%">
</nav>
<!-- Navbar on small screens (Hidden on medium and large screens) -->
<div class="w3-top w3-hide-large w3-hide-medium" id="myNavbar">
<div class="w3-bar w3-black w3-opacity w3-hover-opacity-off w3-center w3-small">
<a href="#" class="w3-bar-item w3-button" style="width:25% !important">HOME</a>
<a href="#about" class="w3-bar-item w3-button" style="width:25% !important">ABOUT</a>
<a href="#photos" class="w3-bar-item w3-button" style="width:25% !important">PHOTOS</a>
<a href="#contact" class="w3-bar-item w3-button" style="width:25% !important">CONTACT</a>
</div>
</div>
<!-- Page Content -->
<div class="w3-padding-large" id="main">
<!-- Header/Home -->
<header class="w3-container w3-padding-32 w3-center w3-black" id="home">
<h1 class="w3-jumbo"><span class="w3-hide-small">ATMOS</span></h1>
</header>
<!-- About Section -->
<div class="w3-content w3-justify w3-text-grey w3-padding-64" id="about">
<h2 class="w3-text-light-grey">Live data generated from ATMOS weather device</h2>
<hr style="width:200px" class="w3-opacity">
<iframe src="http://localhost:3000/d-solo/rOJrXyBMz/atmos-monitor?orgId=1&refresh=30s&panelId=2" width="1200" height="550" frameborder="0"></iframe>
</div>
</div>
<!-- Footer -->
<footer class="w3-content w3-padding-64 w3-text-grey w3-xlarge">
<i></i>
<i</i>
<i></i>
<i></i>
<i></i>
<p class="w3-medium">Voliotis Ioannis Alexandros for IoT Lab 2021, UNIWA<a></p>
<!-- End footer -->
</footer>
<!-- END PAGE CONTENT -->
</div>
</body>
</html>
Loading…
Cancel
Save