# $Id$ # # TODO: package main; use strict; use warnings; use SetExtensions; no if $] >= 5.017011, warnings => 'experimental::smartmatch'; #======================================================================================= sub CustomReadings_Initialize($) { my ($hash) = @_; $hash->{DefFn} = "CustomReadings_Define"; $hash->{UndefFn} = "CustomReadings_Undef"; $hash->{SetFn} = "CustomReadings_Set"; $hash->{AttrList} = "readingDefinitions " . "interval " . "$readingFnAttributes"; } #======================================================================================= sub CustomReadings_Define($$) { my ($hash, $def) = @_; my $name = $hash->{NAME}; CustomReadings_OnTimer($hash); return undef; } #======================================================================================= sub CustomReadings_OnTimer($) { my ($hash) = @_; my $name = $hash->{NAME}; RemoveInternalTimer($hash); InternalTimer(gettimeofday()+ AttrVal( $name, "interval", 5), "CustomReadings_OnTimer", $hash, 0); CustomReadings_Read($hash); } #======================================================================================= sub CustomReadings_Read($) { my ($hash) = @_; my $name = $hash->{NAME}; # Get the readingDefinitions and remove all newlines from the attribute my $readingDefinitions = AttrVal( $name, "readingDefinitions", ""); $readingDefinitions =~ s/\n//g; my @used = ("state"); my $isCombined = 0; my @combinedOutput = (); my $hasErrors = 0; readingsBeginUpdate($hash); my @definitionList = split(",", $readingDefinitions); while (@definitionList) { my $param = shift(@definitionList); while ($param && $param =~ /{/ && $param !~ /}/ ) { my $next = shift(@definitionList); last if( !defined($next) ); $param .= ",". $next; } my @definition = split(':', $param, 2); if ($definition[0] eq "COMBINED") { $isCombined = 1; my $cmdStr = $definition[1]; my $cmdTemp = eval("$cmdStr"); if (ref $cmdTemp eq 'ARRAY') { @combinedOutput = @{ $cmdTemp }; } else { @combinedOutput = split(/^/, $cmdTemp); } Log 5, "Using combined mode for customReadings: $cmdStr"; next; } else { push(@used, $definition[0]); } if($definition[1] ne "") { $isCombined = 0; } my $value; if ($isCombined) { $value = shift @combinedOutput; if (!($value)) { $value = 0; $hasErrors = 1; Log 3, "customReadings: Warning for $name: combined command for " . $definition[0] . " returned nothing or not enough lines."; } } else { $value = eval($definition[1]); } if(defined $value) { $value =~ s/^\s+|\s+$//g; } else { $value = "ERROR"; $hasErrors = 1; } readingsBulkUpdate($hash, $definition[0], $value); } readingsBulkUpdate($hash, "state", $hasErrors ? "Errors" : "OK"); readingsEndUpdate($hash, 1); foreach my $r (keys %{$hash->{READINGS}}) { if (not $r ~~ @used) { delete $hash->{READINGS}{$r}; } } } #======================================================================================= sub CustomReadings_Undef($$) { my ($hash, $arg) = @_; my $name = $hash->{NAME}; RemoveInternalTimer($hash); return undef; } #======================================================================================= sub CustomReadings_GetHTML ($) { my ($name) = @_; my $hash = $main::defs{$name}; my $result = ""; $result .= ""; my @sortedReadings = sort keys %{$hash->{READINGS}}; foreach my $reading (@sortedReadings) { $result .= ""; $result .= ""; $result .= ""; } $result .= "
$reading: " . ReadingsVal($name, $reading, "???") . "
"; return $result; } #======================================================================================= sub CustomReadings_Set($@) { my ($hash, @a) = @_; my $name = shift @a; my $cmd = shift @a; my $arg = join(" ", @a); my $list = "update"; return $list if( $cmd eq '?' || $cmd eq ''); if ($cmd eq "update") { CustomReadings_Read($hash); } else { return "Unknown argument $cmd, choose one of ".$list; } return undef; } 1; =pod =item summary Allows to define own readings. =item summary_DE Ermöglicht eingen readings. =begin html

CustomReadings

=end html =cut