Jump to content

Python help for Raspberry Pi


andy_b_1502

Recommended Posts

I have been following a devicehive tutorial to make a temperature sensor, everything is working as expected up until making the thing update itself temps and relay them into my client. 

 

The script (raspi_led_thermo.py):

 

#/usr/bin/env python

# @author astaff
#
# This sample is to demonstrate DeviceHive Python library
# Connect LED to PIN11 of the board and 1-wire sensor to GPIO4 board PIN #7,
# use pins #1 (3v3) or #2 (5v) for power and pin #6 for ground
#
# (C) DataArt Apps, 2012
# Distributed under MIT license
#

import sys
import os
import time
from time import sleep

try :
import RPi.GPIO as GPIO
except ImportError:
class FakeGPIO(object):
OUT = 'OUTPUT BCM.GPIO17'
BOARD = 'BOARD'
def __init__(self):
print 'Fake gpio initialized'
def setmode(self, value):
print 'Set mode {0}.'.format(value)
def setup(self, io, mode):
print 'Set gpio {0}; Mode: {1};'.format(io, mode)
def output(self, io, vlaue):
print 'Set gpio {0}; Value: {1};'.format(io, vlaue)
GPIO = FakeGPIO()

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from zope.interface import implements
from twisted.python import log
from twisted.internet import reactor, task

import devicehive
import devicehive.auto


# change it to match your address for 1-wire sensor
_W1_FILENAME='/sys/bus/w1/devices/28-000004bc15aa/w1_slave'
if not os.path.exists(_W1_FILENAME) :
_W1_FILENAME = '/dev/null'

# Board's pin #11 (GPIO17)
_LED_PIN=11

# API URL (register for free playground at http://beta2.devicehive.com/playground
_API_URL = 'http://nn1269.pg.devicehive.com/api/'

#
# for easier reading, this class holds all registration information for DeviceHive
#
class RasPiConfig(object):

implements(devicehive.interfaces.IDeviceInfo)

@property
def id(self):
return '9f33566e-1f8f-11e2-8979-c42c030dd6a5'

@property
def key(self):
return 'device-key'

@property
def name(self):
return 'Device1'

@property
def status(self):
return 'Online'

@property
def network(self):
return devicehive.Network(key = 'Netname', name = 'Netname', descr = 'RasPi/Py LED/w1 sample')

@property
def device_class(self):
return devicehive.DeviceClass(name = 'Class1', version = '1.0', is_permanent = False)

@property
def equipment(self):
return [devicehive.Equipment(name = 'LED', code = 'LED', type = 'Controllable LED'), devicehive.Equipment(name = 'THERMO', code = 'temp', type = 'TempSensor')]

#
# This class handles DeviceHive API calls for our device
#
class RasPiApp(object):

implements(devicehive.interfaces.IProtoHandler)

def __init__(self, led, sensor):
super(RasPiApp, self).__init__()
self.connected = False
self.notifs = []
self.info = RasPiConfig()
self.led = led
self.sensor = sensor

def on_apimeta(self, websocket_server, server_time):
log.msg('on_apimeta')

def on_connected(self):
lc = task.LoopingCall(self.sensor.get_temp, self)
lc.start(1)

log.msg('Connected to devicehive server.')
self.connected = True
for onotif in self.notifs :
self.factory.notify(onotif['notification'], onotif['parameters'], device_id = self.info.id, device_key = self.info.key)
self.notifs = []
def on_subscribe(result) :
self.factory.subscribe(self.info.id, self.info.key)
def on_failed(reason) :
log.err('Failed to save device {0}. Reason: {1}.'.format(self.info, reason))
self.factory.device_save(self.info).addCallbacks(on_subscribe, on_failed)

def on_connection_failed(self, reason) :
pass

def on_closing_connection(self):
pass

def on_failure(self, device_id, reason):
pass

