Array Condition within EPA CEP PROTON - fiware
Using CEP Proton I want to check if, for the events received in a time interval, the id of the second and following events is contained in an attribute of type array coming in the first event. Let's say the first event is coming with the attribute called group that is an array of integers (10, 20, 30). The following events will come with an id, ex 20, 25 and so on. I want to check if the id of those events is included in the attribute group included in the first event.
For that I have created a condition in EPA
ArrayContains(ArrayGet(myevent.group,0),ArrayGet(myevent.id,ArraySize(myevent.id)-1))
However I'm getting an error when I click on verify
Error Error in EPA: expression error of undefined myepa
Am I doing anything wrong?
Cannot I access to the attribute array using ArrayGet? Or maybe ArrayContains cannot work with the result of ArrayGet?
JSON
{"epn":{"events":[{"name":"GupsyContextUpdate","createdDate":"Thu Sep 29 2016","attributes":[{"name":"entityId","type":"String","dimension":0},{"name":"entityType","type":"String","dimension":0,"description":"The cost of this event occurrence. Negative if this is an opportunity"},{"name":"SF","type":"Integer","dimension":0,"description":"Used in case the this event occur within an interval"},{"name":"occupied","type":"Integer","dimension":"0"},{"name":"framecounter","type":"Integer","dimension":"0"},{"name":"RSSI","type":"String","dimension":"0"},{"name":"hwversion","type":"String","dimension":"0"},{"name":"swversion","type":"String","dimension":"0"},{"name":"compassz","type":"String","dimension":"0"},{"name":"MACBS","type":"String","dimension":"0"},{"name":"SNR","type":"String","dimension":"0"},{"name":"devEUI","type":"String","dimension":"0"},{"name":"battery","type":"String","dimension":"0"},{"name":"devicetype","type":"String","dimension":"0"},{"name":"compassx","type":"String","dimension":"0"},{"name":"compassy","type":"String","dimension":"0"},{"name":"compasst","type":"String","dimension":"0"},{"name":"neighbours","type":"String","dimension":"1"},{"name":"timestamp","type":"String","dimension":"0"}]},{"name":"gupsyoutput","createdDate":"Thu Sep 29 2016","attributes":[{"name":"Certainty","type":"Double","defaultValue":"1","dimension":0,"description":"The certainty that this event happen (value between 0 to 1)"},{"name":"OccurrenceTime","type":"Date","dimension":0,"description":"No value means it equals the event detection time, other option is to use one of the defined distribution functions with parameters"},{"name":"ExpirationTime","type":"Date","dimension":0},{"name":"Cost","type":"Double","dimension":0,"description":"The cost of this event occurrence. Negative if this is an opportunity"},{"name":"Duration","type":"Double","defaultValue":"0","dimension":0,"description":"Used in case the this event occur within an interval"},{"name":"test","type":"String","dimension":"1"}]}],"epas":[{"name":"gupsyepa","createdDate":"Thu Sep 29 2016","epaType":"Aggregate","context":"gupsyct","inputEvents":[{"name":"GupsyContextUpdate","alias":"gupsyupdate","consumptionPolicy":"Consume","instanceSelectionPolicy":"First"}],"computedVariables":[{"name":"count","aggregationType":"Count","gupsyupdate":"ArrayContains(ArrayGet(gupsyupdate.neighbours,0),ArrayGet(gupsyupdate.id,ArraySize(gupsyupdate.id)-1))"}],"assertion":"count == true","evaluationPolicy":"Immediate","cardinalityPolicy":"Single","internalSegmentation":[],"derivedEvents":[{"name":"gupsyoutput","reportParticipants":false,"expressions":{"Duration":"0","test":"ArrayContains(ArrayGet(gupsyupdate.neighbours,0),ArrayGet(gupsyupdate.devEUI,ArraySize(gupsyupdate.devEUI)-1))"}}]}],"contexts":{"temporal":[{"name":"gupsyct","createdDate":"Thu Sep 29 2016","type":"TemporalInterval","atStartup":false,"neverEnding":false,"initiators":[{"initiatorType":"Event","initiatorPolicy":"Ignore","name":"GupsyContextUpdate"}],"terminators":[{"terminatorType":"RelativeTime","terminationType":"Terminate","relativeTime":"15000"}]}],"segmentation":[],"composite":[]},"consumers":[{"name":"gupsyconsumer","createdDate":"Thu Sep 29 2016","type":"Rest","properties":[{"name":"URL","value":"http://127.0.0.1/ProtonParser/TestEvent2Log.php"},{"name":"contentType","value":"application/xml"},{"name":"formatter","value":"xml"},{"name":"delimiter","value":";"},{"name":"tagDataSeparator","value":"="},{"name":"dateFormat","value":"dd/MM/yyyy-HH:mm:ss"}],"events":[{"name":"gupsyoutput"}]}],"producers":[],"name":"gupsy"}}
Please share the whole JSON definition of your application.
From the information you have provided it is not clear which type of EPA it is (to access a series of events you need a statefull EPA and you need to make sure you write the application in such a way as to be able to distinguish between the first and subsequent events).
Additionally it is not clear why you try to access the same event instance- myevent in both parts of the expression.
ArrayContains recieves (array, value) as operands.
You pass it (value, value), and thats assuming that "myevent.id" is also an array, which from your description I understood it is not?
Anyway, I see lots of potential problems with your expression, therefore I would like to see the whole JSON, or at least the part relevant to the "myepa" EPA.
I have reviewed the JSON application, there are multiple problems:
1)You are using an EPA of type aggregate, to calculate a COUNT. Count is for counting events. It is an integer variable. No boolean values can be assigned to it.
Therefore comparison expressions like "count == true"
Or assigment of boolean values like : "count : ArrayContains(ArrayGet(gupsyupdate.neighbours,0),ArrayGet(gupsyupdate.id,ArraySize(gupsyupdate.id)-1))"
Are not valid.
2)Additionally, assuming you use this expression somewhere, and not in count variable:
-the gupsyupdate event has no attribute "id", so you cannot use this in an expression.
-ArrayGet(gupsyupdate.neighbours,0) - will return a single object within an array... So you cannot use it in ArrayContains expression which is supposed to receive an array
3)The policies of the EPA doesn't make sense... It is an aggregation EPA, but you use it with evaluationPolicy of "Immediate" and cardinality policy "Single". That means this EPA will be evaluated only once, immediately as it receives the first gupsyupdate event. So it will not really act as aggregator....
Please revise your application according to this input.
Related
Caffeine - How to set for each entity its own "expiration time"
We used to use the guava cache and we want to change it to caffeine. We want to set for each entity its own "expiration time", something like - put(K key, V value, long expiration_time). I saw the 3 functions above and I wonder what exactly they are doing, if you can explain me the meaning ant the operations of each one of them it will be great. For example, the return value of expireAfterCreate should be the duration we want for this entity from it's creation untill it's expiration? or something else? I'm also wondering why we have the parameter "currentTime" in both expireAfterRead and expireAfterUpdate if we don't use it in the function? When we used the guava cache we used the expireAfterAccess, what is the substitution for it in caffeine? My last question is how can I set a default value for entities without a unique expiration time. Thank you, May
When we used the guava cache we used the expireAfterAccess, what is the substitution for it in caffeine? We mirror the Guava API, so this is also available on the cache builder. My last question is how can I set a default value for entities without a unique expiration time. Use expireAfterAccess, expireAfterWrite, or return a constant duration with expireAfter(Expiry). I saw the 3 functions above and I wonder what exactly they are doing, if you can explain me the meaning ant the operations of each one of them it will be great. Expiry is a callback interface where a single timestamp value is updated. The invoked method corresponds to the operation performed on the cache entry (created, updated, read). An update or read that should have no effect can return currentDuration to no-op. For example, the return value of expireAfterCreate should be the duration we want for this entity from it's creation untill it's expiration? or something else? Yes. However if the expireAfterUpdate returns a custom value (something other than currentDuration), then that overrides the prior expiration duration. I'm also wondering why we have the parameter "currentTime" in both expireAfterRead and expireAfterUpdate if we don't use it in the function? This can most often be ignored, but is provided if somehow useful. It is the current nano timestamp from the Ticker (not wall clock time). We want to set for each entity its own "expiration time", something like - put(K key, V value, long expiration_time). The callback Expiry is required and generally recommended, because ideally entries are loaded through the cache to avoid stampedes (e.g. LoadingCache). A stampede is when multiple threads lookup the same entry, miss, load it, and overwrite each other putting it in. That wasted work rather than having only one thread perform the load and others wait for the results. That said, this method is available under Cache.policy().expiresVariably(). Those configuration-specific methods are stashed in that area to offer more power when deemed necessary. Thank you, You're very welcome.
Make beam/dataflow Create.of(List<String>) node emit exactly the number of elements in the list
My beam/dataflow job starts with a single static entry passed in like this: Pipeline p = Pipeline.create(options); PCollection<String> initValue = p.apply(Create.of("MyStringValue")); However when I run it (on DataflowRunner), the Create node produced by that statement emits multiple values. The longer I wait, the more times it emits the single value: This doesn't appear to be an artefact as later in the pipeline I get duplicate/triplicate/.. elements. Beam also logs a warning: Can't verify serialized elements of type BoundedSource have well defined equals method. This may produce incorrect results on some PipelineRunner How do I make my Create.of with one value emit just one value to the pipeline? Do I need to attach an equals method or point it towards the equals method for String values (if so, how)!?
Prototype for array locator functions
I am thinking of creating a generic task/function which will read a transaction from any given ovm analysis port and if the transaction matches some constraint provided by user then i will fire an event that matching transaction found. I want the user to pass the constraint like we pass it with array locator functions using the with clause like out = arr.find_first with (item == 10);
The with clause in many of SystemVerilog's constructs is not very OOP friendly. There is no way to pass the with expression as an argument. Two software design patterns you may want to try is the factory - where you allow the user to extend these functions with a difference compare function a policy class - you can make class whose sole purpose is to provide a compare function.
Assignment to "in" mode parameter not allowed
It seems that I can't put a record field as a parameter? joueurActuel.c1 := predColonne(joueurActuel.c1); The function: function predColonne (c : T_Colonne) return T_Colonne; where T_Colonne is a subtype of Positive. joueurActuel is an in parameter (joueurActuel : in T_Joueur;) of a function containing the assignment above. T_Joueur is a record.
This is by design. A formal parameter of mode in is a constant view; it cannot be updated within the subprogram body. A constant cannot be the target of an assignment operation. See section 3.3 od Ada Reference Manual, paragraphs 13, 15, 17 and 25 in particular. So, either you have to store the result of predColonne(joueurActuel.c1) in a local variable, or change joueurActuel into an in out parameter if it's correct from the business logic point of view.
The in mode in joueurActuel : in T_Joueur; is a guarantee you have given to the compiler that you will not update or modify joueurActuel in any way within the procedure where you declared this formal parameter. The fact that it's a record is nothing to do with the problem. joueurActuel.c1 := predColonne(joueurActuel.c1); is an attempt to modify joueurActuel, despite the guarantee. The compiler, correctly, rejects it. If this is really what you want to do, then mode in out will allow it, but first ask yourself it there is a better design. Does the rest of the program need to see the change? If so, then in out is acceptable. Otherwise, copying it to a local variable as Ondrej suggested it, and only modifying the local copy, will work.
ParseFloat html
I am a college student just learning HTML. The assignment that I have to complete is a simple grade calculator. There is a single button that calculates everything, and the values go to three empty text fields(total, average, and percentage). The problem that I am having is the total is calculated and shows up in the field, but the number is followed by [object]. The average field shows NaN and the percentage field remains empty. Here is my code. <input type="button" value="Click to calculate" onclick="fullmark = parseFloat(document.getElementById('fullBox').value); science = parseFloat(document.getElementById ('scienceBox').value); math = parseFloat(document.getElementById('mathBox').value); computer = parseFloat(document.getElementById('computerBox').value); english = parseFloat(document.getElementById('englishBox').value); History = parseFloat(document.getElementById('historyBox').value); total=science+math+computer+english+history; average=(total/5); percentage=(total/fullmark)*100; document.getElementById('totalBox').value=total; document.getElementById('averageBox').value=average; document.getElementById('percentageBox').value=percentage;">
Since you wrote History as the variable name first, but then used history when computing/assigning the value for total, that is a different variable – identifiers in JavaScript are case sensitive. The only reason you don’t get your script aborted with an error about an undefined variable at that point, is that window.history exists – it’s the object that keeps the current navigation history of the window. (All global variables are properties of the window object, so that’s what your use of history gets resolved to.) And since it’s an object, [object] is what you get as result when transferring it into a string context (which happens through the use of +, which is both the addition and the string concatenation operator). Apart from that, writing all that code into an onclick handler is kinda terrible style. Go learn how to use proper functions for stuff like this next ;-)