A Decoder for the Zane Ztrack

Continuing the discussion from Decode: How NOT hex2integer using zTrack by Zane:

I am pretty sure this is not perfect, but it works well with my zTrack Mini (at least when the zTrack mini is behaving!)

function Decoder(bytes, port) {
  // Decode an uplink message from a buffer
  // (array) of bytes to an object of fields.
 
  // port = 99;

var temperature, temp_1, temp_2, bat_10, bat_1, battery, neg;
 
 if (port == 207 || port == 205) {
  temperature = ((bytes[0] & 15) * 10);
  temp_1 = (bytes[1] >> 4);
  temp_2 = (bytes[1] & 15);
  temperature = (temperature + temp_1) + (temp_2/10);
 
  bat_10 = (bytes[2]>> 4)*10;
  bat_1 = (bytes[2] & 15);
  battery = bat_10 + bat_1;
 
  neg = (bytes[0] >> 4);
  if (neg !== 0) temperature = -1 * temperature;

  return {
    port: port,
    temperature : temperature,
    battery : battery,
    composite : "bat:"+battery.toString() + ", tmp:" + temperature.toString() + ", port:" + port.toString()
  }
}
else if (port == 204 || port == 99) {
  
  var latitude = (bytes[0] << 16) | (bytes[1] <<8) | bytes[2];
  latitude = (latitude/8388606) * 90;
  
  if (latitude > 180) {latitude = latitude - 360 }
  
  var longitude = (bytes[3] << 16) | (bytes[4] << 8) | bytes[5];
  longitude = (longitude/8388606) * 180;
  
  if (longitude > 180) {longitude = longitude - 360}
  
  var altitude = (bytes[6] << 8) | bytes[7];
  
  var satellites = bytes[8];
  
  temperature = ((bytes[9] & 15) * 10);
  temp_1 = (bytes[10] >> 4);
  temp_2 = (bytes[10] & 15);
  temperature = (temperature + temp_1) + (temp_2/10);
 
  bat_10 = (bytes[11]>> 4)*10;
  bat_1 = (bytes[11] & 15);
  battery = bat_10 + bat_1;
 
  neg = (bytes[9] >> 4);
  if (neg !== 0) temperature = -1 * temperature;
  
  return {

  port: port,
  latitude : latitude,
  longitude : longitude,
  altitude : altitude,
  sats : satellites,
  temperature: temperature,
  battery : battery,
  composite : "bat:"+battery.toString() 
  + ", tmp:" + temperature.toString()
  + ", lat:" + latitude.toString() 
  + ", long:" + longitude.toString()
  + ", alt:" + altitude.toString()
  + ", sats:" + satellites.toString()
  + ", port:" + port.toString()
  }
  
  
  }
else if (port == 200 || port == 208 || port == 99) {
	return {port: port, composite : "200 or 208 message"}
}
else { return {port: port, composite : "Something Odd"} }

}
1 Like
var bytesToInt = function (bytes) {
    var i = 0;
    for (var x = 0; x < bytes.length; x++) {
        i |= +(bytes[x] << (x * 8));
    }
    return i;
};

Source paxcounter

Beware that this does not take negative values into account, unless you pass exactly 4 bytes. As JavaScript’s bitwise operators always assume 32 bits, fewer number of bytes need sign extension to handle negative values.

(And as an aside, I don’t think the unary plus operator in +(bytes[x] << (x * 8)) has any effect?)

Source lora-serialization? :wink: (But indeed, you nicely give credit in the source code. :+1:)

2 Likes
1 Like

Great, thank you bluesensing1.

I was looking for exactly something like this.

Maybe you can help me on the next step.

I want to connect my ztrack tracker with cayenne my devices.
Do i have to let the payload in my ttn setup like in the link from you or change it to “Cayenne LPP”?

Or is there a better way to see the coordinates from ztrack tracker on a map (but not ttn mapper)?

Best regards

Not sure what’s the reason for all the versions in that document, but it seems none supports negative values for latitude and longitude:

decode.lat = b[0]<<16 | b[1]<<8 | b[2];
decode.lng = b[3]<<16 | b[4]<<8 | b[5];

To support negative values, use:

// Sign-extend to 32 bits for support of negative values, by shifting 8 bits
// too far to the left, followed by a sign-propagating right shift:
decode.lat = b[0]<<24>>8 | b[1]<<8 | b[2];
decode.lng = b[3]<<24>>8 | b[4]<<8 | b[5];

(See Decrypting messages for dummies - #4 by arjanvanb)

If the device does not use Cayenne LPP, then you cannot use TTN Console’s Payload Formats to convert the payload into that format:

1 Like

not all people using IoT are engineers…

1 Like

Hi Guys! Testing a Zane zcar currently - which decoder works with Cayenne? I see they have the sensor listed. Currently not recognising the data format - nothing appearing (integration working as I have many other sensors linked)

Any help much appreciated!

Dean

Like noted in my previous post, you cannot use a Decoder in TTN Console to convert a random payload into a Cayenne-compatible payload. Instead, the device must generate such payload, and then TTN Console must only be configured to use the Cayenne Integration.

1 Like

Zane now have new firmware which give Cayenne payload format… Testing currently. Think there are some bugs however! GPS accuracy 20 mile radius :roll_eyes:

I’d assume that the GPS accuracy is not related to the payload format?

Possibly. If I switch the node back to the ZANE format accuracy is 100% from the device.

1 Like

I’ve been testing one of their new Ztrack Pro devices … and have a decoder for their standard format. They’ve now removed number of satellites from the payload but the rest is there. I am getting a mixed bag of results and they have been sending firmware updates to attempt to resolve.

Lat/Long GPS accurate. Altitude incorrect (wildly). Battery %age is odd. It’s consistent, but will never get anywhere near 100% even when the device is fully charged. I get different battery %ages in different payloads that are adjacent - e.g. a keepalive will say 70% and then immediately following I might get 60% in a longer device moved payload. Temperature seems accurate too. But I think there is definitely some correlation between temperature and battery %age.

Would be great if they could nail these little niggles as the form factor is fantastic.

How are you getting access to the Cayenne payloads?

1 Like

Hi!

They have resolved all the issues for my Zane Zcar, using Cayenne LPP payload now.

Which Firmware version are you running? With V1.5 you need to send a Downlink command 01 to Port 104 to enable Cayenne LPP Format.

1 Like