Item “Tex_UDP_Incoming” receives it’s input via UDP.
It can contain values of variable length.
E.g. value "D0011 is possible, as well as "D001255
These values mean the following:
The second character (D) means the alarm is Disarmed.
The 3rd, 4th, 5th character (001) refer to the alarm partition;
The last part (1 or 255) refer to a user ID. Unfortunately, the length of this part is not fixed.
The code below works fine if the user ID consists out of three digits (e.g. 255). However, when user 1 is registered, I get the following message:
Rule 'Alarm interface via UDP': String index out of range: 8
The error message makes sense. But how do I make the rule below compatible with both user ID 1 and 255?
rule "Alarm interface via UDP"
when
Item Tex_UDP_Incoming received update
then
// We are only interested in the first 7 characters to process our items. The rest often contains NULL values that generate errors.
val inStr = Tex_UDP_Incoming.state.toString.substring(0, 6)
// When alarm is Disarmed (D) we register who disarmed it.
if(inStr.startsWith("\"D0")) {
postUpdate(Tex_Alarm_Status, "0")
postUpdate(Tex_Alarm_Partition, inStr.substring(2, 5))
postUpdate(Tex_Alarm_User, Tex_UDP_Incoming.state.toString.substring(5, 8))
}
end
I’m not at my computer so can’t check, therefore the solution proposed may not exist. That being sais, often when a string is of variable length you could use a substring from # to stringLength or something similar. That way the length of the last bit is to the end however long it may be.
That makes sense. I tried to derive the length, by defined “Tex_UDP_Incoming.state.length”, but whenever I use “length” in my rule, I get:
2017-05-21 22:24:43.038 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Alarm interface via UDP': An error occured during the script execution: The name '<XMemberFeatureCallImplCustom>.length' cannot be resolved to an item or type.
Unfortunately I still have issues with the variable length of “Tex_UDP_Incoming”.
This string could have a length between 6 and 1024;
I am never interested in the information beyond 32. It is always filled with NULL values, which generates errors along the way (The argument ‘state’ must not be null or empty.)
So I could easily chop the last part off with “substring(0, 32)”;
However, in the cases where the received string is only 6 long. I would receive an “String index out of range: 32” error message;
Thanks to your help, I could use “substring(0, Tex_UDP_Incoming.state.toString.length)”
However, this code would imply I would get the NULL-part back in my variable.
So is there an operation I could apply that just takes the first 32 characters of a string, but also accepts less characters (no generation of string index out of range)?
You should check the length of the string first. That would be “Tex_UDP_Incoming.state.toString.length”.
Knowing the length of the string, you can prevent to call for substrings that are non-existing!