Open jpwhitemn opened 4 years ago
This could be done by sending all except the most recent Event via the async channel? Proposals for better ways of handling the use case are invited - for consideration for Ireland release
@iain-anderson since this issue is tagged ireland but in icebox, should we implement this ?
Per Device Service WG meeting today, here are more details about my requirement:
My device has a REST endpoint that when I call, it gives me a collection of RFID alerts. Each alert (which would equate to an event in EdgeX language) is for a product it is seeing via RFID. On each read, it provides a lot of details (what we would call device resources) to include:
tagnumb
tagname
zone
subzone
signal strength
readername
UTC time when tag was read.
The device profile for this device is here: https://github.com/jpwhitemn/device-rest-rfrain/blob/master/cmd/res/device.rfrain.yaml (under older Hanoi schema)
After making the REST call to get the multiple RFID alerts with multiple data points, I'd like the device resource (through SDK) to be able to create multiple events (one for each RFID alert tag) with all the above device resources.
We still need to define which event include which reading clearly in the Device Profile, because Event contains SourceName
now.
I thought the solution is to allow a composite Device Command.
In addition to resourceOperations
, add another field called something like chainedCommand
ChainedCommand []string `json:"chainedCommand,omitempty" yaml:"chainedCommand,omitempty"`
It could trigger other Device Commands to send out additional events
this? https://github.com/edgexfoundry/device-sdk-c/issues/3
field was originally called resource
and subsequently renamed to deviceCommand
but never implemented
There are three ways a device service produces EdgeX Events
:
AutoEvent
is triggered; this in fact similar to the first case, although AutoEvents
are read-onlyProtocolDriver
instance of a device service generates an Event
asynchronously by writing one or more Readings
to the internal async go channel.In the first two cases, the client or AutoEvent
are required to specify a deviceResource
or deviceCommand
(used to aggregate reads or writes for more than one deviceResource
), in the third case the device service can push readings for any of the deviceResources
defined in the current device profile.
It's not possible to use an AutoEvent
to query for all available data, as AutoEvents
use the same internal logic as calls to a device service's command endpoint (i.e. the AutoEvent
needs to specify a deviceResource
or deviceCommand
).
In our device services meeting today, I thought what you were asking for was just a way to tell a device service to send all of it's queued Readings
on-demand. In effect a way to trigger the service to send all of it's current reading via the async channel. We discussed adding a new deviceResource
that could be used to trigger this behavior, but it was pointed out that AutoEvents
don't support writes, only reads. @iain-anderson suggested that you could use Support Scheduler for this however. We could also explore allowing writes via AutoEvents
.
After re-reading @jpwhitemn's comment from after last week's meeting, I don't think my previous comment captures what's really being asked for...
I think the issue here is that the EdgeX data model doesn't map simply to the RFID data model. To simplify it, let's say an RFID has three attributes:
Each RFID event is composed of the three attributes but it doesn't make sense to read them individually as they're constantly changing. You could create a deviceCommand
which reads all three at once, but if these are discrete values that are constantly changing as tags appear and disappear, if you don't query the device service at a high enough sample rate, you'll lose data.
So what do you do? You could:
Make the device service always use the asynchronous channel and always write the three readings together, which means they'd be packaged as a single event. You would only see events when the device service decided to send them.
You could also create a single device resource with a string type, and generate a JSON-based report of all the tags seen and send it using the async channel. This is in fact how the the LLRP RFID service works. You configure the reader by writing ROSpecs and AccessSpecs and then the device service generates ROAccessReport readings via the async channel. The rate at which these reports are generated depends on the number and configuration of the various ROSpecs and AccessSpecs sent to the reader.
As mentioned in the previous comment, you could also define a deviceResource which acts as a trigger to flush the accumulated readings being held at the protocol layer.
@jpwhitemn May we use async channel to produce multiple events to fulfill this requirement?
Using the current SDK, on AutoEvent schedule, the HandleReadCommands method gets called to create and add reading objects to an event. This, however presupposes that at the appointed schedule, only one event is to be created.
Some devices/sensors, when polled, return the data for multiple events/readings. For example, in some RFID devices, when the RFID reader is pulled, multiple RFID tag events are returned. Each tag event contains what tag was read, the signal strength, reader id, etc.
The SDK should allow for creation of multiple events as well as multiple readings on a single event.