Micropython TTN Cayenne integration

I have a LoPy chip from pycom and I am trying to integrate a temperatur/moisture sensor with Cayenne. One option is to use Cayenne MQTT directly from my sensor, but I would really like to go through TTN. I can not figure out how to do this.

  1. My first attempt was to use the TTN payload decoder to create a Cayenne Low Power Payload (LPP), but this does not work.

function Decoder(bytes, port) {
return “03 67 01 10 05 67 00 FF” // Cayenne Low Power Payload (LPP
}

  1. Tried to create a Cayenne Low Power Payload in the micropython device, but TTN does some translation on the payload that I do not understand.

packet = ‘03 67 01 10 05 67 00 FF’.replace(’ ', ‘’).decode(‘hex’)
s.send(packet)

Does anyone have any idea of how I can get this done, TTN and Cayenne works great with Arduino.

Did you follow the instructions at https://www.thethingsnetwork.org/docs/applications/Cayenne ?

Including: did you select the correct Payload Format, and enable the Integration?

1 Like

My mistakes

  1. Remember to change the Payload Format from Custom to Cayenne LLP for the application

  2. Send a bytearray from the LoPy containing Cayenne LLP values something like this

packet = bytearray([0x03, 0x67, 0x01, 0x10, 0x05, 0x67, 0x00, 0xFF]) # Two temperature sensors
s.send(packet)

Now it works like a charm with values ticking into Cayenne as expected, thanks @arjanvanb

1 Like

Can you share the full working code. I also experience problems with using cayenne lpp wiith LoPy. I tried to format the data as you suggested but I still dont get anything in cayenne.

Here is where I create Cayenne LLP payload. Probably not the most elegant way of doing it, but it works.

Hope it helps you out @miroslavpetrov

def tohex(val, nbits):
    return hex((val + (1 << nbits)) % (1 << nbits))

removed_decimals_lat = int(m_lat * 10000) # Remove decimals
removed_decimals_long = int(m_long * 10000) # Remove decimals

lat = '{:>06s}'.format(tohex(removed_decimals_lat, 24)[2:]) 
longi = '{:>06s}'.format(tohex(removed_decimals_long, 24)[2:])

packet = bytearray([0x01, 0x88, int(lat[0:2], 16), int(lat[2:4], 16), int(lat[4:6], 16), int(longi[0:2], 16), int(longi[2:4], 16), int(longi[4:6], 16), 0x00, 0x03, 0xe8]) 

s.send(packet)
1 Like

I was also struggling getting cayenne lpp work on the Lopy but after some trial and error I managed to get something working and created a lib to make it easier to use. The interface is pretty much the same as CayenneLPP in ttn’s arduino lib.

1 Like

Hi,

try this…

1 Like

Hi! I am new to using the LoPy so not sure if I have done it right. But after downloading the library and pasting it in the library directory of pymakr on atom I am still unable to import this module. I must have done it wrong. Can I just check where exactly I should paste the .py file? I tried finding the directory where all the other libraries I could import (eg binascii library) were located but to no avail. The picture below shows the directory at which I saved the file under. Thanks in advance!

directory

The folder sounds correct, did you check that the file actually got synced to the LoPy?
(for example by connecting to the LoPy using FTP and having a look in the folder).

if the file is there, you should be able to use the example code listed on the github page:

from CayenneLPP import CayenneLPP

var cayenne = new CayenneLPP();
cayenne.add_temperature(1, 23.54);

# ... lora setup ...
s.send(cayenne.get_buffer())

If that fails, what error are you getting? (and when?)

Hi Pierre. Thanks for the reply! How do we connect the LoPy using FTP? I tried to do that following this link https://docs.pycom.io/chapter/toolsandfeatures/FTP.html but it says “connection timed out” when I type the IP address in. The error message I got for the CayenneLPP was “ImportError: no module named ‘CayenneLPP’”.

You’ll have to make the LoPy connect to WiFi first. That you would usually do in boot.py. If you click on the link, you’ll get the one that I by default use. Note that you’ll also need lib\config.py also.

I am using OTAA not ABP. Maybe it might be easier for me to adapt some function from the library and put it in my python code. I just need to transfer temperature data so I don’t need the other functions. When I tried reading the code in the library, there was a variable called “self” do you know what that means? Thanks!

Not much difference using OTAA: boot.py and config.py

But to answer your question: “self” in the library is not a variable. In line 30 of the library file you can see:
class CayenneLPP:
That indicates the start of the class definition called CayenneLPP.
All fuctions below that are functions for that class.
Instead of variables, within a class you work with properties. For example:
self.buffer = bytearray() in line 40 defines a property buffer for the class CayenneLPP and set the type to bytearray(). The use of “self” in this case means “of the class that you are currently designing”

So in your main.py file, you import the code for the library using
from CayenneLPP import CayenneLPP
and then you instantiate an object cayenne that has all the functions and properties defined in the class CayenneLPP using the line:
var cayenne = new CayenneLPP();

So with the line
cayenne.add_temperature(1, 23.54);
you call the internal function add_temperature() defined in line 50. That function then calls the function _add_to_buffer defined in line 157 which adds the provided info to the buffer property from line 40.

But if you don’t want to use the library, you might be better of using the code provided by @cristianhumelnicu

(now I’m going to duck for all the comments by people that explain OO programming better than I can)

1 Like

Oh I see! That makes sense. I was trying to find where “self” was being initialized/define and got really confused before that.

The link you provided is definitely a better alternative. Thank you so much!