def do_short_command(self, finished, equipment = None, state = 0):
log.msg('Setting {0} equipment to {1}'.format(equipment, state))
if equipment == 'LED' :
if int(state) == 0 :
self.led.set_off()
else:
self.led.set_on()
# upon completion post the result back
self.factory.notify('equipment', {'state': state, 'equipment': 'LED'}, device_id = self.info.id, device_key = self.info.key)
finished.callback(devicehive.CommandResult('Completed'))

def on_command(self, device_id, command, finished):
# Expecting command as 'UpdateState' and parameters as {"equipment" : "LED", "state" : "0"}
if command.command == 'UpdateLedState' :
self.do_short_command(finished, **command.parameters)
else :
finished.errback()
# end do_command

def notify(self, notif, **params):
if self.connected :
self.factory(notif, params, device_id = self.info.id, device_key = self.info.key)
else :
self.notifs.append({'notification': notif, 'parameters': params})


#
# Temperature sensor wrapper. Gets temperature readings form file, parses them
# and notifies the services is the difference is greater than a certain threshold
#
class TempSensor(object):
def __init__(self, file_name):
self.file_name = file_name
self.last_temp = 0
self.last_good_temp = 0

# internal, get temperature readings from device and check CRC
def _get_temp(self):
with open(self.file_name) as f:
content = f.readlines()
for line in content:
# sometimes CRC is bad, so we will return last known good temp
if line.find('crc=')>=0 and line.find('NO')>=0:
return self.last_good_temp
p = line.find('t=')
if p >= 0:
self.last_good_temp = float(line[p+2:])/1000.0
return self.last_good_temp
return 0.0

# check temperature, if greater than threshold, notify
def get_temp(self, dev):
temp = self._get_temp()
if abs(temp - self.last_temp) > 0.2:
log.msg('Temperature {0} -> {1}'.format(self.last_temp, temp))
dev.notify('equipment', temperature = temp, equipment = "temp")
self.last_temp = temp

#
# Wrapper from LED connected to RasPi
#
class LedDevice(object):
def __init__(self, pin):
# We are using board PIN numbering (as opposed to chip's numbers)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(pin, GPIO.OUT)

def blink(self, count):
for i in range(count):
GPIO.output(_LED_PIN,True)
sleep(0.2)
GPIO.output(_LED_PIN,False)
sleep(0.2)

def set_on(self):
GPIO.output(_LED_PIN, True)

def set_off(self):
GPIO.output(_LED_PIN, False)

#
# main
#
if __name__ == '__main__' :
log.startLogging(sys.stdout)

led = LedDevice(_LED_PIN)
# Blink on start to ensure device is working
led.blink(3)

# create temp sensor and queue it to check for temperature in a separate thread
tempSensor = TempSensor(_W1_FILENAME)

# create a delegate to handle commands
device = RasPiApp(led, tempSensor)
led_factory = devicehive.auto.AutoFactory(device)
reactor.connectDeviceHive(_API_URL, led_factory)

# off we go!
reactor.run()

Using my API URL is sends off the data and on changing the temp it should update itself and notify me, this at the minute just records the 1st temp when the log is started and nothing more. The L.E.D on/off works fine as a consolation prize. 

 

 

