Query on Device Twin array properties - azure-iot-hub

how can query on a reported twin that is an array of strings
for example :
"SupportedCommands": [
"firmwareUpdate",
"diagnostics",
"getLog",
"calculateHash"
]
I checked some command like
WHERE CONTAINS(array, string)
or
WHERE [string] IN [array]
but no one worked

When querying twins and jobs the only supported function is:
IS_DEFINED(property)
see more details here.
As a workaround can be used a querying in the two steps, where the first one (such as a pre-querying process happen on the IoT Hub service side) will returned all twins based on the value of the property, see the following example:
SELECT
deviceId, properties.reported.SupportedCommands
FROM devices
WHERE properties.reported.SupportedCommands NIN [ null, [], ['abc', '123'] ]
the second step will be on the client side using the LINQ statements, see the following example:
var dummy = new { SupportedCommands = new string[] { } };
var query2 = (await query1.GetNextAsJsonAsync()).Where(i => JsonConvert.DeserializeAnonymousType(i, dummy).SupportedCommands.Contains("getLog"));

I solved it like this:
SELECT * FROM devices
WHERE ARRAY_CONTAINS(tags.SupportedCommands,'firmwareUpdate')
I hope it will be useful to you.
Query on IoT Hub to find a device using properties list

Related

Fetching data from multiple APIs using Graphql / REST

I have design question, on the approach that should fetch information about an entity from multiple applications and publish the result to the frontend at real-time. All of these applications can produce results abiding to a particular schema.
Currently I am using GraphQL, to combine the results from both the application source and concatinating the result to the frontend for users to compare and validate the data.
Ex: The query below, fetches the information of a client from two different applications through RESTful data source
const resolvers = {
Query: {
client: async (_source, { clientId }, { dataSources }) => {
clientApp1 = await dataSources.App1ClientsAPI.getClient(clientId);
clientApp2 = await dataSources.App2ClientsAPI.getClient(clientId);
const client = [].concat(clientApp1, clientApp2);
return client;
},
},
};
Schema
type Client {
ssnNumber: String
firstName: String
lastName: String
dateofBirth: String
clientId: Float
source: String
contactList: [Contact]
addressList: [Address]
}
Currently this approach is working fine for top level entity like Client, but when we go to bottom of the chain, like contacts, address, transactions, the number of resultset returned expands drastically. With this approach I see 2 drawbacks, pretty sure, there could be more, but these are the once which are critical for me
Unable to add a filter in the backend Ex: return only App1 data
Unable to control number of records returned by each application at the lower level entities [pagination]
Question
1.Should I modify the approach to use Schema Stiching or GraphQL federation for better performance
2.Any better options outside of Graphql that I should look for, for combining the results from Multiple API's

ObjectFilter in SoftLayer doesn't work

I find ObjectFilter doesn't work in SoftLayer.
I even tried the example provided in the SoftLayer webpage here:
https://sldn.softlayer.com/article/object-filters
REST:
List the ID and hostname of all servers in dal05
https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,hostname]&objectFilter={"datacenter":{"name":{"operation":"dal05"}}}
When I ran this command, it still returns all the virtual guests, regardless what data center that virtual guest belongs to.
try this request:
GET https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,hostname,datacenter]&objectFilter={"virtualGuests":{"datacenter":{"name":{"operation":"dal05"}}}}
The issue with your request is that you are missing the "virtualGuests" property, keep in mind that the objectFilter is filtering over the data in the database, so you need to tell it over what table work and over what record of the table work. e.g. using the "SoftLayer_Account" that implies that all the work will be over the "SoftLayer_Account" table now you need to tell id over what property/record of that table work in this case you need to work over the "virtualGuests" and so on. Please keep in mind that and you review the documentation about the valid properties/records e.g. these are the valid properties/record for Softlayer_Account:
http://sldn.softlayer.com/reference/datatypes/SoftLayer_Account
Regards
Maybe you can try adding virtualGuestsin the filter, something like this:
objectFilter={ "virtualGuests": { "datacenter": { "longName": { "operation": "Dallas 6" } } } }
or please see the first examples of https://sldn.softlayer.com/article/object-filters, like this:
object_filter = {
'virtualGuests': {
'datacenter': {
'name': {'operation': 'dal05'}
}
}
}

Wsapi data store query

