This project has the purpose to build a weather station with several monitoring sensors send the data in cloud and monitor the data from any device. The POC is using only a light and a temperature sensor but it can be extended to any number of sensors like: humidity, wind speed and so on.
To build a weather station you'll need a RaspberryPi(with SD, OS installed..), a number of sensors(light intensity, temperature, humidity...), a sensor schield(analog to digital convertor and signal multiplexor), connection cables(all types: father-father, mother-mother, father-mother..) and a breadbord(for powering up multiple sensors). I used this setup with this breadbord
I have a temperature and a light intensity sensor:
Temperature sensor
Light intensity sensor
I also have a SensorSchield that will convert the analogical values of the sensors to digital values. The RaspberryPi does not have pins for analogic input, so a converter is needed.SensorSchield
Connect the SensorSchield to the RaspberryPi on GPIO pins 8, 9, 10, 11 as shown in the picture. Also connect the sensors to the SensorSchield. Every sensor is connected through breadboard to GND and VCC(3.3V) and to sensorSchield on an analog exit(V0 to V7)For programming the sensors I used spidev library. If you don't have it you can take it from here . I wrote the following code to get the data from the sensors:
import spidev
import time
spi = spidev.SpiDev()
spi.open(0,0)
def readadc(adcum):
if (adcum > 7) or (adcum < 0):#analog identifier out of bounds
return -1
r = spi.xfer2([1, 8+adcum<<4, 0])
adcout = ((r[1]%3 << 8) + r[2])
return adcout
msgCount = 0
while(msgCount < 10):
lightVal = readadc(0)#0 connects light sensor, 1 connects temperature sensor
voltageVal = readadc(1) * 3.3/1024
tempCelsius = (voltageVal - 0.5) * 100
print "Temperature(celsius):", tempCelsius
print "Light val:", lightVal
time.sleep(1)
The code is intended to loop 10 times and display data from sensor on every second.
The output will look like:
Temperature(celsius): 27.021484375
Light val: 234
.....
import json
print json.dumps({'Temperature': tempCelsius, 'LightIntensity': lightVal}, sort_keys=True, indent=4, separators=(',', ': '))
To send the data in cloud I used a AZURE server with an IoT Hub that will act like a data broker.
Microsoft offers a MQTT/HTTP clinet for communicating with the AZURE server for Python.
You need to build this client on you local machine.
git clone --recursive https://github.com/Azure/azure-iot-sdk-python.git
On a terminal, navigate to: 'azure-iot-sdks\python\build_all\linux\' and run:
./setup.sh #to install all dependencies
./build.sh #will build all necessary C libraries
sudo date --set "20 jan 2017 15:00:00"
This should solve your issue. In case the error persists,openssl s_client -connect
openssl x509 -in /usr/lib/ssl/certs/Baltimore_CyberTrust_Root.pem -text
You can see there validity period:tcpdump -w capture.pcap
this will create capture.pcap on home/pi
sudo chmod a+rw capture.pcap
rename the file because pcap is not seen
ftp copy it to windows
Unify the code for programming the sensors and the IoT hub client.
import time
import sys
import spidev
import iothub_client
import json
from datetime import datetime
from iothub_client import *
message_timeout = 10000
# global counters
receive_callbacks = 0
send_callbacks = 0
protocol = IoTHubTransportProvider.MQTT
connection_string = "HostName=;DeviceId=;SharedAccessKey="
spi = spidev.SpiDev()
spi.open(0,0)
def readadc(adcum):
if (adcum > 7) or (adcum < 0):
return -1
r = spi.xfer2([1, 8+adcum<<4, 0])
adcout = ((r[1]%3 << 8) + r[2])
return adcout
class HubManager(object):
def __init__(self):
self.client = IoTHubClient(connection_string, protocol)
# set the time until a message times out
self.client.set_option("messageTimeout", message_timeout)
self.client.set_message_callback(self._receive_message_callback, receive_context)
def _receive_message_callback(self, message, counter):
global receive_callbacks
buffer = message.get_bytearray()
size = len(buffer)
print("Received Message [%d]:" % counter)
print(" Data: <\%s> & Size=\%d" %
(buffer[:size].decode('utf-8'), size))
map_properties = message.properties()
key_value_pair = map_properties.get_internals()
print(" Properties: %s" % key_value_pair)
counter += 1
receive_callbacks += 1
print(" Total calls received: %d" % receive_callbacks)
return IoTHubMessageDispositionResult.ACCEPTED
def _send_confirmation_callback(self, message, result, user_context):
global send_callbacks
print "Confirmarion:", datetime.now()
print(
"Confirmation[%d] received for message with result = %s" %
(user_context, result))
map_properties = message.properties()
key_value_pair = map_properties.get_internals()
print(" Properties: %s" % key_value_pair)
send_callbacks += 1
print(" Total calls confirmed: %d" % send_callbacks)
def send_event(self, event, properties, send_context):
if not isinstance(event, IoTHubMessage):
event = IoTHubMessage(bytearray(event, 'utf8'))
if len(properties) > 0:
prop_map = event.properties()
for key in properties:
prop_map.add_or_update(key, properties[key])
self.client.send_event_async(
event, self._send_confirmation_callback, send_context)
if __name__ == '__main__':
print("\nPython %s" % sys.version)
print("IoT Hub for Python SDK Version: %s" % iothub_client.__version__)
print("Starting the IoT Hub Python sample...")
print(" Protocol %s" % protocol)
print(" Connection string=%s" % connection_string)
try:
hub_manager = HubManager()
msgCount = 0
while msgCount < 2:
lightVal = readadc(0)
voltageVal = readadc(1) * 3.3 /1024
tempCelsius = (voltageVal - 0.5) * 100
print "Celsius:", tempCelsius
print "VoltageVal:", lightVal
currentTime = datetime.now()
strDate = "%s-%s-%s %s:%s" %(str(currentTime.year), str(currentTime.month), str(currentTime.day), str(currentTime.hour), str(currentTime.minute))
jsonMsg = json.dumps({'Time': strDate, 'Temperature': tempCelsius, 'LightIntensity': lightVal}, sort_keys=True, indent=4, separators=(',', ': '))
msg_properties = {
"Property": "MsgId_%d" %msgCount
}
print jsonMsg
hub_manager.send_event(jsonMsg, msg_properties, msgCount)
msgCount += 1
time.sleep(60)
except IoTHubError as e:
print("Unexpected error %s from IoTHub" % e)
except KeyboardInterrupt:
print("IoTHubClient sample stopped")
The output should look like:
{
"LightIntensity": 292,
"Temperature": 28.310546874999996,
"Time": "2017-3-2 16:40"
}
Confirmarion: 2017-03-02 16:40:14.026844
Confirmation[0] received for message with result = OK
Properties: {'Property': 'MsgId_0'}
Total calls confirmed: 1
You can create the monitoring application in any technology that supports communication on mqtt/http protocol.
There are many applications already created, so there is no need to post one here, you can implement one in no time just follow
this link that has implementation for .NET, Node.js or plain Java.
Good luck on creating your own weather station.
If you need some guidance in engineering field or you're seeking for some help don't hesitate to write me.