I would like to create some complex entities, aggregating the results of some simpler entities.
Example scenario: model a room with its temperature.
I have 3 temperature sensors in a room.
I create under Orion 3 "Sensor" entities with a "Temperature" attribute.
I would also like to create a "Room" entity, which contains a consolidated temperature value (says the average of the 3 sensors).
How to do that? Can I use Perseo (http://fiware-iot-stack.readthedocs.io/en/latest/cep/)? The idea is to create a rule on Perseo that will update the attribute value of the room based on the sensor entity values.
Maybe you can model your scenario with FIWARE Comet STH.
One of the use possibilities is:
Aggregated time series context information: The STH component allows the query and retrieval of historical aggregated time series context information, this is information about the evolution of the entity attribute values grouped by time making it straight-forward to get distinct probabilistic measures such as means, standard deviations, maximum and minimum values, as well as the number of occurrences.
This way, you can get the average of the three sensors.
In order to update your Room entity, I think you can register a notification with a url pointing to your Room entity at Orion and use custom headers to specify the headers needed to make the notification works updating your entity.
The following link can help you about custom headers:
How to add a custom header in outgoing notifications with Orion?
I hope this can help you.
Related
I am coding a new application usign CQRS+ES architecture with Event Store DB. In my app, I have the following streams:
user-1
user-2
user-3
...
Each stream contains all events regarding a given user.
I am now creating a projection called user-account, which consists in basic data regarding my user's account (like first name, email, and others)
What is the optimal way to design that projection?
I should have a single projection for each user, creating projections called:
user-account-1
user-account-2
user-account-3
...
Or a single projection for all user-accounts? Being it a key-value pair record (that may store millions of keys in the future)
You can go with one stream per user. Projections are like dimensions. A user can exist in different "dimensions" (CDC naming) and have a different shape in each.
Read https://www.eventstore.com/blog/the-cost-of-creating-a-stream
First, subscribing to individual streams (aggregate or entity streams) won't ever work. You will end up with thousands of subscriptions, which are sitting there doing nothing (how often the user details change?).
The category stream is one way to go, you will project all the events for all the users. Not only you need just one subscription for all your users, but you'll also have more interesting possibilities like "users pending activation" or "blocked users" projections.
I prefer subscribing to $all and apply server-side filtering if necessary. It might have a bit of overhead as you receive more events than you need, but you get so much more power by combining events from different aggregates.
I wrote a little about it in Eventuous documentation.
I have a bunch of historical data (csv) which I want to make accessible through sth-comet. The data is the history of water levels from multiple revers. The data is not provided live, but more or less on a daily basis and contains all the historic records for multiple days.
What I did so far was:
Convert the data into NGSIv2 format data model with dateObserved: DateTime and waterlevel : number field
Update/append the data into Fiware orion
Create a subscription for sth-comet for the entity type
Access the historical data in sth-comet (wrong time)
With this I now have the problem that the "rcvTime" is of course the time when sth-cometreceived the data. Is there a way that I can "overwrite" that attribute or is there a better solution? I also looked at cygnus on inserting data but I think the underlying problem is the same.
I could not find any hint in the avaiable documentation.
In the case of using Cygnus NGSIMongoSink and NGSISthSink you can use TimeInstant metadata in attributes to override received time with the time given in the metadata value.
Have a look to NGSIMongoSink documentation
By default, NGSIMongoSink stores the notification reception timestamp. Nevertheless, if (and only if) working in row mode and a metadata named TimeInstant is notified, then such metadata value is used instead of the reception timestamp. This is useful when wanting to persist a measure generation time (which is thus notified as a TimeInstant metadata) instead of the reception time.
or this similar fragment in NGSISTHSink documentation:
By default, NGSISTHSink stores the notification reception timestamp. Nevertheless, if a metadata named TimeInstant is notified, then such metadata value is used instead of the reception timestamp. This is useful when wanting to persist a measure generation time (which is thus notified as a TimeInstant metadata) instead of the reception time.
Hi I'm a student and I'm working for the first time on the broker. I understood how the creation of entities works and their updating through "update" queries. My question is: you can create an entity that contains variables (eg geolocation) defined with value "null" or "zero" and then initialize them with values that interest me. So as to have dynamic and non-static variables (ie that require user update)?
Or do we need interaction with the CEP to do this?
From what I have read in the fiware-orion guide when I create an entity (ex car having attributes and velocity coordinates: geopoint). The values of these 2 attributes must be set in a static way (ex: speed 100 and position coordinates 40.257, 2.187). If I understand the values of these attributes I can only update them by making an update query. So my question is:
Is it possible to update the value of the attributes that contain the position or the speed of the car in a dynamic way, ie without having to write the values from the keyboard? Or does this require the use of the CEP of orion?
If I could not explain myself more generally I would like to know if it is possible to follow the progress of a moving car without me having to add the values from the keyboard.
Thanks.
Orion Context Brokker exposes a REST-based API that (among other things) allows you to create, update and query entities. From the point of view of Orion, it doesn't matter who is the one invoking the API: it can be done manually (for instance, using Postman or curl) or can be an automated system developed by you or a third party (for instance, a software running in a sensor in the car that measures the speed and periodically sends an update using a wireless communication network).
From a client-server point of view (in the case you are familiar with these concepts), Orion takes the server of the API role and the one updating the speed (either manually or automatically) takes the role of client of the API.
I'm interested in the correct convention to use when requesting a calculation on an entity from the server. That is - a specific entity is involved, but its data is not returned. Instead, a calculation based on the entity is returned.
Take for example a site that stores multiple clocks, each with a different offset/timezone value. The purpose of the site is to present images of analog clocks with hands pointing in the appropriate direction.
Using good convention I would expect to be able to do this:
POST /clocks
{
"offsetHours": 5
}
And I would receive this response:
201 (Created)
{
"id": "fe884d5e",
"offsetHours": 5
}
Now I would expect to be able to retrieve that clock object:
GET /clocks/fe884d5e
Which responds:
200 (OK)
{
"id": "fe884d5e",
"offsetHours": 5
}
This is all fine so far. But there are two other endpoints I would expect to have access to. The first one would return the current time calculated for a clock's offset. The second one would return image data displaying an analog clock based on the clock's current time.
My question is: what does convention dictate the GET requests for these data items should look like? Or is convention loose when it comes to dealing with calculated views of entities?
But there are two other endpoints I would expect to have access to. The first one would return the current time calculated for a clock's offset.
Something like
GET /clocks/fe884d53/localTime
The second one would return image data displaying an analog clock based on the clock's current time.
Something like
GET /clocks/fe884d5e/localTime/analogClock.jpg
or
GET /clocks/fe884d5e/analogClock.jpg
The key idea here is that these are information resources, in precisely the same way that the description of the clock itself is an information resource.
From the point of view of the consumer, the representation is just a document. There shouldn't be any way to know if the document was freshly generated, or copied from a document store, or pulled out of a web cache.
The fact that there is a calculation is just an implementation hidden behind the api.
Once you have clear the idea that these are different resources that share implementation details, the remainder of the work is just bike shedding (is it easy for our routing to find the right implementation? do we have the hierarchical data in the path segment, and the non hierarchical parts in the query, does the spelling look enough like a "resource" to conform with our local coding standards, etc).
Lets assume I have an object that I expose as a REST resource in my application. This object has many fields and contains many other objects including associated collections. Something like this, but think MUCH bigger:
Customer
List<Order> orders
List<Address> shippingAddresses;
// other fields for name, etc.
Order
List<Product> products
// fields for total, tax, shipping, etc.
Product
// fields for name, UPC, description, etc.
I expose the customer in my api as /customer/{id}
Some of my clients will want all of the details for every product in each order. If I follow HATEOAS I could supply a link to get the product details. That would lead to n+1 calls to the service to populate the products within the orders for the customer. On the other hand, if I always populate it then many clients receive a bunch of information they don't need and I do a ton of database lookups that aren't needful.
How do I allow for a customer representation of my resource based on the needs of the client?
I see a few options.
Use Jackson's JsonView annotation to specify in advance what is used. The caller asks for a view appropriate to them. i.e. /customer/{id}?view=withProducts. This would require me to specify all available views at compile time and would not be all that flexible.
Allow the caller to ask for certain fields to be populated in the request, i.e. /customer/{id}?fields=orders,firstName,lastName. This would require me to have some handler that could parse the fields parameter and probably use reflection to populate stuff. Sounds super messy to me. The what do you do about sub-resources. Could I do fields=orders.products.upc and join into the collection that way? Sounds like I'm trying to write hibernate on top of REST or something.
Follow HATEOAS and require the client to make a million HTTP calls in order to populate what they need. This would work great for those that don't want to populate the item most of the time, but gets expensive for someone that is attempting to show a summary of order details or something like that.
Have separate resources for each view...
Other?
I would do something like this:
/customers/{id}/orders/?include=entities
Which is a kind of a more specific variation of your option 1.
You would also have the following options:
Specific order from a specific customer without list of products:
/customers/{id}/orders/{id}
Just the orders of a customer without products:
/customers/{id}/orders/
I tend to avoid singular resources, because most of the time or eventually someone always wants a list of things.
Option 2 (client specifies fields) is a filtering approach, and acts more like a query interface than a GETable resource. Your filter could be more expressive if you accept a partial template in a POST request that your service will populate. But that's complicated.
I'm willing to bet all you need is 2 simple representations of any complex entity. That should handle 99.9% of the cases in your domain. Given that, make a few more URIs, one for each "view" of things.
To handle the 0.1% case (for example, when you need the Products collection fully populated), provide query interfaces for the nested entities that allow you to filter. You can even provide hypermedia links to retrieve these collections as part of the simplified representations above.