Polling serial port

I have a number of sensors that send data to the serial port, some every second and some 10 times a second.

Right now I have my ports defined like:

String Outside_Air_Sensor {serial="/dev/ttyPort0@9600,BASE64"}

And rules that kick off when sensor receives update such as:

rule "Outside_Air_Sensor"
when
  Item Outside_Air_Sensor received update
then
  val to64 = DatatypeConverter::parseBase64Binary(Outside_Air_Sensor.state.toString)
  val ByteBuffer bb = ByteBuffer::wrap(to64)
  val short start = bb.getShort
  val short length = bb.getShort
  if (start==16973 && length==28) {
    val short pm1 = bb.getShort
    if (pm1>0) {
      postUpdate(Outside_PM1, pm1.toString)
    }
    val short pm25 = bb.getShort
    if (pm25>0) {
      postUpdate(Outside_PM25, pm25.toString)
    }
    val short pm10 = bb.getShort
    if (pm10>0) {
      postUpdate(Outside_PM10, pm10.toString)
    }
  }
end

Things basically work, but I don’t need to know the air quality every second, or the level of my septic tank 10 times a second. Is there a way to write a rule that opens the serial port, based on cron say every 30 seconds, reads one value from the serial port and then closes it?

Have you considered rules that trigger on change, rather than update?

I do not think there is a way to poll an incoming stream. These are rather oddly behaved devices, many transmitting onto a serial bus, I wonder how they manage collisions.

Anyway, you may be able to achieve a serial port on-off effect using the Config Admin binding


I’ve no experience with it, but it should allow redirection to a non-existant port (as a substitute for port off) from a rule.
You should expect overrun errors from the unserviced working port.
Quite how you recover from that, or deal with an error when you switch back in the middle of a transmission, I’m not sure.