I am looking to get all projects under a selected project (i.e the entire child project branch ) using Wsapi data store query in Rally SDK 2.0rc1. Is it possible using a query to recursively get all child project names? or will I have to write a separate recursive function to get that information? If a separate recursive function is required, how should I populate that data into for example, a combo box? Do I need to create a separate data store and push the data from my recursive function in it and then link the Combobox's store to it?
Also, how to get the "current workspace name" (workspace that I am working in, inside Rally), in Rally SDK 2.0rc1 ?
Use the 'context' config option to specify which project level to start at and add 'projectScopeDown' to make sure child projects are returned. That would look something like this:
Ext.create('Rally.data.WsapiDataStore', {
limit : Infinity,
model : 'Project',
fetch : ['Name','ObjectID'],
context : {
project : '/project/' + PROJECT_OID,
projectScopeDown : true
}
}).load({
callback: function(store) {
//Use project store data here
}
});
To get your current context data, use: this.getContext().
var workspace = this.getContext().getWorkspace();
var project = this.getContext().getProject();
If you try exposing with console.log the this.getContext().getWorkspace() and this.getContext().getProject() you may understand better what is returned and what is required. In one of my cases I had to use this.getContext().getProject().project.
Using console debug statement is best way to figure what you need based on its usage.

Sencha Touch 2 Beta 2 Store Sync Issues

In ST1.x I had no problem syncing an onlinestore to an offlinestore with the below method, now it seems that sync doesn't work in STB2. I can see the records being output on the console. Anyone else having this issue? I believe it may be a bug...
var remoteStore = Ext.getStore('UpdateConfig');
var localStore = Ext.getStore('UpdateLocalConfig');
remoteStore.each(function (record) {
localStore.add(record.data);
console.log(record.data);
});
localStore.sync();
same question + answer # Sencha Forum
...and same user??? XD
This was answered on the Sencha Touch 2 Forums by TommyMaintz, but I wanted to give the answer here as well.
"One thing I think I see which is wrong is that you are adding a record to the LocalStore using the record.data. In ST2 we now have a Model cache. This means that if you create two instances with the exact same model and id, the second time you create that instance it will just return the already existing instance. This means that if you sync your local store, it won't recognize that record as a 'phantom' record because it already has an id. What you would have to do in your case if you want to make a "copy" of your record by using all the data but removing the id. This will generate a new simple id for it and when you save it to your local storage it will generate a proper local id for it.
When I tried doing this I noticed the "copy" method on Model hasn't been updated to handle this. If you apply the following override you should be able to do localStore.add(record.copy()); localStore.sync()"
Ext.define('Ext.data.ModelCopyFix', {
override: 'Ext.data.Model',
/**
* Creates a copy (clone) of this Model instance.
*
* #param {String} id A new id. If you don't specify this a new id will be generated for you.
* To generate a phantom instance with a new id use:
*
* var rec = record.copy(); // clone the record with a new id
*
* #return {Ext.data.Model}
*/
copy: function(newId) {
var me = this,
idProperty = me.getIdProperty(),
raw = Ext.apply({}, me.raw),
data = Ext.apply({}, me.data);
delete raw[idProperty];
delete data[idProperty];
return new me.self(null, newId, raw, data);
}
});

Data structure to use in Sencha Touch similar to Vector in Blackberry

I am a beginner to sencha Touch, basically i am a blackberry developer. Currently we are migrating our application to support Sencha Touch 1.1. Now i have some business solutions like i want to store the selected values in the local database. I mean i have multiple screens where, Once the user selects a value in each of the screen the data should save in the below following format.
[{'key1': "value1", 'key2': "value2", 'key3': "value3" ,'key4': "value4", 'key5': "value5"}]
1. First, the values need to be saved in key value pairs
2. The keys should play the role of primary key, key shouldn't be duplicated.
3. Should be available till the application life cycle or application session, don't need to save the data permanently.
I have come across the concepts like LocalStorageProxy, JsonStore and some others. I don't understand which one i can use for my specific requirements.
May be my question is bit more confusing. I have achieved the same using vector, in Blackberry Java so any data structure similar to this could help me. Need the basic operations like
Create
Add
Remove
Remove all
Fetch elements based on key
Please suggest me some samples or some code snapshots, which may help me to achieve this.
Edit: 1
I have done the changes as per #Ilya139 's answer. Now I am able to add the data with key,
// this is my Object declared in App.js
NSDictionary: {},
// adding the data to object with key
MyApp.NSDictionary['PROD'] = 'SONY JUKE BOX';
//trying to retrieve the elements from vector
var prod = MyApp.NSDictionary['PROD'];
Nut not able to retrieve the elements using the above syntax.
If you don't need to save the data permanently then you can just have a global object with the properties you need. First define the object like this:
new Ext.Application({
name: 'MyApp',
vectorYouNeed: {},
launch: function () { ...
Then add the key-value pairs to the object like this
MyApp.vectorYouNeed[key] = value;
And fetch them like this
value = MyApp.vectorYouNeed[key];
Note that key is a string object i.e. var key='key1'; and value can be any type of object.
To remove one value MyApp.vectorYouNeed[key] = null; And to remove all of them MyApp.vectorYouNeed = {};