summaryrefslogtreecommitdiff
path: root/roles/daq-node/t/01-probe.t
blob: 8a84da340982068cd9290d6b0d928372f2b5deb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env perl
# -*- mode: perl-ts; -*-

use strict;
use warnings;

use Test::More tests => 3;
use Time::HiRes qw(usleep);

# Basic Atlas Scientific EZO probe smoke test.
#
# Run on a daq-node:
#   prove -v t/probe.t
#
# Optional overrides:
#   FAPG_DAQ_SERIAL_PORT=/dev/ttyUSB1 FAPG_DAQ_SERIAL_BAUD=9600 prove -v t/probe.t

my $port = $ENV{FAPG_DAQ_SERIAL_PORT} // $ARGV[0] // '/dev/ttyUSB0';
my $baud = $ENV{FAPG_DAQ_SERIAL_BAUD} // $ARGV[1] // 9600;

my $serial_module_ok = eval {
    require Device::SerialPort;
    Device::SerialPort->import;
    1;
};

BAIL_OUT("Device::SerialPort is required: $@") unless $serial_module_ok;
BAIL_OUT("Serial port does not exist: $port") unless -e $port;

my $serial = Device::SerialPort->new($port)
    or BAIL_OUT("Cannot open serial port: $port");

$serial->baudrate($baud) or BAIL_OUT("Cannot set baudrate to $baud");
$serial->databits(8)     or BAIL_OUT('Cannot set databits to 8');
$serial->parity('none')  or BAIL_OUT('Cannot set parity to none');
$serial->stopbits(1)     or BAIL_OUT('Cannot set stopbits to 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 '' ? '<no response>' : $value;
}
Copyright 2019--2026 Marius PETER