Steve M.
Created June 17, 2019 © GPL3+

Why is water dripping from my ceiling?

Condensation in your attic can lead to health problems and expensive repairs. Is there a simple way to alert when there's danger?

IntermediateFull instructions provided5 hours35
Why is water dripping from my ceiling?

Things used in this project

Hardware components

SmartEdge Agile Brainium
Avnet SmartEdge Agile Brainium
A powerful little sensor package in an easy-to-use format.
×1
iPhone
Apple iPhone
Used as gateway for the Agile device
×1
Raspberry Pi 2 Model B
Raspberry Pi 2 Model B
Easy way to develop the needed software interface in Python.
×1

Software apps and online services

SMS Messaging API
Twilio SMS Messaging API
Very cool service to enable SMS messaging.
Thonny
Thonny is a Python IDE built into the RPi I was using. Simple but effective.

Story

Read more

Code

Atticmon.py

Python
This is the code required to make the project work
import uuid

import paho.mqtt.client as mqtt

import json

import time

from twilio.rest import Client

#Variables
T = 0.0  #temp in deg C
H = 0.0 #humidity in %
samplefreq = 1 #temp and humid sample frequency in seconds
okmsgfreq = 24 #how often to send an ok message in hours
numsamples = 0 #number of times we have sampled without condensation
condensealert = 'Check attic! You may have condensation.'
okmsg = 'No condensation for the last ' + str(okmsgfreq) + ' hours.'


#Twilio info
twilio_account_sid = "your account side here"
twilio_auth_token = "your auth token here"
to_number = "+1your to number here"
from_number = "+1your from number here"

#Connection Info
mqtt_user_name = 'your username here'
mqtt_password = 'your password here'  # copy and paste here external client id from your account
user_id = 'your user id here'  # copy and paste here your user id
device_id = 'your device id here' # copy and paste here your device id

#MQTT stuff
alerts_topic = '/v1/users/{user_id}/in/alerts'.format(user_id=user_id)
acc_norm_datasource_topic = '/v1/users/{user_id}/in/devices/{device_id}/datasources/ACCELERATION_NORM'.format(
    user_id=user_id,
    device_id=device_id)

humid_topic ='/v1/users/{user_id}/in/devices/{device_id}/datasources/HUMIDITY'.format(user_id=user_id, device_id=device_id)
temp_topic ='/v1/users/{user_id}/in/devices/{device_id}/datasources/HUMIDITY_TEMPERATURE'.format(user_id=user_id, device_id=device_id)


#Cert stuff
ca_cert_path = 'cacert.crt'  

# Function that tests for condensation and messages accordingly
def condensationtest(T, H):
    global numsamples  #make numsamples able to be changed in this function
    client = Client(twilio_account_sid, twilio_auth_token) #set up Twilio client
    
    
    dp= T - (100-H)/5  #approximation of dewpoint
    #Troubleshooting helpers.  Uncomment if needed.
    #print('Here is Temp, Humidity, Dewpoint')
    #print(T)
    #print(H)
    #print(dp)
    
    if T < dp:
        condense_msg="Warning! Conditions for condensations exist."
        print(condense_msg)
        message = client.messages.create(
            to= to_number,
            from_=from_number,
            body=condense_msg)
    
    else:
        no_condense_msg= "No condensation for the last " + str(okmsgfreq) + " hours."
        print(no_condense_msg)
        numsamples = numsamples + 1  #Increment number of samples counter
        print("There have been " + str(numsamples) + " with no condensation.")
        howlong = numsamples * samplefreq  #Calculate how long we have gone in sec with no condensation 
        if (howlong / 3600) >= okmsgfreq:  
            message = client.messages.create(
            to= to_number,
            from_=from_number,
            body=no_condense_msg)
            print('Just sent ok message')


def on_connect(client, userdata, flags, rc):
    print('Connected with result code {code}'.format(code=rc))  #Tells us if connection was made
    

def on_message(client, userdata, msg):
    #print('Msg received from topic={topic}\n{content}'.format(topic=msg.topic, content=str(msg.payload)))
    global T  #Makes T changeable in this function
    global H  #Makes H changeable in this function
    
    
    m_decode=str(msg.payload.decode("utf-8","ignore"))
    m_in=json.loads(m_decode)
    whatiget=(m_in[0]["scalar"])
    print(str(whatiget))
    
    print('=' + str(msg.topic))
    if ("TEMPERATURE" in str(msg.topic)):
        T=whatiget
    else:
        H=whatiget
        print('about to call condensationtest')
        condensationtest(T,H)
    


def main():
    
    #this stuff came from Brainium
    client = mqtt.Client(client_id=str(uuid.uuid4()), transport='websockets')
    client.on_connect = on_connect
    client.on_message = on_message

    client.tls_set(ca_certs=ca_cert_path)
    client.username_pw_set(mqtt_user_name, mqtt_password)

    client.connect('ns01-wss.brainium.com', 443)

    #client.subscribe(alerts_topic) - not needed
    #client.subscribe(acc_norm_datasource_topic) - not needed
    
    client.subscribe(temp_topic)
    client.subscribe(humid_topic)
    while True:
        client.loop()
        print('  ')  #put some space between loops in what is printed to the log
        print('  ')  #put some space between loops in what is printed to the log
        time.sleep(samplefreq) #wait in between messages based on samplefreq variable
    
    
    
    


if __name__ == "__main__":
    main()

Credits

Steve M.

Steve M.

1 project • 0 followers

Comments