our
@EXPORT
=
qw()
;
our
@EXPORT_OK
=
qw(sensors_get
Selector
Value
ValueNA
ValueGroup
Measurement
)
;
our
%EXPORT_TAGS
= (
all
=> [
@EXPORT
,
@EXPORT_OK
]);
{
use
FP::Struct [[\
&is_string
,
'groupname'
], [\
&is_string
,
'sensorname'
],],
'FP::Struct::Show'
,
'FP::Abstract::Pure'
;
_END_
}
{
'name'
,
],
'FP::Struct::Show'
,
'FP::Abstract::Pure'
;
_END_
}
{
'value'
,
'unit'
,
'high_crit'
,
],
'Chj::Linux::LmSensors::ValueBase'
;
sub
maybe_value {
shift
->value
}
sub
value_or {
shift
->value
}
_END_
}
{
use
FP::Struct [],
'Chj::Linux::LmSensors::ValueBase'
;
sub
maybe_value {
undef
}
sub
value_or {
$_
[1]
}
_END_
}
{
'name'
,
'values'
,
],
'FP::Struct::Show'
,
'FP::Abstract::Pure'
;
_END_
}
{
sub
by {
my
(
$method
,
$str
) =
@_
;
sub
{
my
(
$v
) =
@_
;
$v
->
$method
eq
$str
}
}
'time'
,
'groups'
,
],
'FP::Struct::Show'
,
'FP::Abstract::Pure'
;
sub
select
{
my
(
$self
,
$selector
) =
@_
;
$self
->groups->filter(by
"name"
,
$selector
->groupname)
->xone->
values
->filter(by
"name"
,
$selector
->sensorname)->xone
}
_END_
}
import
Chj::Linux::LmSensors::Selector::constructors;
import
Chj::Linux::LmSensors::Value::constructors;
import
Chj::Linux::LmSensors::ValueNA::constructors;
import
Chj::Linux::LmSensors::ValueGroup::constructors;
import
Chj::Linux::LmSensors::Measurement::constructors;
sub
parse_value {
my
(
$s
) =
@_
;
chomp
$s
;
my
(
$name
,
$rest1
) =
$s
=~ m{^([\w -]+):[ \t]*(.*)\z}sx
or
die
"no name match: '$s'"
;
chomp
$rest1
;
if
(
$rest1
=~ m{^N/A\s*\z}sx) {
ValueNA(
$name
)
}
else
{
my
(
$value
,
$unit
,
$rest
)
=
$rest1
=~ m{^([+-]?\d+(?:\.\d*)?)\s*([°A-Za-z]\w*)\s*(.*)\z}sx
or
die
"no values match: '$rest1'"
;
Value(
$name
,
$value
,
$unit
,
$rest
)
}
}
TEST {
parse_value 'fan1: 3770 RPM
'
}
Value(
'fan1'
,
'3770'
,
'RPM'
,
''
);
sub
parse_measurement {
my
(
$str
,
$time
) =
@_
;
my
@groups
=
map
{
my
$s
=
$_
;
my
(
$groupname
,
$groupvalues
) =
$s
=~ m{^([\w -]+)\n
(.*)
\z}sx
or
die
"no group match: '$s'"
;
my
@values
=
map
{ parse_value
$_
}
split
/\n/,
$groupvalues
;
ValueGroup(
$groupname
, array_to_purearray \
@values
)
}
split
/\n\n/,
$str
;
Measurement(
$time
, array_to_purearray \
@groups
)
}
sub
sensors_get_string {
my
$p
= Chj::IO::Command->new_sender({
LANG
=>
"C"
},
"sensors"
,
"-A"
);
$p
->set_encoding(
"utf-8"
);
my
$str
=
$p
->xcontent;
$p
->xxfinish;
$str
}
sub
sensors_get {
parse_measurement(sensors_get_string,
time
)
}
my
$s
= 'acpitz-virtual-0
temp1: +40.0°C (crit = +127.0°C)
temp2: +38.0°C (crit = +104.0°C)
coretemp-isa-0000
Core 0: +35.0°C (high = +105.0°C, crit = +105.0°C)
Core 1: +37.0°C (high = +105.0°C, crit = +105.0°C)
thinkpad-isa-0000
fan1: 3770 RPM
temp1: +40.0°C
temp2: +53.0°C
temp3: N/A
temp4: +44.0°C
temp5: +33.0°C
temp6: N/A
temp7: +32.0°C
temp8: N/A
temp9: +49.0°C
temp10: +39.0°C
temp11: N/A
temp12: N/A
temp13: N/A
temp14: N/A
temp15: N/A
temp16: N/A
';
my
$m
;
TEST {
$m
= parse_measurement(
$s
, 1234567)
}
Measurement(
1234567,
purearray(
ValueGroup(
'acpitz-virtual-0'
,
purearray(
Value(
'temp1'
,
'+40.0'
,
'°C'
,
'(crit = +127.0°C)'
),
Value(
'temp2'
,
'+38.0'
,
'°C'
,
'(crit = +104.0°C)'
)
)
),
ValueGroup(
'coretemp-isa-0000'
,
purearray(
Value(
'Core 0'
,
'+35.0'
,
'°C'
,
'(high = +105.0°C, crit = +105.0°C)'
),
Value(
'Core 1'
,
'+37.0'
,
'°C'
,
'(high = +105.0°C, crit = +105.0°C)'
)
)
),
ValueGroup(
'thinkpad-isa-0000'
,
purearray(
Value(
'fan1'
,
'3770'
,
'RPM'
,
''
),
Value(
'temp1'
,
'+40.0'
,
'°C'
,
''
),
Value(
'temp2'
,
'+53.0'
,
'°C'
,
''
),
ValueNA(
'temp3'
),
Value(
'temp4'
,
'+44.0'
,
'°C'
,
''
),
Value(
'temp5'
,
'+33.0'
,
'°C'
,
''
),
ValueNA(
'temp6'
),
Value(
'temp7'
,
'+32.0'
,
'°C'
,
''
),
ValueNA(
'temp8'
),
Value(
'temp9'
,
'+49.0'
,
'°C'
,
''
),
Value(
'temp10'
,
'+39.0'
,
'°C'
,
''
),
ValueNA(
'temp11'
),
ValueNA(
'temp12'
),
ValueNA(
'temp13'
),
ValueNA(
'temp14'
),
ValueNA(
'temp15'
),
ValueNA(
'temp16'
)
)
)
)
);
TEST {
purearray(
Selector(
'coretemp-isa-0000'
,
'Core 1'
),
Selector(
'thinkpad-isa-0000'
,
'temp14'
)
)->
map
(
sub
{
my
(
$sel
) =
@_
;
$m
->
select
(
$sel
)->value_or(
"no val"
)
}
)
}
purearray(
'+37.0'
,
"no val"
);
1