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"} }

}
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:)

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:

not all people using IoT are engineers…

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.

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.

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?

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.