Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
craigcmehil
Community Manager
Community Manager
 



It's Thursday and I've never actually done one of those "Throw Back Thursday" things and if I understand right it's typically about photos but since according to the Urban dictionary that has changed I decided why not do my own.
Originally "throwback Thursday" but now often used on other days. Can now stand for "throwback to" to indicate an old photo, thought, idea, etc. Often used in social media to reminisce, as usually social media is supposed to show the "here/now/recently."

So here I am digging into my archives and came across this interesting project I did ages ago and I still pull it out from time to time and the last time I did someone said can't you blog about that? So here we go.

So what was the project? Check out how to grab temperature data from a Raspberry Pi and send it to SAP HANA, and take it a step further to get control values from the system to control physical hardware.

The cool part of this is the fact that we have tutorials online already that will help you accomplish this so I'm not going to walk you through every single aspect here instead I'll point you to existing material and perhaps you'll find some other items in the catalog that could be interesting for you as well.

To start with we need the SAP HANA project, back then it was of course SAP HANA XSC so the best place to get up to speed on that would be the following tutorial series we have published that shows how to create your project, tables, procedures and services to publish data and display data.

  1. IoT setup: SAP HANA XS (on-premise or stand-alone server)

  2. Posting data with a REST Client

  3. Checking your data

  4. Using the Tessel to post data to SAP HANA


This particular series focuses on the Tessel 1st generation device but I'll show you the code for the Raspberry Pi I used. Also it's really only the first 2 steps that are most important, very similar to this series posted as well.

  1. Develop your first SAP HANA XSC Application

  2. Access your first data in a SAP HANA XSC Application

  3. Enable XSODATA in your SAP HANA XSC Application

  4. Consume XSODATA in your SAP HANA XSC Application


So hopefully at this point you have your XS app running or maybe even converted it all over to an XSA one?



Now for the actual hardware, which is the really fun part right? So I used a Raspberry Pi which is a great little device and initially I connected some LEDs and a temperature sensor.

  • Connect a black jumper wire to the GND

  • Connect a red jumper wire to the 3.3 V

  • Place an LED in the breadboard

  • Place a 220 Ohm Resister from GND to the short leg of the LED

  • Place a jumper wire from the long leg of the LED to the GPIO pin 18

  • Repeat the process for the second LED and connect to GPIO pin 22

  • Place the digital temperature sensor on the bread board, we are using DS18B20

  • From the "left" leg of the sensor we run a black jumper wire to GND

  • From the "right" leg of the sensor we run a red jumper wire to 3.3v

  • From the "center" leg of the sensor we run a jumper wire to the GPIO pin 16

  • Between the "right" and "center" legs we place a 4.7K Ohm resistor


With the hardware connected I wrote up a quick and dirty little program to interface and run it and of course to post to my XS application.
        import os
import glob
import json
import urllib2
import time
import RPi.GPIO as GPIO

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'

hanaposts = 0
hanaposts2 = 0

# to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
# set up GPIO output channel
GPIO.setup(18, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)

def blink(pin):
GPIO.output(pin,GPIO.HIGH)
time.sleep(1)
GPIO.output(pin,GPIO.LOW)
time.sleep(1)
return

def basic_authorization(user, password):
s = user + ":" + password
return "Basic " + s.encode("base64").rstrip()

def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines

def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c

while True:
hanaposts += 1
txtTemp = read_temp()
txtDate = '/Date(' + str(int(time.time())) + ')/'
url = 'http://[SERVER IP]:[SERVER PORT]/sap/devs/demo/iot/services/iot_input.xsodata/sensor'
params = {"ID": "1", "TDATE": txtDate, "SVALUE": str(txtTemp), "SNAME": "Craig", "STYPE": "Temp" }
req = urllib2.Request(url,
headers = {
"Authorization": basic_authorization('[USER]', '[PASSWORD]'),
"Content-Type": "application/json",
"Accept": "*/*",
}, data = json.dumps(params))
f = urllib2.urlopen(req)
# LED
if hanaposts == 25:
hanaposts = 0
hanaposts2 += 1
blink(22)
if hanaposts2 == 50:
hanaposts2 = 0
blink(18)
time.sleep(1)

Of course I did not stop there, I wanted data going both to and from the device and not just storing my little temperature sensor.