Before i go through the logs and main errors, i wanted to post the working code of the thermal sensor using commands to manually update/refresh it (just incase any of you were thinking there's a fault with this): 

I was pinching the sensor supplying warmth and reloading the command, which you can see works well like that but not automatically? 

 

t= "temp in binary"

root@raspberrypi:/home/pi/devicehive/python/examples# cat /sys/bus/w1/devices/28-000004bc15aa/w1_slave
44 01 4b 46 7f ff 0c 10 a9 : crc=a9 YES
44 01 4b 46 7f ff 0c 10 a9 t=20250
root@raspberrypi:/home/pi/devicehive/python/examples# cat /sys/bus/w1/devices/28-000004bc15aa/w1_slave
6f 01 4b 46 7f ff 01 10 67 : crc=67 YES
6f 01 4b 46 7f ff 01 10 67 t=22937
root@raspberrypi:/home/pi/devicehive/python/examples# cat /sys/bus/w1/devices/28-000004bc15aa/w1_slave
85 01 4b 46 7f ff 0b 10 5f : crc=5f YES
85 01 4b 46 7f ff 0b 10 5f t=24312
root@raspberrypi:/home/pi/devicehive/python/examples# 

Now the error im getting when running raspi_led_thermo.py to log temps: 

root@raspberrypi:/home/pi/devicehive/python/examples# sudo python raspi_led_thermo.py
2013-06-23 13:39:03+0100 [-] Log opened.
2013-06-23 13:39:03+0100 [-] raspi_led_thermo.py:197: exceptions.RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
2013-06-23 13:39:04+0100 [-] Starting factory <devicehive.auto.AutoFactory instance at 0x13ead50>
2013-06-23 13:39:05+0100 [AutoProtocol,client] The call to "/info" api has finished successfully.
2013-06-23 13:39:05+0100 [AutoProtocol,client] on_apimeta
2013-06-23 13:39:05+0100 [AutoProtocol,client] WebSocket protocol has been selected. URL: http://nn1269.pg.devicehive.com:8010/; HOST: nn1269.pg.devicehive.com; PORT: 8010;
2013-06-23 13:39:05+0100 [AutoProtocol,client] Starting factory <devicehive.device.ws.WebSocketFactory instance at 0x17452d8>
2013-06-23 13:39:05+0100 [AutoProtocol,client] Stopping factory <devicehive.auto.AutoFactory instance at 0x13ead50>
2013-06-23 13:39:06+0100 [WebSocketDeviceHiveProtocol,client] Temperature 0 -> 20.187
2013-06-23 13:39:06+0100 [WebSocketDeviceHiveProtocol,client] Connected to devicehive server.
2013-06-23 13:39:06+0100 [WebSocketDeviceHiveProtocol,client] Sending websocket text frame. Payload: {"action": "notification/insert", "notification": {"notification": "equipment", "parameters": {"equipment": "temp", "temperature": 20.187}}, "deviceKey": "device-key", "deviceId": "9f33566e-1f8f-11e2-8979-c42c030dd6a5", "requestId": 1}
2013-06-23 13:39:06+0100 [WebSocketDeviceHiveProtocol,client] device_save <__main__.RasPiConfig object at 0x172ed70>
2013-06-23 13:39:06+0100 [WebSocketDeviceHiveProtocol,client] Sending websocket text frame. Payload: {"action": "device/save", "device": {"status": "Online", "name": "Device1", "equipment": [{"code": "LED", "type": "Controllable LED", "name": "LED"}, {"code": "temp", "type": "TempSensor", "name": "THERMO"}], "deviceClass": {"version": "1.0", "is_permanent": false, "name": "Class1"}, "key": "device-key", "network": {"name": "Netname", "key": "Netname", "description": "RasPi/Py LED/w1 sample"}}, "deviceKey": "device-key", "deviceId": "9f33566e-1f8f-11e2-8979-c42c030dd6a5", "requestId": 2}
2013-06-23 13:39:07+0100 [WebSocketDeviceHiveProtocol,client] Websocket frame (1) has been received. Frame data: {"action":"notification/insert","status":"success","requestId":1,"notification":{"id":65,"timestamp":"2013-06-23T12:39:07.094000"}}.
2013-06-23 13:39:07+0100 [WebSocketDeviceHiveProtocol,client] Websocket message has been received {"action":"notification/insert","status":"success","requestId":1,"notification":{"id":65,"timestamp":"2013-06-23T12:39:07.094000"}}.
2013-06-23 13:39:07+0100 [WebSocketDeviceHiveProtocol,client] Websocket frame (1) has been received. Frame data: {"action":"device/save","status":"success","requestId":2}.
2013-06-23 13:39:07+0100 [WebSocketDeviceHiveProtocol,client] Websocket message has been received {"action":"device/save","status":"success","requestId":2}.
2013-06-23 13:39:07+0100 [WebSocketDeviceHiveProtocol,client] Subscribe device 9f33566e-1f8f-11e2-8979-c42c030dd6a5.
2013-06-23 13:39:07+0100 [WebSocketDeviceHiveProtocol,client] Sending websocket text frame. Payload: {"action": "command/subscribe", "deviceKey": "device-key", "deviceId": "9f33566e-1f8f-11e2-8979-c42c030dd6a5", "requestId": 3}
2013-06-23 13:39:08+0100 [WebSocketDeviceHiveProtocol,client] Websocket frame (1) has been received. Frame data: {"action":"command/subscribe","status":"success","requestId":3}.
2013-06-23 13:39:08+0100 [WebSocketDeviceHiveProtocol,client] Websocket message has been received {"action":"command/subscribe","status":"success","requestId":3}.
2013-06-23 13:39:45+0100 [-] Temperature 20.187 -> 20.437
2013-06-23 13:39:45+0100 [-] Unhandled error in Deferred:
2013-06-23 13:39:45+0100 [-] Unhandled Error
    Traceback (most recent call last):
     File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1169, in run
     self.mainLoop()
     File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1178, in mainLoop
     self.runUntilCurrent()
     File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 800, in runUntilCurrent
     call.func(*call.args, **call.kw)
     File "/usr/lib/python2.7/dist-packages/twisted/internet/task.py", line 215, in __call__
     d = defer.maybeDeferred(self.f, *self.a, **self.kw)
    --- <exception caught here> ---
     File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 134, in maybeDeferred
     result = f(*args, **kw)
     File "raspi_led_thermo.py", line 187, in get_temp
     dev.notify('equipment', temperature = temp, equipment = "temp")
     File "raspi_led_thermo.py", line 153, in notify
     self.factory(AutoFactory, notif, params, device_id = self.info.id, device_key = self.info.key)
    exceptions.NameError: global name 'AutoFactory' is not defined
    
^C2013-06-23 13:40:35+0100 [-] Received SIGINT, shutting down.
2013-06-23 13:40:35+0100 [WebSocketDeviceHiveProtocol,client] Stopping factory <devicehive.device.ws.WebSocketFactory instance at 0x17452d8>
2013-06-23 13:40:35+0100 [-] Main loop terminated.
root@raspberrypi:/home/pi/devicehive/python/examples# sudo python raspi_led_thermo.py
2013-06-23 16:18:52+0100 [-] Log opened.
2013-06-23 16:18:52+0100 [-] raspi_led_thermo.py:197: exceptions.RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
2013-06-23 16:18:54+0100 [-] Starting factory <devicehive.auto.AutoFactory instance at 0xddbd50>
2013-06-23 16:18:54+0100 [AutoProtocol,client] The call to "/info" api has finished successfully.
2013-06-23 16:18:54+0100 [AutoProtocol,client] on_apimeta
2013-06-23 16:18:54+0100 [AutoProtocol,client] WebSocket protocol has been selected. URL: http://nn1269.pg.devicehive.com:8010/; HOST: nn1269.pg.devicehive.com; PORT: 8010;
2013-06-23 16:18:54+0100 [AutoProtocol,client] Starting factory <devicehive.device.ws.WebSocketFactory instance at 0x11342d8>
2013-06-23 16:18:54+0100 [AutoProtocol,client] Stopping factory <devicehive.auto.AutoFactory instance at 0xddbd50>
2013-06-23 16:18:56+0100 [WebSocketDeviceHiveProtocol,client] Temperature 0 -> 20.437
2013-06-23 16:18:56+0100 [WebSocketDeviceHiveProtocol,client] Connected to devicehive server.
2013-06-23 16:18:56+0100 [WebSocketDeviceHiveProtocol,client] Sending websocket text frame. Payload: {"action": "notification/insert", "notification": {"notification": "equipment", "parameters": {"equipment": "temp", "temperature": 20.437}}, "deviceKey": "device-key", "deviceId": "9f33566e-1f8f-11e2-8979-c42c030dd6a5", "requestId": 1}
2013-06-23 16:18:56+0100 [WebSocketDeviceHiveProtocol,client] device_save <__main__.RasPiConfig object at 0x111dd70>
2013-06-23 16:18:56+0100 [WebSocketDeviceHiveProtocol,client] Sending websocket text frame. Payload: {"action": "device/save", "device": {"status": "Online", "name": "Device1", "equipment": [{"code": "LED", "type": "Controllable LED", "name": "LED"}, {"code": "temp", "type": "TempSensor", "name": "THERMO"}], "deviceClass": {"version": "1.0", "is_permanent": false, "name": "Class1"}, "key": "device-key", "network": {"name": "Netname", "key": "Netname", "description": "RasPi/Py LED/w1 sample"}}, "deviceKey": "device-key", "deviceId": "9f33566e-1f8f-11e2-8979-c42c030dd6a5", "requestId": 2}
2013-06-23 16:18:57+0100 [WebSocketDeviceHiveProtocol,client] Websocket frame (1) has been received. Frame data: {"action":"notification/insert","status":"success","requestId":1,"notification":{"id":67,"timestamp":"2013-06-23T15:18:56.722000"}}.
2013-06-23 16:18:57+0100 [WebSocketDeviceHiveProtocol,client] Websocket message has been received {"action":"notification/insert","status":"success","requestId":1,"notification":{"id":67,"timestamp":"2013-06-23T15:18:56.722000"}}.
2013-06-23 16:18:57+0100 [WebSocketDeviceHiveProtocol,client] Websocket frame (1) has been received. Frame data: {"action":"device/save","status":"success","requestId":2}.
2013-06-23 16:18:57+0100 [WebSocketDeviceHiveProtocol,client] Websocket message has been received {"action":"device/save","status":"success","requestId":2}.
2013-06-23 16:18:57+0100 [WebSocketDeviceHiveProtocol,client] Subscribe device 9f33566e-1f8f-11e2-8979-c42c030dd6a5.
2013-06-23 16:18:57+0100 [WebSocketDeviceHiveProtocol,client] Sending websocket text frame. Payload: {"action": "command/subscribe", "deviceKey": "device-key", "deviceId": "9f33566e-1f8f-11e2-8979-c42c030dd6a5", "requestId": 3}
2013-06-23 16:18:58+0100 [WebSocketDeviceHiveProtocol,client] Websocket frame (1) has been received. Frame data: {"action":"command/subscribe","status":"success","requestId":3}.
2013-06-23 16:18:58+0100 [WebSocketDeviceHiveProtocol,client] Websocket message has been received {"action":"command/subscribe","status":"success","requestId":3}.
2013-06-23 16:19:22+0100 [-] Temperature 20.437 -> 20.687
2013-06-23 16:19:22+0100 [-] Unhandled error in Deferred:
2013-06-23 16:19:22+0100 [-] Unhandled Error
    Traceback (most recent call last):
     File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1169, in run
     self.mainLoop()
     File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1178, in mainLoop
     self.runUntilCurrent()
     File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 800, in runUntilCurrent
     call.func(*call.args, **call.kw)
     File "/usr/lib/python2.7/dist-packages/twisted/internet/task.py", line 215, in __call__
     d = defer.maybeDeferred(self.f, *self.a, **self.kw)
    --- <exception caught here> ---
     File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 134, in maybeDeferred
     result = f(*args, **kw)
     File "raspi_led_thermo.py", line 187, in get_temp
     dev.notify('equipment', temperature = temp, equipment = "temp")
     File "raspi_led_thermo.py", line 153, in notify
     self.factory(notif, params, device_id = self.info.id, device_key = self.info.key)
    exceptions.AttributeError: AutoFactory instance has no __call__ method

It has no call method. I tried to add AutoFactory to call it in: notify self.factory but then it said that it wasn't defined, couldn't see correctly where to define AutoFactory so i revoked those changes. I need some help completing this as im no expert i just want a temp sensor for my fish tank. Could somebody tell me how to change this file so it works right please? 

 

If i have missed something that might help, please let me know. I have tried to include what i think it needed to resolve the issue. 

 
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.