[CTOR-38][Plugin] New pack Avigilon camera snmp (#4994)

This commit is contained in:
Lucie Dubrunfaut 2024-04-23 16:52:15 +02:00 committed by GitHub
parent e670dbaacd
commit 5da7c6f509
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 765 additions and 0 deletions

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"libsnmp-perl"
]
}

View File

@ -0,0 +1,10 @@
{
"pkg_name": "centreon-plugin-Hardware-Devices-Camera-Avigilon-Snmp",
"pkg_summary": "Centreon Plugin to monitor Avigilon camera using SNMP",
"plugin_name": "centreon_camera_avigilon_snmp.pl",
"files": [
"centreon/plugins/script_snmp.pm",
"centreon/plugins/snmp.pm",
"hardware/devices/camera/avigilon/snmp/"
]
}

View File

@ -0,0 +1,5 @@
{
"dependencies": [
"perl(SNMP)"
]
}

View File

@ -0,0 +1,180 @@
#
# Copyright 2024 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package hardware::devices::camera::avigilon::snmp::mode::interfaces;
use base qw(snmp_standard::mode::interfaces);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
return $self;
}
1;
__END__
=head1 MODE
Check interfaces.
=over 8
=item B<--add-global>
Check global port statistics (by default if no --add-* option is set).
=item B<--add-status>
Check interface status.
=item B<--add-duplex-status>
Check duplex status (with --warning-status and --critical-status).
=item B<--add-traffic>
Check interface traffic.
=item B<--add-errors>
Check interface errors.
=item B<--add-cast>
Check interface cast.
=item B<--add-speed>
Check interface speed.
=item B<--add-volume>
Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting).
=item B<--check-metrics>
If the expression is true, metrics are checked (default: '%{opstatus} eq "up"').
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display}
=item B<--critical-status>
Define the conditions to match for the status to be CRITICAL (default: '%{admstatus} eq "up" and %{opstatus} ne "up"').
You can use the following variables: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down',
'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard',
'in-ucast', 'in-bcast', 'in-mcast', 'out-ucast', 'out-bcast', 'out-mcast',
'speed' (b/s).
=item B<--units-traffic>
Units of thresholds for the traffic (default: 'percent_delta') ('percent_delta', 'bps', 'counter').
=item B<--units-errors>
Units of thresholds for errors/discards (default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter').
=item B<--units-cast>
Units of thresholds for communication types (default: 'percent_delta') ('percent_delta', 'percent', 'delta', 'deltaps', 'counter').
=item B<--nagvis-perfdata>
Display traffic perfdata to be compatible with NagVis widget.
=item B<--interface>
Set the interface (number expected) example: 1,2,... (empty means 'check all interfaces').
=item B<--name>
Allows you to define the interface (in option --interface) by name instead of OID index. The name matching mode supports regular expressions.
=item B<--speed>
Set interface speed for incoming/outgoing traffic (in Mb).
=item B<--speed-in>
Set interface speed for incoming traffic (in Mb).
=item B<--speed-out>
Set interface speed for outgoing traffic (in Mb).
=item B<--map-speed-dsl>
Get interface speed configuration for interface type 'ADSL' and 'VDSL2'.
Syntax: --map-speed-dsl=interface-src-name,interface-dsl-name
E.g: --map-speed-dsl=Et0.835,Et0-vdsl2
=item B<--force-counters64>
Force to use 64 bits counters only. Can be used to improve performance.
=item B<--force-counters32>
Force to use 32 bits counters (even in SNMP version 2c and version 3). Should be used when 64 bits counters are buggy.
=item B<--reload-cache-time>
Time in minutes before reloading cache file (default: 180).
=item B<--oid-filter>
Define the OID to be used to filter interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr).
=item B<--oid-display>
Define the OID that will be used to name the interfaces (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr).
=item B<--oid-extra-display>
Add an OID to display.
=item B<--display-transform-src> B<--display-transform-dst>
Modify the interface name displayed by using a regular expression.
Example: adding --display-transform-src='eth' --display-transform-dst='ens' will replace all occurrences of 'eth' with 'ens'
=item B<--show-cache>
Display cache interface data.
=back
=cut

View File

