So I have the two pieces working, the MQTT sample code can post bogus data to the dashboard (Example-01-SendData.py from the Cayenne GitHub page) and I can read the temperature off the I2C connected Atlas Scientific PT-1000 ultra low temp probe. However, I’m trying to slim it down and combine the two and I can read off the PT-1000 every 5 seconds just fine, but the posting of data to the MQTT gateway doesn’t seem to want to play. It thinks it’s posting for about a minute with the device “online” but then goes offline without ever displaying any data.
Here’s the Python code:
#!/usr/bin/env python import cayenne.client import time import io # used to create file streams import fcntl # used to access I2C parameters like addresses # Cayenne authentication info. This should be obtained from the Cayenne Dashboard. # setup for Brian Chee Cayenne account MQTT_USERNAME = "myusername" MQTT_PASSWORD = "mypassword" MQTT_CLIENT_ID = "myclientID" delay=5 client = cayenne.client.CayenneMQTTClient() client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID) # For a secure connection use port 8883 when calling client.begin: # client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883) class atlas_i2c: long_timeout = 1.5 # the timeout needed to query readings & calibrations short_timeout = .5 # timeout for regular commands default_bus = 1 # the default bus for I2C on the newer Raspberry Pis, # certain older boards use bus 0 default_address = 102 # the default address for the Temperature sensor def __init__(self, address=default_address, bus=default_bus): # open two file streams, one for reading and one for writing # the specific I2C channel is selected with bus # it is usually 1, except for older revisions where its 0 # wb and rb indicate binary read and write self.file_read = io.open("/dev/i2c-" + str(bus), "rb", buffering=0) self.file_write = io.open("/dev/i2c-" + str(bus), "wb", buffering=0) # initializes I2C to either a user specified or default address self.set_i2c_address(address) def set_i2c_address(self, addr): # set the I2C communications to the slave specified by the address # The commands for I2C dev using the ioctl functions are specified in # the i2c-dev.h file from i2c-tools I2C_SLAVE = 0x703 fcntl.ioctl(self.file_read, I2C_SLAVE, addr) fcntl.ioctl(self.file_write, I2C_SLAVE, addr) def write(self, string): # appends the null character and sends the string over I2C string += "\00" self.file_write.write(string) def read(self, num_of_bytes=31): # reads a specified number of bytes from I2C, # then parses and displays the result res = self.file_read.read(num_of_bytes) # read from the board # remove the null characters to get the response response = filter(lambda x: x != '\x00', res) if(ord(response) == 1): # if the response isnt an error # change MSB to 0 for all received characters except the first # and get a list of characters char_list = map(lambda x: chr(ord(x) & ~0x80), list(response[1:])) # NOTE: having to change the MSB to 0 is a glitch in the # raspberry pi, and you shouldn't have to do this! # convert the char list to a string and returns it return "Command succeeded " + ''.join(char_list) else: return "Error " + str(ord(response)) def query(self, string): # write a command to the board, wait the correct timeout, # and read the response self.write(string) # the read and calibration commands require a longer timeout if((string.upper().startswith("R")) or (string.upper().startswith("CAL"))): time.sleep(self.long_timeout) elif((string.upper().startswith("SLEEP"))): return "sleep mode" else: time.sleep(self.short_timeout) return self.read() def close(self): self.file_read.close() self.file_write.close() def main(): device = atlas_i2c(102) # creates the I2C port object, specify the address # or bus if necessary i=0 timestamp = 0 # put this in just to push some data to the dashboard, but it never arrives client.celsiusWrite(1,22.345) while True: i= device.query("R") client.celsiusWrite(1,i) print "My Temp in C: "+i time.sleep(delay) if __name__ == '__main__': main()