Hi everyone
I have pieced together a python script, from various sources, for loading DS18B20 sensors and reading temperatures directly from pin 4 on a Raspberry Pi. So long so good, but i am having problems forwarding the data to emoncms.
The url seems to be setup correctly and i have used the same way for URL-requests as here: https://github.com/emoncms/raspberrypi/blob/master/rfm2pigateway.py
None the less nothing is being updated in the database one the raspberry.
Output:
pi@raspberrypi ~ $ python sensorRead.py
http://localhost/emoncms/input/post?json={28-000003f1cbe0:2256,28-0000040cd9ec:2256,28-000003f1d3c3:2262}
http://localhost/emoncms/input/post?json={28-000003f1cbe0:2262,28-0000040cd9ec:2256,28-000003f1d3c3:2262}
The script:
import os
import glob
import time
import urllib2, httplib
os.system('sudo modprobe w1-gpio')
os.system('sudo modprobe w1-therm')
base_dir = '/sys/bus/w1/devices'
f = open(base_dir + '/w1_bus_master1/w1_master_slave_count', 'r');
sensorCount = f.readlines()
sensorCount = [int(l[0]) for l in sensorCount]
f.close()
f = open(base_dir + '/w1_bus_master1/w1_master_slaves', 'r');
devices = f.readlines()
f.close()
def read_temp_raw(sensor):
device_file = base_dir + '/' + devices[sensor][:-1] + '/w1_slave'
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp(sensor):
lines = read_temp_raw(sensor)
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw(sensor)
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
return temp_string[0:4]
while True:
url = "http://localhost/emoncms/input/post?json={"
for x in range(0, sensorCount[0]):
url = url + devices[x][:-1] + ":" + read_temp(x) + ","
url = url[:-1]+"}"
print(url)
urllib2.urlopen(url)
time.sleep(10)
Does anybody have a clue on what is going wrong?
Kind regards,
Emil Bunk
Re: push data to emoncms with python
Hi.
Glad to have another pythonist here.
You can test your URLs aside the python script with wget or a browser such as links.
I'm wondering if this is not an apikey issue. Try this:
- http://localhost/emoncms/input/post?json={28-000003f1cbe0:2256,28-0000040cd9ec:2256,28-000003f1d3c3:2262}
+http://localhost/emoncms/input/post?json={28-000003f1cbe0:2256,28-0000040cd9ec:2256,28-000003f1d3c3:2262}&apikey=your_read_write_apikey
Re: push data to emoncms with python
I'd like to say you can import rfm2pigateway.py, then instantiate class ServerDataBuffer.
Instantiation :
Re: push data to emoncms with python
Fix commited and pull request sent:
https://github.com/emoncms/raspberrypi/pull/26
With this commit, you can try to import rfm2pigateway and use the ServerDataBuffer class in your script.
Re: push data to emoncms with python
Pythonist, don't know if i would call myself that. This is my first pythonscript, it just seemed like the easy way to access the sensors (red. somebody else wrote the most of the script)
I tried out the URL and it works fine if i run it with a browser. I thought about the api-key too, but it seemed like a overkill to access the database, just to retrieve the api-key. But i will try it out and see if i have more luck :)
Thanks for the quick response
Re: push data to emoncms with python
You're welcome.
You don't have to access the database to get the key.
You can hardcode it, obviously...
Or you can use the new API from emonCMS v5, just like I did in the python script. See function get_settings().
Accessing the DB would mean hardcoding DB login parameters in the script. Not much better than hardcoding the apikey itself. I'm using the csv module because sometimes separating stuff with special characters could be a little tricky.
Regarding the format to send data, I suppose you saw the API help link in the Input menu.
The ServerDataBuffer class I wrote uses the "bulk mode" which means you can't add names to the inputs. It may be a good idea to use the json format where names can be added but it might not be that simple, since I'm not sure this method allows to send samples with different times.
Re: push data to emoncms with python
Make sense and that would be an obvious reason to avoid using the API-key, so no hardcoding was needed. Don't we agree that the rfm2pigateway, uses the same way to request/visit the URL as i have tried? with the only difference being; not including the api-key.
I have also tried this methode: https://github.com/openenergymonitor/EmoncmsPythonLink/blob/master/pylink.py
again no luck.
About the input names, i wanted to add the sensor address as names because they are unique, which will make locating the sensors way easier, if one is reading something out of range. I plan on marking every sensor with its address. (The system i am working on is to be used in vaccine cold room facilities and therefore it should be possible to add and remove sensors as needed)
There is no need to send samples with different time stamps, so that should not be a problem.
I will try out your method later today.
Re: push data to emoncms with python
I'm not sure I understand your first paragraph.
I believe adding the hardcoded apikey works for you, right ?
You can take inspiration in rfm2pigateway for the part where you get the settings (including the apikey) through the API if you don't want it hardcoded.
I now realize it is a bit weird that you need the apikey to post locally, but you can get it for free with a local post through the API. In short, why not authorize a local post without the apikey in the first place ? Historical reasons, I guess.
rfm2pigateway does not use the same syntax as yours to send data samples. See here: http://openenergymonitor.org/emon/node/2249. I think you understood that
You'd rather stick to your way as it makes sense to have names for the inputs and you don't do sample buffering. This means you can't use the ServerDataBuffer class as I wanted to suggest you. No big deal, recreating the URL string isn't so difficult. I just like reusable code and I'd like to address this.
Re: push data to emoncms with python
I'm sorry if i have not made myself clear. Im still quite new to; python, emoncms and all that follows :)
To make things clear:
I have not tried with a hardcoded api yet. But it does work without the api-key through a browser, so if i request:
http://localhost/emoncms/input/post?json={28-000003f1cbe0:2256,28-0000040cd9ec:2256,28-000003f1d3c3:2262}
in the browser on the raspberry, it does make 3 inputs, with the 3 addresses as names and the matching readings, which is what i need.
But the urllib2.open(URL) however does nothing.
urllib2.urlopen(http://localhost/emoncms/input/post?json={28-000003f1cbe0:2256,28-0000040cd9ec:2256,28-000003f1d3c3:2262})
And i two want reusable code, that was why i wanted to avoid the api-key altogether.
Re: push data to emoncms with python
I believe you need to add the apikey to post from a browser, unless you're logged in the emoncms interface with the same browser.
Are you saying you can post from your browser without the apikey and without being logged in ? Is this a browser on the Pi ?
Re: push data to emoncms with python
Of course! didn't think about the login at all, i was logged in when i tried the link. Okay, this should be fixed by adding the API-key, but as we talk about before it would be nice that the script worked without hardcoding an API-key. So is it possible to pull the api?
Thanks again for all your help! :)
Re: push data to emoncms with python
Yes, it is possible. It is what I do in the python script.
You can take inspiration in rfm2pigateway for the part where you get the settings (including the apikey) through the API if you don't want it hardcoded. See function get_settings().
I hope the comments make it clear enough. I'm not a much experienced pythonist myself, I don't use those cryptical one-line-does-it-all instructions, my code is rather step-by-step styled.
Re: push data to emoncms with python
i think i got the part that i need, however it seems like the get_settings() fails.
This is what i use to get the api:
def get_api():
result = urllib2.urlopen("http://localhost/emoncms/raspberrypi/get.json")
result = result.readline()
result = result[1:-1].split(',')
settings = {}
for s in result:
s = csv.reader([s], delimiter=':').next()
settings[s[0]] = s[1].replace("\\","")
return settings['apikey']
with following error:
settings[s[0]] = s[1].replace("\\","")
IndexError: list index out of range
I will admit that i haven't looked into how it works entirely, but in my understanding this should be sufficient for pulling the api.
Re: push data to emoncms with python
I'm still having problems with pulling the api and it will also crash if you remove a sensor. But side from that, everything is working!
Thanks alot for your help Jerome
Re: push data to emoncms with python
You're welcome.
Try this an see what happens:
You get the point.
If this doesn't help. Use the python interpreter, do the imports, and then
To see what is returned. There should be only one line, with the settings.
Re: push data to emoncms with python
Hi Jerome,
It returns nothing, the result is empty. ? Im alittle confused, the path emoncms/raspberrypi/ does not exist, shouldn't it be under /var/www/emoncms/raspberrypi?
Re: push data to emoncms with python
When logged on my rasp, if I issue
I get a file with the following content:
{"userid":"1","apikey":"my_apikey","sgroup":"210",... and all my settings}
I can launch a python interpreter and execute the following commands:
and I get the same result.
Don't you ?
Re: push data to emoncms with python
I am still getting nothing :/
pi@raspberrypi ~ $ wget http://localhost/emoncms/raspberrypi/get.json
--2013-04-18 22:32:46-- http://localhost/emoncms/raspberrypi/get.json
Resolving localhost (localhost)... 127.0.0.1, ::1
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 0 [text/html]
Saving to: `get.json'
[ <=> ] 0 --.-K/s in 0s
2013-04-18 22:32:46 (0.00 B/s) - `get.json' saved [0/0]
Re: push data to emoncms with python
I didn't answer your question. No, you don't need it to be under /var/www/emoncms/raspberrypi. It's a rewrite rule. emoncms/whater goes into emoncms/Modules/whatever. Roughly speaking.
You did install the raspberrypi module, right ?
I don't see why you would have http://localhost/emoncms/input/post working, but not http://localhost/emoncms/raspberrypi/get.json
Perhaps could you have a look in the apache log ?
/var/log/apache2/error.log
Re: push data to emoncms with python
Something was definitely wrong with the RPi module. None of the init scripts were there. I didn't do the installation of emoncms myself. I believe my supervisor has been messing around with things. I have made a new SD card from scratch and things seems to work now.
Thanks a lot,
Jerome :)
I will post the script for mounting multiple DS18B20 sensors on the Pi, when I have fixed a few bugs.