#!/usr/bin/env perl # Basic Atlas Scientific EZO probe smoke test. use v5.32.1; use strict; use warnings; use Test2::V0; plan tests => 3; use Device::SerialPort; use Time::HiRes qw(usleep); my $port = '/dev/ttyUSB0'; my $baud = 9600; my $serial = Device::SerialPort->new($port) or die "Cannot open serial port: $port"; $serial->baudrate($baud); $serial->databits(8); $serial->parity('none'); $serial->stopbits(1); $serial->read_char_time(0); $serial->read_const_time(100); note("Testing EZO probe on $port at $baud baud"); my $info = ezo_command( $serial, 'I', 500_000 ); note( "I => " . printable($info) ); ok( $info ne '', 'probe is reachable' ); like( $info, qr/(?:\?I,|EZO|PH|EC|DO|ORP)/i, 'probe is identifiable' ); my $reading = ezo_command( $serial, 'R', 1_500_000 ); note( "R => " . printable($reading) ); like( $reading, qr/OK/, 'probe returns a single reading' ); sub ezo_command { my ( $serial, $command, $wait_us ) = @_; drain_serial($serial); my $written = $serial->write("$command\r"); return '' unless defined $written && $written > 0; usleep($wait_us); my $reply = ''; while (1) { my ( $count, $buffer ) = $serial->read(255); last unless $count; $reply .= $buffer; } return clean_reply($reply); } sub drain_serial { my ($serial) = @_; while (1) { my ( $count, undef ) = $serial->read(255); last unless $count; } } sub clean_reply { my ($reply) = @_; $reply =~ s/\r/\n/g; $reply =~ s/\n+/\n/g; $reply =~ s/^\n|\n$//g; return $reply; } sub printable { my ($value) = @_; return $value eq '' ? '' : $value; }