OurWeather REST Interface to the Raspberry Pi Released

GroveWeatherPi

REST-APIOurWeather REST Interface to the Raspberry Pi Released

SwitchDoc Labs has now released a Python program (for the OurWeather REST Interface) that reads the OurWeather Weather Station and stores the data from the weather station in a MySQL database.   It does this by making use of the REST interface of the OurWeather Weather Kit.

What is OurWeather?

0070GOurWeather is an ESP8266 based  connected weather station containing 7 different sensors that will teach about electronics, software and theunspecified-8 copy weather.   It contains all the sensors and wires to make a fully functional, WiFi weather station.   No software programming is required, it works right out of the box. However, if you want to change the way OurWeather works, add your own software or do something entirely different, we have the Open Source software available.   And what is one of the coolest features of OurWeather?   Building the kit requires NO SOLDERING. It uses Grove Connectors.    It is all plug and play based building, with a full step-by-step photograph based instruction manual.  It is a safe and educational way to learn about weather, electronics and science topics.   You can watch our successful kickstarter video here: https://youtu.be/pw6hSNSQnsM

See the Grove Connector Tutorial Here.

What is the REST Interface For OurWeather?

The OurWeather / WeatherPlus Advanced Usage Manual is now available for download on the OurWeather product page and the WeatherPlus product page.

This manual documents the REST interface present in OurWeather / WeatherPlus and tells how to program the WeatherPlus board using the Arduino IDE.

Example of REST Call

https://192.168.1.118/FullDataString

returns a JSON string:

{"FullDataString": "21.30,36.70,25.63,101714.00,620.44,0.00,0.00,0.00,0.70,0.00,0.00,0.00,0.00,0.00,0.00,0,04/24/2016 11:56:10,SwitchDoc Labs", "id": "1", "name": "OurWeather", "connected": true}

The values in the FullDataString are all in metric.

  • Outdoor Temperature
  • Outdoor Humidity
  • Indoor Temperature
  • Barometric Pressure
  • Altitude
  • Current Wind Speed
  • Current Wind Gust
  • Current Wind Direction
  • Rain Total
  • Wind Speed Minimum
  • Wind Speed Maximum
  • Window Gust Minimum
  • Window Gust Maximum
  • Wind Direction Minimum
  • Wind Direction Maximum
  • Is Display English Or Metric
  • Current Date/Time on OurWeather
  • OurWeather Station Name
  • Current Air Quality Sensor Reading
  • Current Air Quality Qualitative Reading

SDL_Pi_DataLoggerIMG_1153

The DataLogger consists of a Raspberry Pi 3 running the DataLogging Python Software,  MySQL, MatPlotLib and an Apache Webserver.

The DataLogging software is available on github.com (SDL_Pi_DataLogger).  The DataLogger software, hardware and installation tutorial is here.

 

Reading from the OurWeather REST Interface from the Raspberry Pi

The code for reading from the OurWeather REST interface is very straight forward on the Raspberry Pi.

The steps are:

1) Set up your URI (URL) call: https://192.168.1.140/FullDataString

2) Read the JSON data from OurWeather using the function “fetchJSONData” shown below

3) Parse the data as shown in the DataLogger example

4) Store it in the MySQL database

5) Analyze the data

Here is the read and database code from SDL_Pi_DataLogger (OURWEATHERFunctions.py):

# set up your OurWeather IP Address here
uri = 'https://192.168.1.140/FullDataString'
path = '/'

# fetch the JSON data from the OurWeather device
def fetchJSONData(uri, path):
        target = urlparse(uri+path)
        method = 'GET'
        body = ''

        h = http.Http()

        # If you need authentication some example:
        #if auth:
        #    h.add_credentials(auth.user, auth.password)

        response, content = h.request(
                target.geturl(),
                method,
                body,
                headers)

        # assume that content is a json reply
        # parse content with the json module
        data = json.loads(content)

        return data

headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8'
}





def readOURWEATHERData(password):
        print('readOURWEATHERData - The time is: %s' % datetime.now())

        data = fetchJSONData(uri, path)


        # pre split weather data
        preSplitData = data['FullDataString']
        WData = preSplitData.split(",")
        print Data

        if (len(WData) < 18):
                # we have a bad read
                # try again later
                print "bad read from OurWeather"
                return 0

        if (len(WData) == 18):
                # Version does not have air quality
                WData.append(0)
                WData.append(4)

        # open database
        con = mdb.connect('localhost', 'root', password, 'DataLogger' )
        cur = con.cursor()

        #
        # Now put the data in MySQL
        #
        # Put record in MySQL

        print "writing SQLdata ";


        # write record
        deviceid = 0
        query = 'INSERT INTO '+OURWEATHERtableName+('(timestamp, deviceid, Outdoor_Temperature , Outdoor_Humidity , Indoor_Temperature , Barometric_Pressure , Altitude , Current_Wind_Speed , Current_Wind_Gust , Current_Wind_Direction , Rain_Total , Wind_Speed_Minimum , Wind_Speed_Maximum , Wind_Gust_Minimum , Wind_Gust_Maximum , Wind_Direction_Minimum , Wind_Direction_Maximum , Display_English_Metrice , OurWeather_DateTime , OurWeather_Station_Name , Current_Air_Quality_Sensor , Current_Air_Quality_Qualitative ) VALUES(UTC_TIMESTAMP(),  %i, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %i, "%s" , "%s", %i, %i)' % ( int(data['id']), float(WData[0]), float(WData[1]), float(WData[2]), float(WData[3]), float(WData[4]), float(WData[5]), float(WData[6]), float(WData[7]), float(WData[8]), float(WData[9]), float(WData[10]), float(WData[11]), float(WData[12]), float(WData[13]), float(WData[14]), int(WData[15]), WData[16], WData[17], int(WData[18]), int(WData[19])) )

        print("query=%s" % query)

        cur.execute(query)
        con.commit()

