For the purposes of this tutorial, we're going to assume you've already installed the Newbound software on your Raspberry Pi and are now interested in attaching an SHT-1x type moisture sensor like this one.
In order for the software to talk to the sensor, you'll need to make sure certain python libraries are installed on your Raspberry Pi as well: apt-get install python3 python3-dev python3-pip -y pip3 install pi-sht1x
apt-get install python3 python3-dev python3-pip -y pip3 install pi-sht1x
There are a number of ways you can successfully wire one of these up to a Raspberry Pi, but we're going to assume you are using physical pins 17 (3.3v), 19 (BCM 10/Data), 23 (BCM 11/Clock) and 25 (ground), where Red = VCC (3-5VDC), Black or Green = Ground, Yellow = Clock, Blue = Data. (Don't forget to connect a 10K resistor from the blue Data line to the red VCC).
Now, run the MetaBot app on your Raspberry Pi and create a new control. In our example we have a library called "moisture" and we added a control named "sensor". Edit your new control, and use the API tab to create a new command called "read". Set the language to Python. Set the imports to: import sys import json import math from time import sleep import argparse import RPi.GPIO as GPIO from pi_sht1x import SHT1x import logging logger = logging.getLogger() logging.basicConfig(stream=sys.stdout, level=logging.ERROR) Set the code to: with SHT1x(10, 11, gpio_mode=GPIO.BCM, vdd='3.5V', resolution='HIGH', heater=False, otp_no_reload=False, crc_check=True, logger=logger) as sensor: temp = sensor.read_temperature() humidity = sensor.read_humidity(temp) dewpoint = sensor.calculate_dew_point(temp, humidity) h = humidity/100 if humidity < 100 else 0.9999999 a = -math.log(1 - h) b = 0.000045 * ( temp + 460 ) moist = math.pow( a / b, 0.638); val = { 'temperature': temp, 'humidity':humidity, 'dewpoint':dewpoint, 'moisture':moist } return val
import sys import json import math from time import sleep import argparse import RPi.GPIO as GPIO from pi_sht1x import SHT1x import logging logger = logging.getLogger() logging.basicConfig(stream=sys.stdout, level=logging.ERROR)
with SHT1x(10, 11, gpio_mode=GPIO.BCM, vdd='3.5V', resolution='HIGH', heater=False, otp_no_reload=False, crc_check=True, logger=logger) as sensor: temp = sensor.read_temperature() humidity = sensor.read_humidity(temp) dewpoint = sensor.calculate_dew_point(temp, humidity) h = humidity/100 if humidity < 100 else 0.9999999 a = -math.log(1 - h) b = 0.000045 * ( temp + 460 ) moist = math.pow( a / b, 0.638); val = { 'temperature': temp, 'humidity':humidity, 'dewpoint':dewpoint, 'moisture':moist } return val
Next, in the HTML5 tab, add your control's user interface: HTML: <canvas class='fullsize'/> CSS: .fullsize{ width: 100%; height: 100%; background-color:#000c; } JS: var me = this; var ME = $('#'+me.UUID)[0]; var canvas = me.canvas = $(ME).find('canvas')[0]; var ctx = me.ctx = canvas.getContext('2d'); me.ready = function(){ var cdata = $(ME).data('control'); me.which = cdata && cdata.which ? cdata.which : "moisture"; me.title = cdata && cdata.title ? cdata.title : me.which.substring(0,1).toUpperCase()+me.which.substring(1); if (document.body.moisture){ if (document.body.moisture.moisture) me.redraw(); else document.body.moisture.push(me.redraw); } else { document.body.moisture = [ me.redraw ]; send_read(function(result){ var cbs = document.body.moisture; document.body.moisture = result.data; for (var i in cbs) cbs[i](); }); } }; me.redraw = function(){ me.data = document.body.moisture; var w = $(ME).width(); var h = $(ME).height(); var v = me.data && $.isNumeric(me.data[me.which]) ? me.data[me.which] : '--'; var percent = $.isNumeric(v) ? v/100 : 0; var units = me.which == 'temperature' || me.which == 'dewpoint' ? 'c' : '%'; v = $.isNumeric(v) ? v.toFixed(1) : v; var large = 56*w/150; var medium = 24; var small = 18*w/150; var stroke1 = 15*w/150; var stroke2 = 5*w/150; var stroke3 = 8; var h1 = 20 + h/2; var h2 = large*0.65; var h3 = 30; canvas.width = w-2; canvas.height = h-2; ctx.strokeStyle = '#aaa'; ctx.lineWidth = stroke1; ctx.beginPath(); ctx.arc(w/2,h1,w/3,0.75*Math.PI,2*Math.PI); ctx.stroke(); ctx.strokeStyle = '#4b8c2a'; ctx.beginPath(); ctx.arc(w/2,h1,w/3,0.75*Math.PI,0.75*Math.PI + percent*1.25*Math.PI); ctx.stroke(); ctx.font = medium+"px Arial"; ctx.fillStyle = '#fff'; ctx.lineWidth = stroke3; ctx.strokeStyle = '#000'; ctx.textAlign = 'center'; ctx.shadowColor = 'black'; ctx.strokeText(me.title,w/2,h3); ctx.fillText(me.title,w/2,h3); ctx.font = large+"px Arial"; ctx.lineWidth = stroke2; ctx.strokeText(v,w/2,h1+large/4); ctx.fillText(v,w/2,h1+large/4); ctx.font = small+"px Arial"; ctx.strokeText(units,w/2,h1+h2); ctx.fillText(units,w/2,h1+h2); };
<canvas class='fullsize'/>
.fullsize{ width: 100%; height: 100%; background-color:#000c; }
var me = this; var ME = $('#'+me.UUID)[0]; var canvas = me.canvas = $(ME).find('canvas')[0]; var ctx = me.ctx = canvas.getContext('2d'); me.ready = function(){ var cdata = $(ME).data('control'); me.which = cdata && cdata.which ? cdata.which : "moisture"; me.title = cdata && cdata.title ? cdata.title : me.which.substring(0,1).toUpperCase()+me.which.substring(1); if (document.body.moisture){ if (document.body.moisture.moisture) me.redraw(); else document.body.moisture.push(me.redraw); } else { document.body.moisture = [ me.redraw ]; send_read(function(result){ var cbs = document.body.moisture; document.body.moisture = result.data; for (var i in cbs) cbs[i](); }); } }; me.redraw = function(){ me.data = document.body.moisture; var w = $(ME).width(); var h = $(ME).height(); var v = me.data && $.isNumeric(me.data[me.which]) ? me.data[me.which] : '--'; var percent = $.isNumeric(v) ? v/100 : 0; var units = me.which == 'temperature' || me.which == 'dewpoint' ? 'c' : '%'; v = $.isNumeric(v) ? v.toFixed(1) : v; var large = 56*w/150; var medium = 24; var small = 18*w/150; var stroke1 = 15*w/150; var stroke2 = 5*w/150; var stroke3 = 8; var h1 = 20 + h/2; var h2 = large*0.65; var h3 = 30; canvas.width = w-2; canvas.height = h-2; ctx.strokeStyle = '#aaa'; ctx.lineWidth = stroke1; ctx.beginPath(); ctx.arc(w/2,h1,w/3,0.75*Math.PI,2*Math.PI); ctx.stroke(); ctx.strokeStyle = '#4b8c2a'; ctx.beginPath(); ctx.arc(w/2,h1,w/3,0.75*Math.PI,0.75*Math.PI + percent*1.25*Math.PI); ctx.stroke(); ctx.font = medium+"px Arial"; ctx.fillStyle = '#fff'; ctx.lineWidth = stroke3; ctx.strokeStyle = '#000'; ctx.textAlign = 'center'; ctx.shadowColor = 'black'; ctx.strokeText(me.title,w/2,h3); ctx.fillText(me.title,w/2,h3); ctx.font = large+"px Arial"; ctx.lineWidth = stroke2; ctx.strokeText(v,w/2,h1+large/4); ctx.fillText(v,w/2,h1+large/4); ctx.font = small+"px Arial"; ctx.strokeText(units,w/2,h1+h2); ctx.fillText(units,w/2,h1+h2); };
Finally, download this file and put it in your Raspberry Pi's "newbound/html" folder: cd /root/Newbound/html wget https://www.newbound.com/botmanager/asset/site/moisture.html
cd /root/Newbound/html wget https://www.newbound.com/botmanager/asset/site/moisture.html
Your Raspberry Pi should now serve up a /moisture.html page that looks like this: