# $Id$
#
# TODO:
package main;
use strict;
use warnings;
use SetExtensions;
sub
CustomReadings_Initialize($)
{
my ($hash) = @_;
$hash->{DefFn} = "CustomReadings_Define";
$hash->{UndefFn} = "CustomReadings_Undef";
$hash->{AttrList} = "readingDefinitions "
. "interval "
. "$readingFnAttributes";
}
sub
CustomReadings_Define($$)
{
my ($hash, $def) = @_;
my $name = $hash->{NAME};
CustomReadings_read($hash);
return undef;
}
sub CustomReadings_read($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+ AttrVal( $name, "interval", 5), "CustomReadings_read", $hash, 0);
# Get the readingDefinitions and remove all newlines from the attribute
my $readingDefinitions = AttrVal( $name, "readingDefinitions", "");
$readingDefinitions =~ s/\n//g;
my @used = ("state");
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);
push(@used, $definition[0]);
my $value = eval($definition[1]);
if($value) {
$value =~ s/^\s+|\s+$//g;
}
else {
$value = "ERROR";
}
readingsBulkUpdate($hash, $definition[0], $value);
}
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 .= "
";
foreach my $reading (keys %{$hash->{READINGS}}) {
$result .= "";
$result .= "$reading: | " . ReadingsVal($name, $reading, "???") . " | ";
$result .= "
";
}
$result .= "
";
return $result;
}
1;
=pod
=begin html
CustomReadings
FHEM module to define own readings.
This module allows to define own readings. The readings can be defined in an attribute so that they can get changed without changing the code of the module.
To use this module you should have some perl and linux knowledge
The examples presuppose that you run FHEM on a linux machine like a Raspberry Pi or a Cubietruck.
Note: the "bullshit" definition is an example to show what happens if you define bullshit :-)
Example (definition in fhem.cfg)
define myReadings CustomReadings
attr myReadings room 0-Test
attr myReadings group Readings
attr myReadings interval 2
attr myReadings readingDefinitions hdd_temperature:qx(hddtemp /dev/sda 2>&1),
ac_powersupply_voltage:qx(cat /sys/class/power_supply/ac/voltage_now 2>&1) / 1000000,
ac_powersupply_current:qx(cat /sys/class/power_supply/ac/current_now 2>&1) / 1000000,
perl_version:$],
timezone:qx(cat /etc/timezone 2>&1),
kernel:qx(uname -r 2>&1),
device_name:$hash->{NAME},
bullshit: $hash->{bullshit},
fhem_backup_folder_size:qx(du -ch /opt/fhem/backup | grep total | cut -d 't' -f1 2>&1)
Optionally, to display the readings:
define myReadingsDisplay weblink htmlCode {CustomReadings_GetHTML('myReadings')}
attr myReadingsDisplay group Readings
attr myReadingsDisplay room 0-Test
Resulting readings:
ac_powersupply_current |
0.236 |
2014-08-09 15:40:21 |
|
ac_powersupply_voltage |
5.028 |
2014-08-09 15:40:21 |
bullshit |
ERROR |
2014-08-09 15:40:21 |
device_name |
myReadings |
2014-08-09 15:40:21 |
fhem_backup_folder_size |
20M |
2014-08-09 15:40:21 |
hdd_temperature |
/dev/sda: TS128GSSD320: 47°C |
2014-08-09 15:40:21 |
kernel |
3.4.103-sun7i+ |
2014-08-09 15:40:21 |
perl_version |
5.014002 |
2014-08-09 15:40:21 |
timezone |
Europe/Berlin |
2014-08-09 15:40:21 |
Define
define <name> CustomReadings
Readings
As defined
Attributes
- interval
Refresh interval in seconds
- readingDefinitions
The definitions are separated by a comma. A definition consists of two parts, separated by a colon.
The first part is the name of the reading and the second part the function.
The function gets evaluated and must return a result.
Example: kernel:qx(uname -r 2>&1)
Defines a reading with the name "kernel" and evaluates the linux function uname -r
=end html
=cut
|