Drawing the Temperature and Humidity Graph in DataLogger

OurWeather
OurWeather

Once you have the weather data in a database, you can start to perform analysis on the data.   This example uses MatPlotLib.

This graph was taken from our indoor testing OurWeather system inside the lab, so the temperature does not vary much.
Here is the temperature / humidity graphing code from SDL_Pi_DataLogger. The code goes through these four steps:

1) Open MySQL Database

2) Query data from MySQL database, storing in array

3) Build Graph with MatPlotLib

4) Copy resulting graph to /var/www/html to display on webpage

def buildOURWEATHERGraphTemperature(password, myGraphSampleCount):
                print('buildOURWEATHERGraph - The time is: %s' % datetime.now())

                # open database
                con1 = mdb.connect('localhost', 'root', password, 'DataLogger' )
                # now we have to get the data, stuff it in the graph

                mycursor = con1.cursor()

                print myGraphSampleCount
                query = '(SELECT timestamp, deviceid, Outdoor_Temperature, OutDoor_Humidity, OurWeather_Station_Name, id FROM '+OURWEATHERtableName+' ORDER BY id DESC LIMIT '+ str(myGraphSampleCount) + ') ORDER BY id ASC'

                print "query=", query
                try:
                        mycursor.execute(query)
                        result = mycursor.fetchall()
                except:
                        e=sys.exc_info()[0]
                        print "Error: %s" % e


                t = []   # time
                u = []   # Outdoor temperature
                v = []   # Outdoor humidity
                averageTemperature = 0.0
                currentCount = 0

                for record in result:
                        t.append(record[0])
                        u.append(record[2])
                        v.append(record[3])
                        averageTemperature = averageTemperature+record[2]
                        currentCount=currentCount+1
                        StationName = record[4]

                averageTemperature = averageTemperature/currentCount

                print ("count of t=",len(t))

                fds = dates.date2num(t) # converted
                # matplotlib date format object
                hfmt = dates.DateFormatter('%H:%M:%S')
                #hfmt = dates.DateFormatter('%m/%d-%H')

                fig = pyplot.figure()
                fig.set_facecolor('white')
                ax = fig.add_subplot(111,axisbg = 'white')
                ax.vlines(fds, -200.0, 1000.0,colors='w')

                ax2 = fig.add_subplot(111,axisbg = 'white')



                ax.xaxis.set_major_formatter(hfmt)
                pyplot.xticks(rotation='45')
                pyplot.subplots_adjust(bottom=.3)
                pylab.plot(t, u, color='r',label="Outside Temp (C) ",linestyle="-",marker=".")
                pylab.xlabel("Time")
                pylab.ylabel("degrees C")
                pylab.legend(loc='upper left')
                pylab.axis([min(t), max(t), -20, 50])

                ax2 = pylab.twinx()
                pylab.ylabel("% ")
                pylab.plot(t, v, color='b',label="Outside Hum %",linestyle="-",marker=".")
                pylab.axis([min(t), max(t), 0, 100])
                pylab.legend(loc='lower left')
                pylab.figtext(.5, .05, ("%s Average Temperature %6.2f\n%s") %( StationName, averageTemperature, datetime.now()),fontsize=18,ha='center')
                pylab.grid(True)

                pyplot.show()
                pyplot.savefig("/var/www/html/OURWEATHERDataLoggerGraphTemperature.png", facecolor=fig.get_facecolor())



                mycursor.close()
                con1.close()

                fig.clf()
                pyplot.close()
                pylab.close()
                gc.collect()
                print "------OURWEATHERGraphTemperature finished now"

 

2 Comments

  1. Thanks for all the hard work on this project! I am trying to follow along, and I do believe I have everything installed correctly, and I can see the raw data from my OurWeather device in a browser. I modified the uri in ~/SDL_Pi_DataLogger/OURWEATHERFunctions.py but I don’t believe the database is getting any information. Any suggestions on what to check? Or did I miss a step? I see the database in MySQL and it appears to be built correctly.

    Thanks again for such an awesome (and sometimes challenging) project!

    • Pete,

      You have a password wrong or something like that with the MySQL database. One of the problems with running the tasks using apscheduler is that the tasks are run in threads and the exceptions just disappear rather than showing what is wrong. This is something that we need to look into. How to redirect those exceptions to the screen when running in a thread.

      Here is what to do. Execute the read functions directly in the main thread:

      In DataLogger.py, right after this:

      if __name__ == '__main__':

      scheduler = BackgroundScheduler()

      Add the following statement:

      OURWEATHERFunctions.readOURWEATHERData(password)

      Execute DataLogger.py and you will see the exception and be able to figure out what is wrong.

      Best,
      SDL

2 Trackbacks / Pingbacks

  1. OurWeather - Solar Power Extender Kit First Tests - SwitchDoc Labs
  2. Guest Blog - Larry Bonnette's Solar Powered OurWeather Station #3 - SwitchDoc Labs

Comments are closed.