From 2df1f65db04aa5508d3b4507c4c8363148cee0a4 Mon Sep 17 00:00:00 2001
From: herrmannj <>
Date: Fri, 18 Jun 2021 00:11:25 +0000
Subject: [PATCH] 59_Netzfrequenz.pm: initial version
git-svn-id: https://svn.fhem.de/fhem/trunk@24653 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/FHEM/59_Netzfrequenz.pm | 244 +++++++++++++++++++++++++++++++++++
1 file changed, 244 insertions(+)
create mode 100755 fhem/FHEM/59_Netzfrequenz.pm
diff --git a/fhem/FHEM/59_Netzfrequenz.pm b/fhem/FHEM/59_Netzfrequenz.pm
new file mode 100755
index 000000000..89b61da01
--- /dev/null
+++ b/fhem/FHEM/59_Netzfrequenz.pm
@@ -0,0 +1,244 @@
+# $Id$
+###############################################################################
+#
+# This file is part of fhem.
+#
+# Fhem is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Fhem is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with fhem. If not, see .
+#
+#
+###############################################################################
+
+package main;
+
+use 5.018;
+use feature qw( lexical_subs );
+
+use strict;
+use warnings;
+use utf8;
+use Carp qw(croak carp);
+use HttpUtils;
+use Scalar::Util qw ( looks_like_number );
+use Time::HiRes qw ( gettimeofday );
+
+sub Netzfrequenz_Initialize {
+ my ($hash) = @_;
+
+ my @attrList;
+ {
+ no warnings qw( qw );
+ @attrList = qw(
+ disable:0,1
+ interval
+ processing
+ );
+ };
+
+ $hash->{'DefFn'} = 'Netzfrequenz_Define';
+ $hash->{'UndefFn'} = 'Netzfrequenz_Undef';
+ $hash->{'DeleteFn'} = 'Netzfrequenz_Delete';
+ #$hash->{'SetFn'} = 'Netzfrequenz_Set';
+ #$hash->{'GetFn'} = 'Netzfrequenz_Get';
+ $hash->{'AttrFn'} = 'Netzfrequenz_Attr';
+ #$hash->{'NotifyFn'} = 'Netzfrequenz_Notify';
+ $hash->{'RenameFn'} = 'Netzfrequenz_Rename';
+ $hash->{'AttrList'} = join(' ', @attrList)." $readingFnAttributes ";
+
+ return undef;
+};
+
+sub Netzfrequenz_Define {
+ my ($hash) = @_;
+
+ my $cvsid = '$Id$';
+ $cvsid =~ s/^.*pm\s//;
+ $cvsid =~ s/Z\s\S+\s\$$/ UTC/;
+ $hash->{'SVN'} = $cvsid;
+
+ return "no FUUID, is fhem up to date?" if (not $hash->{'FUUID'});
+ InternalTimer(0, \&Netzfrequenz_Run, $hash);
+ return;
+};
+
+# reread / temporary remove
+sub Netzfrequenz_Undef {
+ my ($hash, $name) = @_;
+ Netzfrequenz_StopTimer($hash);
+ return;
+};
+
+# delete / permanently remove
+sub Netzfrequenz_Delete {
+ my ($hash, $name) = @_;
+ my $error;
+ Netzfrequenz_StopTimer($hash);
+ return $error;
+};
+
+sub Netzfrequenz_Run {
+ my ($hash) = @_;
+ my $name = $hash->{'NAME'};
+ return if IsDisabled($name);
+ Netzfrequenz_StartTimer($hash, 1);
+ return;
+};
+
+sub Netzfrequenz_Set {
+ my ($hash, $name, $cmd, @args) = @_;
+
+ my @cmds = qw( );
+ return sprintf ("Unknown argument $cmd, choose one of %s", join(' ', @cmds)) unless (any {$cmd eq $_} @cmds);
+ return;
+};
+
+sub Netzfrequenz_Attr {
+ my ($cmd, $name, $attrName, $attrValue) = @_;
+ my $hash = $defs{$name};
+ $attrValue //= '';
+
+ if ($cmd eq 'set') {
+ if ($attrName eq 'disable') {
+
+ };
+ if ($attrName eq 'interval') {
+
+ };
+
+ if (($attrName eq 'processing') and ($attrValue !~ m/^\s*{.*}\s*$/s)) {
+ return 'must be perl code enclosed in curly brackets';
+ };
+ };
+ if ($cmd eq 'del') {
+ if ($attrName eq 'disable') {
+
+ };
+ if ($attrName eq 'interval') {
+
+ };
+ };
+ return;
+};
+
+sub Netzfrequenz_Rename {
+ my ($name) = @_;
+ my $hash;
+
+ if (exists($defs{$name})) {
+ $hash = $defs{$name};
+ } else {
+ # should not happen
+ croak('cannot find me..');
+ };
+
+ if (ref($hash->{param}) eq 'HASH') {
+ $hash->{param}->{name} = $name;
+ };
+};
+
+sub Netzfrequenz_StartTimer {
+ my ($hash, $timeout) = @_;
+ my $ts = gettimeofday() + $timeout;
+ InternalTimer($ts, \&Netzfrequenz_ApiRequest, $hash);
+ return;
+};
+
+sub Netzfrequenz_ApiRequest {
+ my ($hash) = @_;
+
+ $hash->{param} //= {
+ url => "https://www.netzfrequenz.info/json/act.json",
+ timeout => 5,
+ name => $hash->{NAME}, # prevent circular ref
+ method => "GET",
+ keepalive => 1,
+ header => "User-Agent: fhem/Netzfrequenz $hash->{SVN}\r\nccept-Charset: utf-8, iso-8859-1",
+ httpversion => "1.1",
+ callback => \&Netzfrequenz_ApiResponse
+ };
+
+ HttpUtils_NonblockingGet($hash->{param});
+ return;
+};
+
+sub Netzfrequenz_ApiResponse {
+ my ($param, $err, $data) = @_;
+
+ #use Data::Dumper;
+ #print Dumper $param;
+
+ my $name = $param->{name};
+ my $hash;
+
+ if (exists($defs{$name})) {
+ $hash = $defs{$name};
+ };
+
+ # should not happen
+ croak('cannot find me..') unless $hash;
+
+ my $timeout = 1;
+
+ if ($data and looks_like_number($data)) {
+ my $actual = sprintf('%.3f', $data);
+
+ readingsBeginUpdate($hash);
+ readingsBulkUpdate($hash, 'frequency', $actual);
+ readingsEndUpdate($hash, 1);
+
+ if (my $p = AttrVal($name, 'processing', undef)) {
+ local $_ = $actual;
+ if ($p =~ m/^\s*{.*}\s*$/s) {
+ eval $p;
+ # } else {
+ # $p =~ s/\$_/$actual/g;
+ # eval "fhem $p";
+ # say "fhem '$p'";
+ # say $@ if $@;
+ };
+ };
+ } else {
+ $timeout = 60;
+ };
+
+ Netzfrequenz_StartTimer($hash, $timeout);
+ return;
+};
+
+1;
+
+=pod
+=item device
+=item summary shows the actual frenquency of the german power grid
+=item summary_DE zeigt die aktuelle Netzfrequenz an
+=begin html
+
+
+
Netzfrequenz
+
+ displays the actual frenquency of the german power grid
+
+
+
+
+ Define
+
+ define <name> Netzfrequenz
+
+ defines the device.
+
+
+
+=end html
+
+=cut