Here I went a bit more complex (even more so for the final bit that you see in the video above) so I added more components. Namely here I added more lights to visually see the processes happening and I added a fan that in turn cools down the sensor if it reports to hot.



 

Jumping back to the HANA system I added an additional "control" table that I could read values from to determine if I reached one of the limits or not. To access that table I use and OData service.
jsonStr = getServerResponse('http://[SERVER IP]/[XS PATH]/iot_control.xsodata/control?$format=json&$filter=SCONTROL%20eq%20%27COLD%27')
coldTemp = jsonStr['d']['results'][0]['SVALUE']

With my additional hardware components, my additional tables and controls in place it was time to modify the Python code to access the new values and activate the new fan.
	import os
import glob
import json
import urllib2
import time
import RPi.GPIO as GPIO

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
maxtemp = 0
mintemp = 0

# to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD)
# set up GPIO output channel
GPIO.setup(12, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
GPIO.setup(16, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)

def blink(pin):
GPIO.output(pin, GPIO.HIGH)
time.sleep(0.5)
GPIO.output(pin, GPIO.LOW)
time.sleep(0.5)
return

def temp_low():
GPIO.output(12, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(15, GPIO.HIGH)
GPIO.output(16, GPIO.LOW)
return

def temp_high():
GPIO.output(12, GPIO.LOW)
GPIO.output(13, GPIO.HIGH)
GPIO.output(15, GPIO.HIGH)
GPIO.output(16, GPIO.LOW)
return

def temp_ok():
GPIO.output(12, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(15, GPIO.LOW)
GPIO.output(16, GPIO.HIGH)
return

# Get values from server
def getServerResponse(url):
req = urllib2.Request(url)
opener = urllib2.build_opener()
f = opener.open(req)
return json.loads(f.read())

def basic_authorization(user, password):
s = user + ":" + password
return "Basic " + s.encode("base64").rstrip()

def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines

def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c

jsonStr = getServerResponse("http://[SERVER IP]/sap/devs/demo/iot/services/iot_control.xsodata/control?$format=json&$filter=SCONTROL%20eq%20%27COLD%27")
mintemp = jsonStr['d']['results'][0]['SVALUE']
print ('MIN Temp is set at ' + mintemp + 'c')

jsonStr = getServerResponse("http://[SERVER IP]/sap/devs/demo/iot/services/iot_control.xsodata/control?$format=json&$filter=SCONTROL%20eq%20%27HOT%27")
maxtemp = jsonStr['d']['results'][0]['SVALUE']
print ('MAX Temp is set at ' + maxtemp + 'c')

while True:
# Value of Sensor
txtTemp = read_temp()
# Timestamp
txtDate = '/Date(' + str(int(time.time())) + ')/'
# HTTP Post to HANA
url = 'http://[SERVER IP]/sap/devs/demo/iot/services/iot_input.xsodata/sensor'
params = {"ID": "1", "TDATE": txtDate, "SVALUE": str(txtTemp), "SNAME": "MySensor", "STYPE": "Temp" }
# print(params)
req = urllib2.Request(url,
headers = {
"Authorization": basic_authorization('[USER]', '[PASSWORD]'),
"Content-Type": "application/json",
"Accept": "*/*",
}, data = json.dumps(params))
f = urllib2.urlopen(req)
blink(18)


jsonStr = getServerResponse("http://[SERVER IP]/sap/devs/demo/iot/services/iot.xsodata/IOT?$orderby=ID%20desc&$top=1&$select=SVALUE&$filter=SNAME%20eq%20%27Ian%27&$format=json")
currtemp = jsonStr['d']['results'][0]['SVALUE']

if (float(currtemp) <= float(maxtemp)):
if (float(currtemp) < float(mintemp)):
print ('>>> HEATER ON ' + currtemp + "c lower than MIN temp of " + str(mintemp) + "c")
temp_low()
else:
print ('HEATER/FAN OFF ' + currtemp + "c within bounds")
temp_ok()
else:
print ('>>> FAN ON ' + currtemp + "c exceeds MAX temp of " + str(maxtemp) + "c")
temp_high()

# Loop to next reading
time.sleep(3)

The video shows the "final" version which I added some button controls to but the buttons simply made doing the "demo" easier as I could start and stop the process as I needed to and not just have it all happen at once.

Happy Thursday!