Lora packet data is encoded as hex string but decoding to ASCII is showing nonsense - mqtt

I am using 2 LHT65N sensors, a Wisgate Edge Lite 2 Gateway, forwarding the payload to a Mosquitto broker, and to display data I am using mqtt.js.
I am receiving packets from the sensors and the data I get is a hex string, but when I am decoding it to plaintext I get no useful data.
So this is the object I get:
{
"applicationID": "1",
"applicationName": "ptxd_temp_humid",
"devEUI": "a84041a777864399",
"deviceName": "sensor_uphill",
"timestamp": 1674051438,
"fCnt": 179,
"fPort": 2,
"data": "CBCF09200203017FFF7FFF",
"data_encode": "hexstring",
"adr": true,
"rxInfo": [
{
"gatewayID": "ac1f09fffe08bf79",
"loRaSNR": 0,
"rssi": -59,
"location": {
"latitude": 0,
"longitude": 0,
"altitude": 0
}
}
],
"txInfo": {
"frequency": 868800000,
"dr": 7
}
You can see that the packet data is encoded as a hex string.
I am using this method:
decoder(bytes: any) {
var batt_v = ((bytes[0]<<8 | bytes[1]) & 0x3FFF)/1000;
var temp_int = ((bytes[2]<<24>>16 | bytes[3])/100).toFixed(2);
var temp_ext = ((bytes[7]<<24>>16 | bytes[8])/100).toFixed(2);
var hum_int = ((bytes[4]<<8 | bytes[5])/10).toFixed(1);
var ext_sen =
{
"0":"No external sensor",
"1":"Temperature Sensor",
}[bytes[6]&0x7F];
return {
Ext_sensor: ext_sen,
BatV: batt_v,
TempC_SHT: temp_int,
Hum_SHT: hum_int,
TempC_DS: temp_ext,
};
To achieve this:
{
"BatV": 1,
"TempC_SHT": "27.56",
"Hum_SHT": "50.6",
"TempC_DS": "25.23"
}
But I get:
{
"BatV": 0,
"TempC_SHT": "0.00",
"Hum_SHT": "0.9",
"TempC_DS": "0.00"
}
I feel that the problem is the gateway. The system log of the gateway is already receiving the encoded data. I tried a hex converter and also the payload formatter of the LHT65N but neither gave me the correct data. I also triple checked the API key, but it is correct.
Is there any configuration that I have to do to receive the correct data?
Solution
I was passing the wrong type into the method. I was confused because I compared my data to others and mine appeared to be too short so I was pretty confused. I am decoding my hexstring to a UInt8Array now and it's working as expected.
client.on('message', (topic, message: Buffer, packet:
mqtt.IPublishPacket) => {
let payload = JSON.parse(message.toString())
console.log(Buffer.from(payload.data, 'hex'))
this.data = this.Decoder(Buffer.from(payload.data, 'hex'));
console.log(this.data)
})

The hex string "data": "CBCF09200203017FFF7FFF" that's received decodes properly with the code you showed. Running it against the hex string, I get:
{
Ext_sensor: 'Temperature Sensor',
BatV: 3.023,
TempC_SHT: '23.36',
Hum_SHT: '51.5',
TempC_DS: '327.67'
}
So that seems to be working. If this arrives via the gateway all the way to the MQTT broker, the problem isn't with the gateway then. It is with either the broker, or the decoder itself, but then again, as I said, the decoder's code seems to be working. It looks like you are getting wrong data, somewhere between it is sent to the decoder and the time it is returned to you.

Related

Thingsboard Upload Converter with multiple timestamps

My device takes measuremets more often than it communicates with MQTT broker, so there can be more than one timestamb in each message, like this:
my/device/telemetry 1651396728000:22,13;1651400328000:25,10;...so on
I want to use built-in Thingsboard MQTT Integration with my custom Upload Converter, but I can't find proper format for result object with multiple timestamps in it (how it was in Gateway Telemetry API)
The output of your data converter should be an array like this:
var result = [
{
"deviceName": "88888888",
"deviceType": "tracker",
"attributes": {
"att1": "val1",
},
"telemetry": {
"ts": 1652738915000,
"values": {
"blah": "blooo",
"External Voltage": 12812
}
}
},
{same},
{similar}
]

Can't place GraphQL custom type as a Postman variable

Has anyone had luck with placing a GraphQL custom type argument as a Postman or Graphql variable? I'm kinda spinning in circles right now, I hope a fresh pair of eyes could point me in the right direction.
What I'm trying to do is to send a mutation request using Postman. The problem I'm having is that the method I'm calling is taking a custom type as an argument. Placing the content of that variable as GraphQL variable or Postman variable is giving me a headache. I can't embedd pictures yet, so here are the links (they are safe).
Schema
This custom type is a JSON-like structure, consisting of two enums and a set of primitive types (strings, ints...). I can screenshot the entire thing but basically that's it: two enums followed by strings, ints...
Custom type definition
What I've tried so far:
Simply hardcoding the request in Postman works but I wish to send multiple requests with varying data
Placing it in a GraphQL variable results in error message
{
"errors": [
{
"message": "Bad request - invalid request body.",
"locations": []
}
],
"data": null
}
Placing the custom type content as a Postman environment variable works, but I'm getting a syntax error (although the request passes...).
Request body is below. Hardcoding it and using a Postman variable produces the same request body, apart from the syntax error.
query: "mutation {
createApplication(request: {
applicationKind: NEW_ISSUANCE,
documentKind: REGULAR_PASSPORT,
personalData: {
timestamp: null,
firstname: "NAME",
lastname: "LASTNAME",
middlename: "MIDDLENAME",
dateOfBirth: "2011-09-28",
citizenshipCountryCode: "USA",
gender: MALE,
personalNumber: "3344",
placeOfBirth: "CHICAGO",
municipalityOfBirth: "SOUTH",
countryCodeOfBirth: "USA"},
addressData:{
street: "WEST",
municipality: "EAST",
place: "CHICAGO",
country: {
code: "USA",
name: null
},
entrance: "б",
flat: "13",
number: "35"}
})
{
__typename
... on AsyncTaskStatus {
taskID
state
payload {
... on ApplicationUpdated {
applicationID
applicationNumber
__typename
}
__typename
}
__typename
}
... on Error {
...errorData
__typename
}
}
}
fragment errorData on Error {
__typename
code
message
}"
Postman variable with a squiggly line
I'm spinning in circles right now. Has anyone had any luck with Postman requests of this kind?
I can post more info, screenshots...just let me know. I'll be watching this topic closely and provide feedback.
Thank you for your time.
please add a the variable in variable section as :
{
"request": {{request}}
}
and then refer this in your query as
$request

Twilio and Sendgrid - Incoming SMS

Current we send one-way SMS via MS Flow and Twilio which works fine. I have been exploring how to handle incoming SMS, so I followed a guide and managed to utilise Sendgrid to forward incoming SMS to my e-mail address which also works.
However, I am looking to have the original sender receive the SMS via e-mail. I can give each staff member their own phone number which would define each individual but I need a way of Twilio or Sendgrid doing a lookup prior to sending the reply e-mail so it knows where to send it i.e.
User 1 = 01234455678,
User 2 = 01234543245,
User 3 = 06546546445,...etc.
I guess I could re-create the same process for each number but it would require lots of Twilio Functions and Variables which doesn't seem like a great way to accomplish this?
Sorry, I a not much of a coder and try to use on-line guides and forums where I can.
Many Thanks,
JP
You can try something like this, hosting the mapping on Twilio Assets as a Private asset but you could also pull this information into Studio via the HTTP Request Widget if you hosted it on an external server (a bit more advanced). In my case I called my file mapping.json which has the format:
[
{
"name": "John Doe",
"phone": "+14075551212",
"email": "jdoe#example.com"
},
{
"name": "Susan Doe",
"phone": "+19545551212",
"email": "sdoe#example.com"
},
{
"name": "Nadia Doe",
"phone": "+14705551212",
"email": "ndoe#example.com"
},
{
"name": "Carl Doe",
"phone": "+18025551212",
"email": "cdoe#example.com"
}
]
Then you would use the Run Function widget and send in 3 key:value pairs (Function Parameters):
From - {{trigger.message.From}}
To - {{trigger.message.To}}
Body - {{trigger.message.Body}}
Your Twilio Function would then consume these parameters and the contents of the private asset to handle the mapping. Make sure to configure your Twilio Functions environment with the Sendgrid NPM package, #sendgrid/mail version 7.0.1 and you configure the two Sendgrid specific environmental variables below with their respective values (accessed via the context object in the JavaScript):
SENDGRID_API_KEY
FROM_EMAIL_ADDRESS
const fs = require('fs');
const sgMail = require('#sendgrid/mail');
exports.handler = function(context, event, callback) {
let from = event.From;
let to = event.To;
let body = event.Body;
let fileName = 'mapping.json';
let file = Runtime.getAssets()[fileName].path;
let text = fs.readFileSync(file);
let mappings = JSON.parse(text);
// Filter array to match to number
let result = mappings.filter(record => record.phone === to);
if (result.length) {
sgMail.setApiKey(context.SENDGRID_API_KEY);
// Define message params
const msg = {
to: result[0].email,
from: context.FROM_EMAIL_ADDRESS,
text: body,
subject: `New SMS from: ${from}`,
};
// Send message
sgMail.send(msg)
.then(response => {
console.log("Success.");
callback();
})
.catch(err => {
console.log("Not Success.");
callback(err);
});
} else {
console.log("** NO MATCH **");
callback();
}
};
Let me know how it goes.

Automl image prediction problems

I get different results when using a model to get image annotation predictions from web UI and from API. Specifically, using the web UI I actually get predictions, but using the API I get nothing - just empty output.
It's this one that gives nothing using the API: https://cloud.google.com/vision/automl/docs/predict#automl-nl-example-cli
Specifically, the return value is {} - an empty JS object. So, the call goes through just fine, there's just no output.
Any hints as to how to debug the issue?
By default only results with prediction score > 0.5 are returned by the API.
To get all predictions you will need to provide extra argument 'score_threshold' to predict request:
For the REST API:
{
"payload": {
"image": {
"imageBytes": "YOUR_IMAGE_BYTES"
},
"params": { "score_threshold": "0.0" },
}
}
For the python call:
payload = {'image': {'image_bytes': content }, "params": { "score_threshold": "0.0" }}
With this argument all predictions will be returned. The predictions will be ordered by the 'score'.
Hope that helps,
That doesn't work, at least at the moment.
Instead the params need to go at the same level as the payload. E.g.:
{
"payload": {
"image": {
"imageBytes": "YOUR_IMAGE_BYTES"
}
},
"params": { "score_threshold": "0.0" },
}

Cell triangulation on BlackBerry

Any ideas about how to do cell triangulation for Blackberry and J2ME phones? I know how to get the cell id but I couldn't do triangulation.
If you can do an HTTP Post to an arbitray website, you can use Google's geolocation api.
Simply POST data in the following JSON format to https://www.google.com/loc/json.
See the above link on how to add more information to your json from wifi etc. to greatly increase the accuracy of the result. And pay special attention to the mobile country code, getting it is not obvious.
{
"version": "1.1.0",
"cell_towers": [
{
"cell_id": "42",
"location_area_code": 415,
"mobile_country_code": 310,
"mobile_network_code.": 410,
"age": 0,
"signal_strength": -60,
"timing_advance": 5555
},
{
"cell_id": "88",
"location_area_code": 415,
"mobile_country_code": 310,
"mobile_network_code": 580,
"age": 0,
"signal_strength": -70,
"timing_advance": 7777
}
]
}
This will return you Google's estimate of the latitude/longitude on your location, along with accuracy and optionally a geocoded address. You can test it quickly e.g. with the Chrome extension called REST Console.
However, it seems that the Blackberry API only provides info on the currently connected cell, not other visible but unregistered cells. In this situation cannot do triangulation, as you (unsuprisingly) need three points to triangulate! However, a less accurate radial estimate of location is still possible.
You can still use the Google API for this, by providing only one tower, or you can use the Ericsson API if you choose. You might want to test with both and compare the accuracy. The Ericcson API is a similar JSON api to Google's, but only expects a single cell as input. A tutorial is available, but it boils down to a JSON request like this:
StringBuffer url = new StringBuffer();
url.append("http://cellid.labs.ericsson.net/json/lookup");
url.append("?cellid=").append(cell.getCellId());
url.append("&mnc=").append(cell.getMnc());
url.append("&mcc=").append(cell.getMcc());
url.append("&lac=").append(cell.getLac());
url.append("&key=").append(API_KEY);
try {
byte[] data = getHttp(url.toString());
if(data!=null) {
JSONObject o = new JSONObject(new String(data));
JSONObject pos = o.getJSONObject("position");
this.longitude = pos.getDouble("longitude");
this.latitude = pos.getDouble("latitude");
this.accuracy = pos.getDouble("accuracy");
this.cellName = pos.optString("name");
}
} catch (IOException e) {
e.printStackTrace();
}

Resources