LAN device consisting of a server and multiple environmental sensors pushes XML data to HE. The XML data has one parent element (for the server) and one or more child elements (the sensors). The sensors can be several different "types".
Every time data is received by the parent driver's parse() function, I want to process each child element (sensor) with the updated data by calling a function for the sensor device type. Here's the code so far...
There's probably several errors in the above code, but it does "compile" like it is. I've tried several different things, but it always gets a compile error or throws an exception. What class should be used instead of "String"?
The above version of the code gets throws this exception...
groovy.lang.MissingMethodException: No signature of method: groovy.util.slurpersupport.NodeChild.updateDS18B20() is applicable for argument types: () values: on line 228 (method parse)
Note that if I move the code from the child functions into the calling function, the code works as expected, i.e., this works as expected...
But your sensor member is probably a NodeChild or some other complex type. You can track that down and type it explicitly in the parameter list, or you can just declare it like this and then sort it out inside updateXXX function:
I changed the calling function to what you suggested and specified groovy.util.slurpersupport.NodeChild as the parameter class for the called functions.
Now the called functions are being driven, but I keep getting syntax errors in them when I try to access any of the XML sensor values, e.g.,...
temperature = sensor.Temperature
...saves fine in the calling function, but gets this syntax error in the called functions...
Expression [VariableExpression] is not allowed: sensor at line number 244
If that doesn't help, please post more code (with line numbers) and more log output of what the XML content looks like. It's impossible to guess what is going wrong without more context.
You should be able to break down the data just by parsing the XML, so you can make it a little bit more dynamic. Here's a version from one of the longer dumps you posted in your previous thread.
There are several different types of sensors. The last log I posted contains two of them. My goal is to pass a child node to a sensor-specific function for "individual processing" based on the child's tag (e.g., owd_DS18B20, owd_EDS0068, etc.) or the child's "Name" value (e.g., DS18B20, EDS0068, etc.). The sensor values vary by device. For example, the DS18B20 has about a dozen values, whereas the EDS0068 has about 70. Processing requirements will vary depending on the sensor type. That's why I want to separate the functions by sensor type, i.e., to make the code more readable/manageable.
Your function works, but it looks to me like a "general purpose" function that is passed the complete XML doc and it processes all types of sensors in the same function.
That was just an example of how to probe in to the data in the XML document. Here's how you might structure it differently if you were writing sensor handlers.
import groovy.util.slurpersupport.GPathResult
void processResponse(GPathResult xmlObj)
{
log.debug "Inspecting XML..."
xmlObj.children().each()
{
switch(it.name())
{
case "owd_EDS0068":
owd_EDS0068(it)
break
default:
log.error "no handler found for (${it.name()})"
return
}
}
}
void commonOwdProcessing(GPathResult xmlObj)
{
xmlObj.children().each()
{
if(it.@Units != "")
{
log.debug "Measurement type = ${it.name()}"
log.debug "Units = ${it.@Units}"
log.debug "Value = ${it.toFloat()}"
}
}
}
void owd_EDS0068(GPathResult xmlObj)
{
commonOwdProcessing(xmlObj)
// do anything specific to this sensor type
log.debug "Health = ${xmlObj.Health}"
}
That works. If you look at the previous code I posted, lines 219-230 were copied from the driver I am using as a template. I'm not sure why but replacing that code with the code in your processResponse function works the way I wanted it to.