@ -0,0 +1,105 @@
#
# Copyright 2024 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package hardware::devices::camera::avigilon::snmp::mode::memory;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub custom_memory_output {
my ($self, %options) = @_;
my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
return sprintf(
'total system memory available: %s',
$total_value . " " . $total_unit
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'memory', type => 0 }
];
$self->{maps_counters}->{memory} = [
{ label => 'available', nlabel => 'memory.available', set => {
key_values => [{ name => 'total' }],
closure_custom_output => $self->can('custom_memory_output'),
perfdatas => [
{ value => 'total', template => '%d', min => 0,
unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'name' }
],
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my $oid_total = '.1.3.6.1.4.1.46202.1.1.1.6.0'; #memAvailable
my $snmp_result = $options{snmp}->get_leef(
oids => [$oid_total],
nothing_quit => 1
);
$self->{memory} = {
total => $snmp_result->{$oid_total}
};
}
1;
__END__
=head1 MODE
Check system memory available.
=over 8
=item B<--warning-available*>
Warning threshold for total memory available (B).
=item B<--critical-available*>
Critical threshold for total memory available (B).
=back
=cut

View File

@ -0,0 +1,128 @@
#
# Copyright 2024 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package hardware::devices::camera::avigilon::snmp::mode::storage;
use base qw(centreon::plugins::templates::counter);
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use centreon::plugins::misc qw(is_empty);
use strict;
use warnings;
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'storage', type => 0 }
];
$self->{maps_counters}->{storage} = [
{ label => 'status',
type => 2,
unknown_default => '%{storage_state} =~ /Unknown/i',
warning_default => '%{storage_state} =~ /insufficientMediaCapacity/i || %{storage_state} =~ /insufficientMediaSpeed/i',
critical_default => '%{storage_state} =~ /mediaNotPresent/i || %{storage_state} =~ /error/i',
set => {
key_values => [{ name => 'storage_state' }],
output_template => 'state of the SD card: %s',
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my $storage_state_mapping = {
1 => 'mediaNotPresent',
2 => 'mediaDetected',
3 => 'existingDataOnMediaDetected',
4 => 'mediaFormatting',
5 => 'scanningForRecordings',
6 => 'readOnly',
7 => 'readyToRecord',
8 => 'recording',
9 => 'errorFormatting',
10 => 'errorWriting',
11 => 'insufficientMediaCapacity',
12 => 'insufficientMediaSpeed',
13 => 'error'
};
my $oid_storage_state = '.1.3.6.1.4.1.46202.1.1.1.5.0'; #storageState
my $snmp_result = $options{snmp}->get_leef(
oids => [$oid_storage_state],
nothing_quit => 1
);
if(centreon::plugins::misc::is_empty($storage_state_mapping->{$snmp_result->{$oid_storage_state}})==0){
$self->{storage} = {
storage_state => $storage_state_mapping->{$snmp_result->{$oid_storage_state}}
};
# If state is not in the mapping, return unkown
}else{
$self->{storage} = {
storage_state => "Unknown"
};
}
}
1;
__END__
=head1 MODE
Check storage state of the SD card.
=over 8
=item B<--unknown-status>
Define the conditions to match to return a unknown status (default: "%{storage_state} =~ /Unknown/i").
The condition can be written using the following macros: %{storage_state}.
=item B<--warning-status>
Define the conditions to match to return a warning status (default: "%{storage_state} =~ /insufficientMediaCapacity/i || %{storage_state} =~ /insufficientMediaSpeed/i").
The condition can be written using the following macros: %{storage_state}.
=item B<--critical-status>
Define the conditions to match to return a critical status (default: "%{storage_state} =~ /mediaNotPresent/i || %{storage_state} =~ /error/i").
The condition can be written using the following macros: %{storage_state}.
=back
=cut

View File

@ -0,0 +1,144 @@
#
# Copyright 2024 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package hardware::devices::camera::avigilon::snmp::mode::temperature;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
sub custom_status_output {
my ($self, %options) = @_;
return sprintf(
"sensor %s [type:%s] status: %s",
$self->{result_values}->{id},
$self->{result_values}->{type},
$self->{result_values}->{status}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'sensors', type => 0 }
];
$self->{maps_counters}->{sensors} = [
{ label => 'temperature',
nlabel => 'sensor.temperature.celsius',
set => {
key_values => [{ name => 'temperature' }],
output_template => 'temperature: %.2f C',
perfdatas => [
{ template => '%s', min => 0, unit => 'C', label_extra_instance => 1, instance_use => 'id' }
]
}
},
{ label => 'status',
type => 2,
critical_default => '%{status} ne "ok"',
set => {
key_values => [{ name => 'status' }, { name => 'id' }, { name => 'type' }],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-sensor-id:s' => { name => 'filter_id' }
});
return $self;
}
my $state_mapping = {
1 => 'ok',
2 => 'failure',
3 => 'outOfBoundary'
};
my $type_mapping = {
1 => 'mainSensor',
};
sub manage_selection {
my ($self, %options) = @_;
my $oid_type = '.1.3.6.1.4.1.46202.1.1.1.1.1.1'; # tempSensorType: The type of a temperature sensor, i.e. where it is mounted
my $oid_id = '.1.3.6.1.4.1.46202.1.1.1.1.1.2'; # tempSensorId: The unique identifier for a temperature sensor.
my $oid_status = '.1.3.6.1.4.1.46202.1.1.1.1.1.3'; # tempSensorStatus: The status of a temperature sensor.
my $oid_temperature = '.1.3.6.1.4.1.46202.1.1.1.1.1.4'; # tempSensorValue: The temperature as measured in degrees Celsius.
my $snmp_result = $options{snmp}->get_leef(
oids => [$oid_type, $oid_id, $oid_status, $oid_temperature],
nothing_quit => 1
);
$self->{sensors} = {
id => $snmp_result->{$oid_id},
type => $type_mapping->{$snmp_result->{$oid_type}},
status => $state_mapping->{$snmp_result->{$oid_status}},
temperature => $snmp_result->{$oid_temperature}
};
}
1;
__END__
=head1 MODE
Check temperature sensor state and value.
=over 8
=item B<--warning-status>
Define the conditions to match to return a warning status.
The condition can be written using the following macros: %{status}.
=item B<--critical-status>
Define the conditions to match to return a critical status (default: '%{status} ne "ok"').
The condition can be written using the following macros: %{status}.
=item B<--warning-temperature*>
Warning threshold for temperature (Celsius).
=item B<--critical-temperature*>
Critical threshold for temperature (Celsius).
=back
=cut

View File

@ -0,0 +1,51 @@
#
# Copyright 2024 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package hardware::devices::camera::avigilon::snmp::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_snmp);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
%{$self->{modes}} = (
'interfaces' => 'hardware::devices::camera::avigilon::snmp::mode::interfaces',
'memory' => 'hardware::devices::camera::avigilon::snmp::mode::memory',
'storage' => 'hardware::devices::camera::avigilon::snmp::mode::storage',
'temperature' => 'hardware::devices::camera::avigilon::snmp::mode::temperature',
'uptime' => 'snmp_standard::mode::uptime',
);
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Avigilon camera in SNMP.
=cut

View File

@ -1,3 +1,4 @@
--add-sysdesc
--display-transform-dst --display-transform-dst
--display-transform-src --display-transform-src
--exclude-fs --exclude-fs
@ -5,6 +6,7 @@
--filter-vdom --filter-vdom
--force-counters32 --force-counters32
--force-counters64 --force-counters64
--force-oid
--map-speed-dsl --map-speed-dsl
--nagvis-perfdata --nagvis-perfdata
--oid-display --oid-display
@ -12,6 +14,7 @@
--oid-filter --oid-filter
2c 2c
ADSL ADSL
Avigilon
Centreon Centreon
Datacore Datacore
deltaps deltaps
@ -47,6 +50,7 @@ SureBackup
topic-messages-inflighted topic-messages-inflighted
total-oper-down total-oper-down
total-oper-up total-oper-up
uptime
VDSL2 VDSL2
Veeam Veeam
WSMAN WSMAN

View File

@ -0,0 +1,14 @@
.1.3.6.1.4.1.46202.1.1.1.1.1.1 = INTEGER: 1
.1.3.6.1.4.1.46202.1.1.1.1.1.2 = Gauge32: 1
.1.3.6.1.4.1.46202.1.1.1.1.1.3 = INTEGER: 1
.1.3.6.1.4.1.46202.1.1.1.1.1.4 = INTEGER: 23
.1.3.6.1.4.1.46202.1.1.1.2.0 = Gauge32: 163
.1.3.6.1.4.1.46202.1.1.1.3.0 = Timeticks: (80599046) 9 days, 7:53:10.46
.1.3.6.1.4.1.46202.1.1.1.4.1.0 = Counter64: 3145223708
.1.3.6.1.4.1.46202.1.1.1.4.2.0 = Counter64: 1976056200
.1.3.6.1.4.1.46202.1.1.1.4.3.0 = Gauge32: 11000
.1.3.6.1.4.1.46202.1.1.1.4.4.0 = Gauge32: 2786000
.1.3.6.1.4.1.46202.1.1.1.4.5.0 = Gauge32: 2
.1.3.6.1.4.1.46202.1.1.1.4.6.0 = Gauge32: 100000000
.1.3.6.1.4.1.46202.1.1.1.5.0 = INTEGER: 1
.1.3.6.1.4.1.46202.1.1.1.6.0 = Gauge32: 476004

View File

@ -0,0 +1,38 @@
*** Settings ***
Documentation Hardware Camera Avigilon memory
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
*** Variables ***
${CMD} ${CENTREON_PLUGINS}
... --plugin=hardware::devices::camera::avigilon::snmp::plugin
... --mode=memory
... --hostname=127.0.0.1
... --snmp-port=2024
*** Test Cases ***
Avigilon camera Memory ${tc}/3
[Documentation] Hardware Camera Avigilon Memory
[Tags] hardware avigilon memory
${command} Catenate
... ${CMD}
... --snmp-community=hardware/devices/camera/avigilon/snmp/hardware-camera-avigilon
... --warning-available='${warning_available}'
... --critical-available='${critical_available}'
${output} Run ${command}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... \nWrong output result for command:\n${command}\n\nExpected:\n${expected_result}\nCommand output:\n${output}\n\n
Examples: tc warning_available critical_available expected_result --
... 1 ${EMPTY} ${EMPTY} OK: total system memory available: 464.85 KB | 'memory.available'=476004B;;;0;
... 2 5000 ${EMPTY} WARNING: total system memory available: 464.85 KB | 'memory.available'=476004B;0:5000;;0;
... 3 ${EMPTY} 5000 CRITICAL: total system memory available: 464.85 KB | 'memory.available'=476004B;;0:5000;0;

View File

@ -0,0 +1,39 @@
*** Settings ***
Documentation Hardware Camera Avigilon storage
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
*** Variables ***
${CMD} ${CENTREON_PLUGINS}
... --plugin=hardware::devices::camera::avigilon::snmp::plugin
... --mode=storage
... --hostname=127.0.0.1
... --snmp-port=2024
*** Test Cases ***
Avigilon camera Storage ${tc}/3
[Documentation] Hardware Camera Avigilon Storage
[Tags] hardware avigilon storage
${command} Catenate
... ${CMD}
... --snmp-community=hardware/devices/camera/avigilon/snmp/hardware-camera-avigilon
... --warning-status='${warning_status}'
... --critical-status='${critical_status}'
... --unknown-status='${unknown_status}'
${output} Run ${command}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... \nWrong output result for command:\n${command}\n\nExpected:\n${expected_result}\nCommand output:\n${output}\n\n
Examples: tc warning_status critical_status unknown_status expected_result --
... 1 ${EMPTY} ${EMPTY} ${EMPTY} OK: state of the SD card: mediaNotPresent
... 2 \\%\{storage_state\} =~ /mediaNotPresent/ ${EMPTY} ${EMPTY} WARNING: state of the SD card: mediaNotPresent
... 3 ${EMPTY} \\%\{storage_state\} =~ /mediaNotPresent/ ${EMPTY} CRITICAL: state of the SD card: mediaNotPresent
... 4 ${EMPTY} ${EMPTY} \\%\{storage_state\} =~ /mediaNotPresent/ UNKNOWN: state of the SD card: mediaNotPresent

View File

@ -0,0 +1,42 @@
*** Settings ***
Documentation Hardware Camera Avigilon temperature
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Test Timeout 120s
*** Variables ***
${CMD} ${CENTREON_PLUGINS}
... --plugin=hardware::devices::camera::avigilon::snmp::plugin
... --mode=temperature
... --hostname=127.0.0.1
... --snmp-port=2024
*** Test Cases ***
Avigilon camera Temperature ${tc}/5
[Documentation] Hardware Camera Avigilon Temperature
[Tags] hardware avigilon temperature
${command} Catenate
... ${CMD}
... --snmp-community=hardware/devices/camera/avigilon/snmp/hardware-camera-avigilon
... --warning-temperature='${warning_temperature}'
... --critical-temperature='${critical_temperature}'
... --warning-status='${warning_status}'
... --critical-status='${critical_status}'
${output} Run ${command}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... \nWrong output result for command:\n${command}\n\nExpected:\n${expected_result}\nCommand output:\n${output}\n\n
Examples: tc warning_temperature critical_temperature warning_status critical_status expected_result --
... 1 ${EMPTY} ${EMPTY} ${EMPTY} ${EMPTY} OK: temperature: 23.00 C, sensor 1 [type:mainSensor] status: ok | 'sensor.temperature.celsius'=23C;;;0;
... 2 20 ${EMPTY} ${EMPTY} ${EMPTY} WARNING: temperature: 23.00 C | 'sensor.temperature.celsius'=23C;0:20;;0;
... 3 ${EMPTY} 20 ${EMPTY} ${EMPTY} CRITICAL: temperature: 23.00 C | 'sensor.temperature.celsius'=23C;;0:20;0;
... 4 ${EMPTY} ${EMPTY} \\%\{status\} =~ /ok/ ${EMPTY} WARNING: sensor 1 [type:mainSensor] status: ok | 'sensor.temperature.celsius'=23C;;;0;
... 5 ${EMPTY} ${EMPTY} ${EMPTY} \\%\{status\} =~ /ok/ CRITICAL: sensor 1 [type:mainSensor] status: ok | 'sensor.temperature.celsius'=23C;;;0;