I would like to fill label and description fields without any manual work.
Or what is the best way for TB to fill those fields?
Label & Description in device
You should do it in the rulechain.
You should have in you rulechain tab the Root rule chain, add a script transformation node after the message filter one (you need to connect the two nodes with an Entity created tag if you want it to be done on every device).
to access the label and the description in the node you need "msg.additionalInfo.description" and "msg.label"
add the nodes to he existing root rule chain, and add an originator filter for device if you only want this to be done on devices
You can fill the Label via Data Converter ("deviceLabel" or "assetLabel" key). Description is not supported, yet.
Support was added in version 3.3.2:
https://thingsboard.io/docs/pe/reference/releases/#v332-november-11-2021
// Result object with device/asset attributes/telemetry data
var result = {
// Use deviceName and deviceType or assetName and assetType, but not both.
deviceName: 'Name',
deviceType: "Type",
deviceLabel: "Label",
attributes: {},
telemetry: {}
};
Related
I am testing some network packets of my Organisation's product. We already have custom plugins. I am trying to add some some more fields into those existing plugins (like conversion of 2 byte code to a string and assign it to a field)
Thankyou in advance for reading my query.
--edit
Wireshark version : 2.4.5 (organization's plugins dont work on latest wireshark application)
--edit
Problem statement:
I am able to add field and show value, but fieldname is not displayed as defined.
I cannot share the entire .lua file but i will try to explain What i did:
Below is the image where I have a field aprint.type. this is a two byte field. In .lua file, for display purpose it is appended with corresponding description using a custom function int_to_enum.
I want to add one more proto field aprint.typetext which will show the text.
What I did:
Added a protofield f_apr_msg_type_txt = ProtoField.string("aprint.typetxt","aprint_type_text") (Tried f_apr_msg_type_txt = ProtoField.string("aprint.typetxt","aprint_type_text",FT_STRING) also)
Below the code where subtree aprint.type is shown, added my required field as subtree:add(f_apr_msg_type_txt, msg_type_string) (Below is image of code extract)
I am able to see the text but field Name is shown as Wireshark Lua text (_ws.lua.text)
Normally displaying strings based on numeric values is accomplished by a value string lookup, so you'd have something like so:
local aprint_type_vals = {
[1] = "Foo",
[2] = "Bar",
[9] = "State alarm"
}
f_apr_msg_type = ProtoField.uint16("aprint.type", "Type", base.DEC, aprint_type_vals)
f_apr_msg_type_txt = ProtoField.string("aprint.typetxt","aprint_type_text", base.ASCII)
... then
local msg_type = tvb(offset, 2):le_uint()
subtree:add_le(f_apr_msg_type, tvb(offset, 2))
subtree:add(f_apr_msg_type_txt, tvb(offset, 2), (aprint_type_vals[msg_type] or "Unknown"))
--[[
Alternatively:
subtree:add(f_apr_msg_type_txt, tvb(offset, 2)):set_text("aprint_type_text: " .. (aprint_type_vals[msg_type] or "Unknown"))
--]]
I'm also not sure why you need the extra field with only the text when the text is already displayed with the existing field, but that's basically how you'd do it.
I know its possible to read a parameter externally from the iFrame of the configurator
const frameColour = params.find(({ key }) => key === "frameColour");
but is it possible to on the ADD TO CART action to read the value of a Parameter Key (frameColour) and display it in an HTML DIV / Input? The reason for this is I have the parameter key that is the colour of the Shelf Frame I'm building, I want to be able to read the colour and display it to the Screen, then I can store that colour in my external database
After you've created a new configurator using the embedding API you can use this to get notified about parameter updates:
configurator.extended.callbacks.onUpdateParameters = (parameters) => {
// add your logic here
};
configurator.extended will give you access to the RoomleConfigurator instance (https://docs.roomle.com/web/api/classes/roomleconfigurator.html)
I would like to see if they can help me with the creation of a variable, where I can change the labels of the MQTT message that is sent from my IoT devices, in order to make it easier and to select the correct parameters when creating a dashboard. .
Example:
This is the message received to my server.
[{"n": "model", "d": "iot-zigbee1783"}, {"n": "Relay", "ap": true}, {"t": "gateway", "ma": "0035DDf45VAIoT215"}]
What I want is to change the label "d" for "deviceIoT" and "ap" for "door sensor" also if it is possible to change the true or false of the door sensor for open and closed.
You can do this with the help of Thingsboards rule-chain.
There is also an official tutorial for this:
https://thingsboard.io/docs/user-guide/rule-engine-2-0/tutorials/transform-incoming-telemetry/
They use the transformation-rule-node called script to convert temperatures from [°F] to [°C].
While this is not your use case, it shows you how to handle incoming telemetry before it is saved to the database.
You could do a mapping of value-keys like this:
var theCustomizedMessage = {};
theCustomizedMessage['customizedKey'] = msg['originalIncomingKey'];
return {msg: theCustomizedMessage, metadata: metadata, msgType: msgType};
Keep in mind that this might be contra-productive since you have to update the rule-node scripts, when something changes.
As an alternative option you can rename the key labels in the widget configuration. This will not help your dashboard developers. But a documentation document will do :)
I strongly recommend against the replacement of boolean values with strings ('closed', 'opened'). This is a job for the widgets (e.g. their value format functions).
I am currently working on a POC by using ThingsBoard PE.
Our raw data contains [Asset] [Attributes].
Data flow:
[IoT cloud] --https webhook carry raw data--> [ThingsBoard PE HTTP INTEGRATION] --uplink--> [ThingsBoard PE Data Converter]
My question is: is it possible to apply [Rule Chain] after [ThingsBoard PE Data Converter]? Therefore, the device can auto create relationship with [Asset] by the [Attribute], instead of [AssetName].
Example data after data converter process:
{
"deviceName": "ABC",
"deviceType": "temperature",
"attributes": {
"asset_id": 6 // <-- the id is used in asset attribute
},
"telemetry": {
"temperature": 39.43
}
}
Answering your two, separate questions:
is it possible to apply [Rule Chain] after [ThingsBoard PE Data Converter]?
Yes it is possible. Once your data is successfully integrated and you are receiving it, you can access it using the [Input] Rule Node (the default green one that is always there when you create a Rule) and route it to any other node you need.
Therefore, the device can auto create relationship with [Asset] by the [Attribute], instead of [AssetName].
So, you want the relationship to take your custom attribute and use that as the pattern that identifies the Asset you want to create the relationship from.
The PE edition already has the Create Relation Node. However, seems that as it is one is not able to do what you seek (has no option to specify custom Asset id).
However, two options you got are:
Create a Custom Rule Node that does what you want. For that try checking the Rule Node Development page from Thingsboard. You can use the Create Relation Node as base and work from there. This can be a longer solution than doing...
Enrich your incoming message's metadata, adding your desired attribute. The Create Relation Node allows you to use variables on your message's metadata in your Name and Type patterns, as seen from this screenshot I took from that node:
This allows us a workaround to what you want to do: Add a Script Transformation Node that adds attributes.asset_id to the metadata, for example as metadata.asset_id, so you can then use it as ${asset_id} on your Name and Type patterns.
For example, your Transform() method of such Script Transformation Node should look something like this:
function Transform(msg, metadata, msgType){
//assumming your desired id is msg.attributes.asset_id, add it to the metadata
metadata.asset_id = msg.attributes.asset_id;
//return the message, in your case to the Create Relation Node
return {msg: msg, metadata:metadata, msgType:msgType};
}
Finally, your Rule should be connected like this:
[Input] -> [Script Node] -> [Create Relation Node] -> [...whatever else you like]
I have a question about the query based on the predefined constraints in PopotoJs. In this example, the graph can be filtered based on the constraints defined in the search boxes. The sample file in this example visualizations folder, constraint is only defined for "Person" node. It is specified in the sample html file like the following:
"Person": {
"returnAttributes": ["name", "born"],
"constraintAttribute": "name",
// Return a predefined constraint that can be edited in the page.
"getPredefinedConstraints": function (node) {
return personPredefinedConstraints;
},
....
In my graph I would like to apply that query function for more than one node. For example I have 2 nodes: Contact (has "name" attribute) and Delivery (has "address" attribute)
I succeeded it by defining two functions for each nodes. However, I also had to put two search box forms with different input id (like constraint1 and constraint2). And I had to make the queries in the associated search boxes.
Is there a way to make queries which are defined for multiple nodes in one search box? For example searching Contact-name and/or Delivery-adress in the same search box?
Thanks
First I’d like to specify that the predefined constraints feature is still experimental (but fully functional) and doesn’t have any documentation yet.
It is intended to be used in configuration to filter data displayed in nodes and in the example the use of search boxes is just to show dynamically how it works.
A common use of this feature would be to add the list of predefined constraint you want in the configuration for every node types.
Let's take an example:
With the following configuration example the graph will be filtered to show only Person nodes having "born" attribute and only Movie nodes with title in the provided list:
"Person": {
"getPredefinedConstraints": function (node) {
return ["has($identifier.born)"];
},
...
}
"Movie": {
"getPredefinedConstraints": function (node) {
return ["$identifier.title IN [\"The Matrix\", \"The Matrix Reloaded\", \"The Matrix Revolutions\"]"];
},
...
}
The $identifier variable is then replaced during query generation with the corresponding node identifier. In this case the generated query would look like this:
MATCH (person:`Person`) WHERE has(person.born) RETURN person
In your case if I understood your question correctly you are trying to use this feature to implement a search box to filter the data. I'm still working on that feature but it won't be available soon :(
This is a workaround but maybe it could work in your use case, you could keep the search box value in a variable:
var value = d3.select("#constraint")[0][0].value;
inputValue = value;
Then use it in the predefined constraint of all the nodes type you want.
In this example Person will be filtered based on the name attribute and Movie on title:
"Person": {
"getPredefinedConstraints": function (node) {
if (inputValue) {
return ["$identifier.name =~ '(?i).*" + inputValue + ".*'"];
} else {
return [];
}
},
...
}
"Movie": {
"getPredefinedConstraints": function (node) {
if (inputValue) {
return ["$identifier.title =~ '(?i).*" + inputValue + ".*'"];
} else {
return [];
}
},
...
}
Everything is in the HTML page of this example so you can view the full source directly on the page.
#Popoto, thanks for the descriptive reply. I tried your suggestion and it worked pretty much well. With the actual codes, when I make a query it was showing only the queried node and make the other node amount zero. I wanted to make a query which queries only the related node while the number of other nodes are still same.
I tried a temporary solution for my problem. What I did is:
Export the all the node data to JSON file, search my query constraint in the exported JSONs, if the file is existing in JSON, then run the query in the related node; and if not, do nothing.
With that way, of course I needed to define many functions with different variable names (as much as the node amount). Anyhow, it is not a propoer way, bu it worked for now.