Define a specific order, by which plugins receive deltas?
I am using the following plugin to detect outliers in sensor data (depth, STW, AWS): https://github.com/chris0348/signalk-detect-outliers
This works fine for depth, STW and AWS. But TWS, that is provided by the derived-data plugin (based on among others AWS), still shows an outlier when the apparent wind speed AWS had an outlier. So apparently derived-data gets the deltas before they are handled via the detect-outlier plugin.
Is there an option to assure, that the deltas that derived-data gets are handled before by the detect-outlier-plugin?
27 Replies
The only way currently would to make the detect-outlier-plugin use registerDeltaInputHandler
wait. it already does
actually looks like there's a bug in that plugin
unless I am crazy, it's actnually not filtering anything out except position
it's definitely not implemented correctly
Is that your plugin?
the plugin is setting that path to null when is wants to filter
but it should just not call next() when it wants to filter
"send = 0"
Yes, its my plugin
The github version is not up to date...
let me check
I'm not 100% sure this is the issue
but setting path to null is definitely not the right way to do this
the delta input handlers definitely get called before derived data
I checked the github version against my locally running version: The only differences are some debug messages etc.
and the plugin works fine
Here two examples for depth and AWS: Corrupt values are detected and a diagnostic "outlier"-delta is send instead
but if that was true, derived-data would not get the delta
Hhmm, strange
Here a more specific example: An outlier in AWS is detected, the "outlier"-delta is sent, but the TWS is corrupt (close to zero)
And TWS comes from derived-data:
can you try fixing the plugin? I really don't know the impact of setting the path to null
or actually. just change the path to ..._outlier
instead of emitting a new delta
I've set the value to "null" to explicitly show that no clean data is available, otherwise iirc, the value for path would still show the last clean value, wich might be misleading of eg. for depth over longer time no clean data is received.
I guess this issue would also appear if I change the path to the the corrupt data to the _outlier path. Then the "real" path would remain unchanged and show the last clean value. Misleading in case I do not constantyl check the _outlier path.
shoot, sorry, I misread the code
so I wonder if derived data is not handling null values correctly?
for TWS
Oh, indeed, that might be the case!
The corrupt TWS values are identically 0
so probably null is interpreted as 0...
yep. I bet that's it
I remember a discussion from some days ago that went into this direction...
I will have a look how to fix this
Hi Scott, I modified trueWind.js to check for null of the input values. When in the plugin detect-outliers I now intentionally set AWS to null, also the deltas derived via trueWind.js are set to null, which is what I initially expected.
Since I am not an experience js programmer I post the new trueWind.js here before I prepare a PR
module.exports = function (app) {
return {
group: 'wind',
optionKey: 'trueWind',
title: 'True Wind Angle, Direction and Speed',
derivedFrom: [
'navigation.headingTrue',
'navigation.speedThroughWater',
'environment.wind.speedApparent',
'environment.wind.angleApparent'
],
calculator: function (headTrue, speed, aws, awa) {
var angle
var speed
var dir
if (headTrue == null || speed == null || aws == null || awa == null) {
angle = null
speed = null
dir = null
} else {
var apparentX = Math.cos(awa) * aws
var apparentY = Math.sin(awa) * aws
angle = Math.atan2(apparentY, -speed + apparentX)
speed = Math.sqrt(
Math.pow(apparentY, 2) + Math.pow(-speed + apparentX, 2)
)
if (aws < 1e-9) {
angle = awa
}
dir = headTrue + angle
if (dir > Math.PI * 2) {
dir = dir - Math.PI * 2
} else if (dir < 0) {
dir = dir + Math.PI * 2
}
}
return [
{ path: 'environment.wind.directionTrue', value: dir },
{ path: 'environment.wind.angleTrueWater', value: angle },
{ path: 'environment.wind.speedTrue', value: speed }
]
}
}
}
Probably it's not the most elegant implementation. What do you think?Looks good to me
Probably checking for !== and moving var = null to the else statement?
The result would be identical
The way you have it is easier to read, IMO
Hi @Scott Bender , Hi @Teppo Kurki , I just sent a PR for this fix
The run at github failed due to a missing "fix" label. This seems to be new, for earlier PR this was not necessary iirc
Can this be added during the merging process or do I need to add this to the PR before it can be processed?
You can go to github and set the label
Ok, I will check
It’s over on the right side
Hhmm, I do not see <an option to set a label
hmm.
I guess I have to do it
I'm so used to having permission, didn
didn't realize the PR submitter could not do it...
I added the label
Thank you!