andy_b_1502 Posted June 23, 2013 Share Posted June 23, 2013 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): 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# 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" 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. Quote Link to comment Share on other sites More sharing options...
andy_b_1502 Posted June 23, 2013 Author Share Posted June 23, 2013 I found the following URL: http://twistedmatrix.com/documents/13.0.0/api/twisted.internet.protocol.ReconnectingClientFactory.html Un-fortunately it doesn't mean much to me. It does state to make sure it starts but that Factory and not AutoFactory: Method doStart Make sure startFactory is called. Method doStop Make sure stopFactory is called. Quote Link to comment Share on other sites More sharing options...
andy_b_1502 Posted June 25, 2013 Author Share Posted June 25, 2013 Just found this: http://docs.python.org/2/library/sqlite3.html To use the module, you must first create a Connection object that represents the database. Here the data will be stored in the example.db file: Its stops and starts here: 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> Could somebody point me in the right direction to create the connection object? Or am i barking up the wrong proccess-tree?? Quote Link to comment Share on other sites More sharing options...
Kojebric Posted October 18, 2013 Share Posted October 18, 2013 There is a bug in line 153: There was an error in the sample code:if self.connected :self.factory(notif, params, device_id = self.info.id, device_key = self.info.key) The changed version:if self.connected :self.factory.notify(notif, params, device_id = self.info.id, device_key = self.info.key) solution is described in git:https://github.com/devicehive/devicehive-python/pull/2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.