diff --git a/fhem/contrib/WBS/18_WBS.pm b/fhem/contrib/WBS/18_WBS.pm new file mode 100644 index 000000000..92f3ba71e --- /dev/null +++ b/fhem/contrib/WBS/18_WBS.pm @@ -0,0 +1,122 @@ +################################################################################ +# Web based Sensors = 18_WBS.pm +# Sensors updated only via Web +# +# +# Define: +# define WBS TYPE CODE +# +# Type = READING-NAME f.e. +# CODE = Unique-Code for WBS-Sensors max. 16 Chars +# +# Example +# define WBS001 WBS Temperature 1032D8ED01080011 +# $defs$defs{WBS001}{TYPE} = WBS +# $defs$defs{WBS001}{CODE} = 12345 +# $defs{WBS001}{READINGS}{Temperature}{VAL} = 0 +# $defs{WBS001}{READINGS}{Temperature}{TIME} = TimeNow() +# Only One READING for each WBS +# +# Updates via WEB: +# MSG-Format: +# WBS:SENSOR-CODE:VALUE +# WBS -> Web Based Sensor -> matching in FHEM +# Sensor-Code -> Unique-Code for WBS-Sensors max. 16 Chars +# Value -> Data from Sensor like 18°C -> Format: INT only [1...90.-] +# max. lenght Value: -xxx.xxx 8 Chars +# max-Lenght MSG: 3:16:8 = 29 Chars +# Example: Temperature form Dallas 1820-Temp-Sensors 24.32 °Celsius +# WBS:1032D8ED01080011:23.32 +# Update via http-get-request +# http://[MY_FHEMWEB:xxxx]/fhem/rawmsg?WBS:1032D8ED01080011:23.32 +################################################################################ +package main; +use strict; +use warnings; +use POSIX; +use Data::Dumper; +use vars qw(%defs); +use vars qw(%attr); +use vars qw(%data); +# Reverse-Lokup-Pointer +my %defptr; +################################################################################ +sub WBS_Initialize($) +{ + my ($hash) = @_; + $hash->{Match} = "^WBS:"; + $hash->{DefFn} = "WBS_Define"; + $hash->{UndefFn} = "WBS_Undef"; + $hash->{ParseFn} = "WBS_Parse"; + $hash->{AttrList} = "IODEV do_not_notify:0,1 loglevel:0,5 disable:0,1"; +} +################################################################################ +sub WBS_Define($) +{ + # define WBS TYPE CODE + my ($self, $defs) = @_; + Log 0, "WBS|DEFINE: " . Dumper(@_); + Log 0, "WBS|DEFPTR: " . Dumper(%defptr); + my @a = split(/ /, $defs); + return "WBS|Define|ERROR: Unknown argument count " . int(@a) . " , usage define WBS TYPE CODE" if(int(@a) != 4); + my $Type = $a[2]; + my $Code = $a[3]; + if(defined($defptr{$Code})) { + return "WBS|Define|ERROR: Code is used"; + } + if(length($Code) > 16) { + return "WBS|Define|ERROR: Max. Length CODE > 16"; + } + $self->{CODE} = $Code; + $self->{STATE} = "NEW: " . TimeNow(); + $self->{WBS_TYPE} = $Type; + $self->{READINGS}{$Type}{VAL} = 0; + $self->{READINGS}{$Type}{TIME} = TimeNow(); + $defptr{$Code} = $self; + Log 0, "WBS|DEFPTR: " . Dumper(%defptr); + return undef; +} +################################################################################ +sub WBS_Undef($$) +{ + my ($hash, $name) = @_; + delete($defptr{$hash->{CODE}}) + if(defined($hash->{CODE}) && defined($defptr{$hash->{CODE}})); + return undef; +} +################################################################################ +sub WBS_Parse($$) +{ + my ($iodev,$rawmsg) = @_; + # MSG: WBS:1032D8ED01080011:23.32 + my ($null,$code,$value) = split(/:/, $rawmsg); + if(length($code) > 16 ) { + return "WBS|Parse|ERROR: Max. Length CODE > 16"; + } + if(length($value) > 8) { + return "WBS|Parse|ERROR: Max. Length VALUE > 8"; + } + # Find Device-Name + if(!defined($defptr{$code})) { + return "WBS|Parse|ERROR: Unkown Device for $code"; + } + Log 0, "WBS|Parse: " . Dumper(%defptr); + my $wbs = $defptr{$code}; + my $wbs_name = $wbs->{NAME}; + #LogLevel + my $ll = 0; + if(defined($attr{$wbs_name}{loglevel})) {$ll = $attr{$wbs_name}{loglevel};} + #Clean-Value + $value =~ s/[^0123456789.-]//g; + # Get Reading + my $reading = $wbs->{WBS_TYPE}; + $wbs->{READINGS}{$reading}{VAL} = $value; + $wbs->{READINGS}{$reading}{TIME} = TimeNow(); + # State: [FirstChar READING]:VALUE + my $fc = uc(substr($reading,0,1)); + $wbs->{STATE} = "$fc: $value"; + # Changed + $wbs->{CHANGED}[0] = "$reading:$value"; +} +################################################################################ +1; diff --git a/fhem/contrib/WBS/99_CGI_RAWMSG.pm b/fhem/contrib/WBS/99_CGI_RAWMSG.pm new file mode 100644 index 000000000..d4803b5dd --- /dev/null +++ b/fhem/contrib/WBS/99_CGI_RAWMSG.pm @@ -0,0 +1,119 @@ +################################################################################ +# 99_CGI_RAWMSG +# +# Route RAW-Sensor-Data via FHEMWEB/CGI to fhem.pl: Function -> disptach($$$) +# +# Examples for RAW-Sensor-Data +# WBS = WeB-Sensors +# WBS:SENSOR-CODE:SENSOR-TYPE:VALUE:TIMESTAMP +# HMS -> H909801530400F4 +# CUL_WS -> K21500163 +################################################################################ +package main; +use strict; +use warnings; +use Data::Dumper; +use vars qw(%data); +use vars qw($__ME); +################################################################################ +sub CGI_RAWMSG_Initialize($) +{ + # FHEM Part + my ($hash) = @_; + $hash->{Clients} = ":CUL_WS:HMS:WBS:"; + my %mc = ( + "1:CUL_WS" => "^K.....", + "2:HMS" => "^810e04....(1|5|9).a001", + "3:WBS" => "^WBS:", + ); + $hash->{MatchList} = \%mc; + # CGI Part + my $cgi_key = "rawmsg"; + my $cgi_name = "CGI_RAWMSG"; + # PRIV-CGI + my $fhem_url = "/" . $cgi_key ; + $data{FWEXT}{$fhem_url}{FUNC} = "CGI_RAWMSG_Dispatch"; + $data{FWEXT}{$fhem_url}{LINK} = $cgi_key; + $data{FWEXT}{$fhem_url}{NAME} = $cgi_name; + # Create IO-Device for fhem-dispatcher + $data{$cgi_key}{NAME} = $cgi_name; + $data{$cgi_key}{MatchList} = \%mc; + if(!defined($defs{$cgi_name})){ + fhem "define $cgi_name dummy"; + $defs{$cgi_name}{STATE} = "AKTIV 99_CGI_RAWMSG"; + $defs{$cgi_name}{TYPE} = "CGI_RAWMSG"; + fhem "attr $cgi_name comment DUMMY_DEVICE_FOR_99_CGI_RAWMSG"; + } + +} +################################################################################ +sub CGI_RAWMSG_Dispatch($$) +{ + my ($htmlarg) = @_; + my ($ret_param,$ret_txt,@tmp,$rawmsg,$cgikey); + Log 0, "CGI_RAWMSG|Dispatch|START: $htmlarg"; + $ret_param = "text/plain; charset=ISO-8859-1"; + $ret_txt = "ERROR;NODATA"; + print "CGI_RAWMSG|Dispatch: " . Dumper(@_) . "\n"; + # Aufurf: http://[FHEMWEB]/fhem/rawmsg?TEST12345 + # htmlarg = /rawmsg?TEST12345 + if($htmlarg =~ /\?/) { + @tmp = split(/\?/,$htmlarg); + $cgikey = shift(@tmp); + $cgikey =~ s/\///; + $rawmsg = shift(@tmp); + # HELP + if($rawmsg eq "help") { + no strict "refs"; + $ret_txt = &CGI_RAWMSG_help; + use strict "refs"; + return ($ret_param, $ret_txt); + } + # Check rawmsg + foreach my $m (sort keys %{$data{$cgikey}{MatchList}}) { + Log 0, "CGI_RAWMSG|MatchList-RAWMSG: $rawmsg"; + Log 0, "CGI_RAWMSG|MatchList-Key: $m"; + Log 0, "CGI_RAWMSG|MatchList-Val: " . $data{$cgikey}{MatchList}{$m}; + my $match = $data{$cgikey}{MatchList}{$m}; + if($rawmsg =~ m/$match/) { + Log 0, "CGI_RAWMSG|MatchList-Key FOUND: $m"; + # $ret_txt = "HTMLARG = $htmlarg\n"; + # $ret_txt .= "CGI-KEY = $cgikey\n"; + # $ret_txt .= "RAWMSG = $rawmsg\n"; + # Dummy-Device + my $name = $data{$cgikey}{NAME}; + my $hash = $defs{$name}; + $hash->{"${name}_MSGCNT"}++; + $hash->{"${name}_TIME"} = TimeNow(); + $hash->{RAWMSG} = $rawmsg; + my %addvals = (RAWMSG => $rawmsg); + my $ret_disp = &Dispatch($hash, $rawmsg, \%addvals); + if(defined($ret_disp)) {$ret_txt = "OK;" . join(";" ,@$ret_disp) . "\n";} + else {$ret_txt = "ERROR;NODEVICEFOUND";} + return ($ret_param, $ret_txt); + } + } + $ret_txt = "ERROR;NODATAMATCH"; + } + return ($ret_param, $ret_txt); +} + +################################################################################ +sub CGI_RAWMSG_help +{ + my $txt = "Route RAW-Sensor-Data via FHEMWEB/CGI to FHEM\n"; + $txt .= "FHEM.PL Function -> disptach($$$)\n"; + $txt .= "Examples for RAW-Sensor-Data \n"; + $txt .= "WBS = WeB-Sensors\n"; + $txt .= "WBS:SENSOR-CODE:SENSOR-TYPE:VALUE:TIMESTAMP\n"; + $txt .= "HMS -> H909801530400F4\n"; + $txt .= "CUL_WS -> K21500163 \n"; + retrun $txt; +} +################################################################################ +sub CGI_RAWMSG_new_iodev +{ +} +################################################################################ +1; +################################################################################