diff --git a/fhem/FHEM/95_PostMe.pm b/fhem/FHEM/95_PostMe.pm new file mode 100644 index 000000000..a75433df4 --- /dev/null +++ b/fhem/FHEM/95_PostMe.pm @@ -0,0 +1,1186 @@ +######################################################################################## +# +# PostMe.pm +# +# FHEM module to set up a system of sticky notes, similar to Post-Its +# +# Prof. Dr. Peter A. Henning +# +# $Id$ +# +# Not named Post-It, which is a trademark of 3M +# +######################################################################################## +# +# This programm 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. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script 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. +# +######################################################################################## + +package main; + +use strict; +use warnings; +use vars qw(%defs); # FHEM device/button definitions +use vars qw(%intAt); # FHEM at definitions +use vars qw($FW_RET); # Returned data (html) +use vars qw($FW_RETTYPE); # image/png or the like +use vars qw($FW_wname); # Web instance + +######################### +# Global variables +my $postmeversion = "1.0"; +my $FW_encoding = "UTF-8"; + +######################################################################################### +# +# PostMe_Initialize +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub PostMe_Initialize ($) { + my ($hash) = @_; + + my $devname = $hash->{NAME}; + + $hash->{DefFn} = "PostMe_Define"; + $hash->{SetFn} = "PostMe_Set"; + $hash->{GetFn} = "PostMe_Get"; + $hash->{UndefFn} = "PostMe_Undef"; + $hash->{InitFn} = "PostMe_Init"; + $hash->{AttrFn} = "PostMe_Attr"; + $hash->{AttrList} = "postmeTTSDev postmeMsgFun postme[0-9]+MsgRec postmeMailFun postme[0-9]+MailRec postmeStd postmeIcon postmeStyle:test,jQuery,HTML,SVG postmeClick:0,1 ".$readingFnAttributes; + + $data{FWEXT}{"/PostMe_widget"}{FUNC} = "PostMe_widget"; + $data{FWEXT}{"/PostMe_widget"}{FORKABLE} = 1; + + return undef; +} + +######################################################################################### +# +# PostMe_Define - Implements DefFn function +# +# Parameter hash = hash of device addressed, def = definition string +# +######################################################################################### + +sub PostMe_Define ($$) { + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + my $now = time(); + my $devname = $hash->{NAME}; + + $modules{PostMe}{defptr}{$a[0]} = $hash; + + readingsBeginUpdate($hash); + readingsBulkUpdate($hash,"state","Initialized"); + readingsEndUpdate($hash,1); + InternalTimer(gettimeofday()+2, "PostMe_Init", $hash,0); + + return undef; +} + +######################################################################################### +# +# PostMe_Undef - Implements Undef function +# +# Parameter hash = hash of device addressed, def = definition string +# +######################################################################################### + +sub PostMe_Undef ($$) { + my ($hash,$arg) = @_; + + RemoveInternalTimer($hash); + + return undef; +} + +######################################################################################### +# +# PostMe_Attr - Implements Attr function +# +# Parameter hash = hash of device addressed, ??? +# +######################################################################################### + +sub PostMe_Attr($$$) { + my ($cmd, $name, $attrName, $attrVal) = @_; + return; +} + +######################################################################################### +# +# PostMe_Init - Check, if default PostMes have been defined +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub PostMe_Init($) { + my ($hash) = @_; + my $devname = $hash->{NAME}; + my $now = time(); + my $err = 0; + + #-- current number of PostMes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + my @std = split(',',AttrVal("$devname","postmeStd",undef)); + + for( my $i=0;$i{NAME}; + my ($loop,$res); + + #-- current number of PostMes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + + for( $loop=1;$loop<=$cnop;$loop++){ + $res = ReadingsVal($devname, sprintf("postme%02dName",$loop), undef); + last + if($res eq $name); + } + #-- no PostMe with this name + if( $res ne $name ){ + return undef; + }else{ + return $loop; + } + } + +######################################################################################### +# +# PostMe_Create - Create a new PostMe +# +# Parameter hash = hash of device addressed +# name = name of PostMe +# +######################################################################################### + +sub PostMe_Create($$) { + my ($hash,$name) = @_; + my $devname = $hash->{NAME}; + + if( PostMe_Check($hash,$name) ){ + my $mga = "Error, a PostMe named $name does already exist"; + Log 1,"[PostMe_Create] $mga"; + return "$mga"; + } + + #-- current number of PostMes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + $cnop++; + + readingsBeginUpdate($hash); + readingsBulkUpdate($hash, sprintf("postme%02dName",$cnop),$name); + readingsBulkUpdate($hash, sprintf("postme%02dCont",$cnop),""); + readingsBulkUpdate($hash, "postmeCnt",$cnop); + readingsEndUpdate($hash,1); + + Log3 $devname,3,"[PostMe] Added a new PostMe named $name"; + return undef; +} + +######################################################################################### +# +# PostMe_Delete - Delete an existing PostMe +# +# Parameter hash = hash of device addressed +# name = name of PostMe +# +######################################################################################### + +sub PostMe_Delete($$) { + my ($hash,$name) = @_; + my $devname = $hash->{NAME}; + my $loop; + + if( index(AttrVal("$devname","postmeStd",""),$name) != -1){ + my $mga = "Error, the PostMe named $name is a standard PostMe and cannot be deleted"; + Log 1,"[PostMe_Delete] $mga"; + return "$mga"; + } + + my $pmn=PostMe_Check($hash,$name); + + if( !$pmn ){ + my $mga = "Error, a PostMe named $name does not exist"; + Log 1,"[PostMe_Delete] $mga"; + return "$mga"; + } + + #-- current number of PostMes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + + readingsBeginUpdate($hash); + #-- re-ordering + for( $loop=$pmn;$loop<$cnop;$loop++){ + readingsBulkUpdate($hash, sprintf("postme%02dName",$loop), + ReadingsVal($devname, sprintf("postme%02dName",$loop+1),"")); + readingsBulkUpdate($hash, sprintf("postme%02dCont",$loop), + ReadingsVal($devname, sprintf("postme%02dCont",$loop+1),"")); + } + $cnop--; + readingsBulkUpdate($hash, "postmeCnt",$cnop); + readingsEndUpdate($hash,1); + + fhem("deletereading $devname ".sprintf("postme%02dName",$cnop+1)); + fhem("deletereading $devname ".sprintf("postme%02dCont",$cnop+1)); + + Log3 $devname,3,"[PostMe] Deleted PostMe named $name"; + return undef; + } + +######################################################################################### +# +# PostMe_Rename - Renames an existing PostMe +# +# Parameter hash = hash of device addressed +# name = name of PostMe +# newname = newname of PostMe +# +######################################################################################### + +sub PostMe_Rename($$$) { + my ($hash,$name,$newname) = @_; + my $devname = $hash->{NAME}; + my $loop; + + if( index(AttrVal("$devname","postmeStd",""),$name) != -1){ + my $mga = "Error, the PostMe named $name is a standard PostMe and cannot be renamed"; + Log 1,"[PostMe_Rename] $mga"; + return "$mga"; + } + + my $pmn=PostMe_Check($hash,$name); + + if( !$pmn ){ + my $mga = "Error, a PostMe named $name does not exist"; + Log 1,"[PostMe_Rename] $mga"; + return "$mga"; + } + + my $pnn=PostMe_Check($hash,$newname); + + if( !$pnn ){ + if( ReadingsVal($devname, sprintf("postme%02dName",$pnn),"") ne ""){ + my $mga = "Error, a PostMe named $newname does already exist and is not empty"; + Log 1,"[PostMe_Rename] $mga"; + return "$mga"; + } + + #-- current number of PostMes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + + readingsBeginUpdate($hash); + #-- re-ordering + for( $loop=$pnn;$loop<$cnop;$loop++){ + readingsBulkUpdate($hash, sprintf("postme%02dName",$loop), + ReadingsVal($devname, sprintf("postme%02dName",$loop+1),"")); + readingsBulkUpdate($hash, sprintf("postme%02dCont",$loop), + ReadingsVal($devname, sprintf("postme%02dCont",$loop+1),"")); + } + $cnop--; + readingsBulkUpdate($hash, "postmeCnt",$cnop); + readingsEndUpdate($hash,1); + + fhem("deletereading $devname ".sprintf("postme%02dName",$cnop+1)); + fhem("deletereading $devname ".sprintf("postme%02dCont",$cnop+1)); + } + ReadingsSingleUpdate($hash,sprintf("postme%02dName",$pmn),$newname,1); + + Log3 $devname,3,"[PostMe] Renamed PostMe named $name into $newname"; + return undef; +} + +######################################################################################### +# +# PostMe_Add - Add something to a PostMe +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub PostMe_Add($$@) { + my ($hash,$name,@args) = @_; + my $devname = $hash->{NAME}; + + my $pmn=PostMe_Check($hash,$name); + + if( !$pmn ){ + my $mga = "Error, a PostMe named $name does not exist"; + Log 1,"[PostMe_Add] $mga"; + return "$mga"; + } + my $raw = join(' ',@args); + #-- remove meta data + my $item = $raw; + $item =~ s/\[.*\]//g; + $item =~ s/\]//g; + $item =~ s/\[//g; + #-- check old content + my $old = ReadingsVal($devname, sprintf("postme%02dCont",$pmn),""); + my $ind = index($old,$item); + if( $ind >= 0 ){ + my $mga = "Error, item $item is already present in PostMe $name"; + Log 1,"[PostMe_Add] $mga"; + return "$mga"; + } + $old .= "," + if($old ne ""); + #-- TODO: META DATA MISSING + readingsSingleUpdate($hash, sprintf("postme%02dCont",$pmn),$old.$item,1); + + Log3 $devname,3,"[Postme] Added item $item to PostMe named $name"; + return undef; + } + +######################################################################################### +# +# PostMe_Modify - Modify something from a PostMe +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub PostMe_Modify($$@) { + my ($hash,$name,@args) = @_; + my $devname = $hash->{NAME}; + + my $pmn=PostMe_Check($hash,$name); + + if( !$pmn ){ + my $mga = "Error, a PostMe named $name does not exist"; + Log 1,"[PostMe_Remove] $mga"; + return "$mga"; + } + #-- difficult to separate item from new meta data. For now, first term is the item, + # second term is the attribute and remaining terms are the value + my $item = @args[0]; + my $attr = @args[1]; + splice(@args,0,2); + my $val = join(' ',@args); + + #-- check old content + my $old = ReadingsVal($devname, sprintf("postme%02dCont",$pmn),""); + my $ind = index($old,$item); + if( $ind < 0 ){ + my $mga = "Error, item $item is not present in PostMe $name"; + Log 1,"[PostMe_Remove] $mga"; + return "$mga"; + } + #-- item + my @lines = split(',',$old); + my $new = ""; + for( my $loop=0;$loop{NAME}; + + my $pmn=PostMe_Check($hash,$name); + + if( !$pmn ){ + my $mga = "Error, a PostMe named $name does not exist"; + Log 1,"[PostMe_Remove] $mga"; + return "$mga"; + } + my $raw = join(' ',@args); + #-- remove meta data + my $item = $raw; + $item =~ s/\[.*\]//g; + #-- check old content + my $old = ReadingsVal($devname, sprintf("postme%02dCont",$pmn),""); + my $ind = index($old,$item); + if( $ind < 0 ){ + my $mga = "Error, item $item is not present in PostMe $name"; + Log 1,"[PostMe_Remove] $mga"; + return "$mga"; + } + #-- item may be a short version of the real entry + my @lines= split(',',$old); + my $new = ""; + for( my $loop=0;$loop{NAME}; + + my $pmn=PostMe_Check($hash,$name); + + if( !$pmn ){ + my $mga = "Error, a PostMe named $name does not exist"; + Log 1,"[PostMe_Clear] $mga"; + return "$mga"; + } + + readingsSingleUpdate($hash, sprintf("postme%02dCont",$pmn),"",1 ); + + Log3 $devname,3,"[PostMe] Cleared PostMe named $name"; + return undef; + } + +######################################################################################### +# +# PostMe_LineIn - format a single PostMe line from input +# +# Parameter hash = hash of device addressed +# line = raw data in the form item [att1="val1" att2="val2"] +# +######################################################################################### + +sub PostMe_LineIn($$) { + my ($hash,$line) = @_; + my $devname = $hash->{NAME}; + + } + +######################################################################################### +# +# PostMe_LineOut - format a single PostMe line for output +# +# Parameter hash = hash of device addressed +# line = raw data in the form item [att1="val1" att2="val2"] +# format = 0 - item only +# +######################################################################################### + +sub PostMe_LineOut($$$) { + my ($hash,$line,$format) = @_; + my $devname = $hash->{NAME}; + my ($i,$line2,$item,$meat,$new,@lines,%meta); + + #Log 1,"LINEOUT format = $format, line=$line"; + + #-- format == 0 - single item line + if( $format < 10){ + $item = $line; + $item =~ s/\s+\[.*//; + $line =~ s/.*\[//; + $line =~ s/\]//; + my @list1 = split(/ /,$line); + foreach my $item2(@list1) { + my ($i,$j)= split(/=/, $item2); + $meta{$i} = $j; + } + #Log 1,"line=$line, item=$item"; + return $item; + + #-- formats >= 10 for all items in a PostMe + }elsif( $format >= 10){ + my @lines = split(',',$line); + my $new = ""; + my $item; + my $meat; + + for( my $loop=0;$loop=0 ){ + $item = substr($line2,0,$i); + $meat = substr($line2,$i); + $item =~ s/\s*$//; + $meat =~ s/.*\[//; + $meat =~ s/\]//; + my @list1 = split('" ',$meat); + foreach my $item2(@list1) { + my ($i,$j)= split(/=/, $item2); + $j =~ s/^"//; + $meta{$i} = $j; + Log 1,"Setting META $i to VALUE $j"; + } + }else{ + $item = $line2; + $meat = ""; + $item =~ s/\s*$//; + } + #-- plain format, item only + $new .= $item.',' + if( $format == 10); + + #-- meta data in brackets + if( $format == 11){ + if( $meat ne "" ){ + $new .= $item.'('.$meat.'),'; + }else{ + $new .= $item.','; + } + } + + #-- json format by hand + if( $format == 15 ){ + $new .= '{"item": "'.$item.'"'; + if( $meat ne "" ){ + $new .= ',"meta": {'; + foreach my $k (keys %meta){ + $new .= '"'.$k.'": "'.$meta{$k}.'",'; + } + $new .= '}'; + } + $new .= '},'; + } + } + $new =~ s/""/"/g; + $new =~ s/,}/}/g; + $new =~ s/,$//; + return $new; + } + } + +######################################################################################### +# +# PostMe_Set - Implements the Set function +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub PostMe_Set($@) { + my ( $hash, $name, $key, @args ) = @_; + + #-- for the selector: which values are possible + if ($key eq "?"){ + my @cmds = ("create","delete","rename","add","modify","remove","clear"); + return "Unknown argument $key, choose one of " .join(" ",@cmds); + } + + my $value = shift @args; + #Log 1,"[PostMe_Set] called with key ".$key." and value ".$value; + + if( $key eq "create"){ + PostMe_Create($hash,$value); + + }elsif( $key eq "delete"){ + PostMe_Delete($hash,$value); + + }elsif( $key eq "rename"){ + PostMe_Remove($hash,$value,@args); + + }elsif( $key eq "add"){ + PostMe_Add($hash,$value,@args); + + }elsif( $key eq "modify"){ + PostMe_Modify($hash,$value,@args); + + }elsif( $key eq "remove"){ + PostMe_Remove($hash,$value,@args); + + }elsif( $key eq "clear"){ + PostMe_Clear($hash,$value); + } +} + +######################################################################################### +# +# PostMe_Get - Implements the Get function +# +# Parameter hash = hash of device addressed +# +######################################################################################### + +sub PostMe_Get($$$@) { + my ($hash, $name, $key, @args) = @_; + my $pmn; + my $res = ""; + my $devname = $hash->{NAME}; + + #Log 1,"[PostMe_Get] with name=$name key=$key args=@args"; + + my $hasMail = defined(AttrVal($devname,"postmeMailFun",undef)) ? 1 : 0; + my $hasMsgr = defined(AttrVal($devname,"postmeMsgFun",undef)) ? 1 : 0; + my $hasTTS = defined(AttrVal($devname,"postmeTTSDev",undef)) ? 1 : 0; + + #-- for the selector: which values are possible + if ($key eq "?"){ + #-- current number of PostMes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + my $pml = ""; + for( my $i=1;$i<=$cnop;$i++){ + $pml .= "," + if( $i >1); + $pml .= ReadingsVal($devname, sprintf("postme%02dName",$i),""); + } + my @cmds = ("version:noArg","all:noArg","list:".$pml); + $res = "Unknown argument $key choose one of ".join(" ",@cmds); + $res.= " mail:".$pml + if($hasMail); + $res.= " message:".$pml + if($hasMsgr); + $res.= " ttsSay:".$pml + if($hasTTS); + $res.= " z_JSON:".$pml; + + return $res; + } + + Log 1,"[PostMe_Get] with key=$key"; + + if ($key eq "version") { + return "PostMe.version => $postmeversion"; + + #-- list one PostMe + } elsif( ($key eq "list")||($key eq "z_JSON")||($key eq "mail")||($key eq "message")||($key eq "ttsSay") ){ + + $pmn = PostMe_Check($hash,$args[0]); + if( !$pmn ){ + my $mga = "Error, a PostMe named $name does not exist"; + Log 1,"[PostMe_Get] $mga"; + return "$mga"; + } + ##-- list + if( $key eq "list" ){ + $res = ReadingsVal($devname, sprintf("postme%02dName",$pmn),""); + $res .= ": "; + $res .= PostMe_LineOut($hash,ReadingsVal($devname, sprintf("postme%02dCont",$pmn),"")."\n",10); + return $res; + + ##-- JSON + }elsif( $key eq "z_JSON" ){ + my $line = ReadingsVal($devname, sprintf("postme%02dName",$pmn),""); + $res = PostMe_LineOut($hash,ReadingsVal($devname, sprintf("postme%02dCont",$pmn),""),15); + return '{"'.$line.'": ['.$res.']}'; + + ##-- send by mail + }elsif( $key eq "mail" ){ + my $rcpt = AttrVal($devname,sprintf("postme%02dMailRec",$pmn),undef); + my $sbjt = ReadingsVal($devname, sprintf("postme%02dName",$pmn),undef); + my $text = PostMe_LineOut($hash,ReadingsVal($devname, sprintf("postme%02dCont",$pmn),undef),11); + my $fun = AttrVal($devname,"postmeMailFun",undef); + + if( $rcpt && $sbjt && $text && $fun ){ + my $ref = \&$fun; + &$ref($rcpt,$sbjt,$text); + } + my $mga = "$sbjt sent by mail"; + readingsSingleUpdate($hash,"state",$mga,1 ); + Log3 $devname,3,"[PostMe] ".$mga; + return undef; + + ##-- send by instant messenger + }elsif( $key eq "message" ){ + my $rcpt = AttrVal($devname,sprintf("postme%02dMsgRec",$pmn),undef); + my $sbjt = ReadingsVal($devname, sprintf("postme%02dName",$pmn),undef); + my $text = PostMe_LineOut($hash,ReadingsVal($devname, sprintf("postme%02dCont",$pmn),undef),11); + my $fun = AttrVal($devname,"postmeMsgFun",undef); + + if( $rcpt && $sbjt && $text && $fun ){ + my $ref = \&$fun; + &$ref($rcpt,$sbjt,$text); + } + my $mga = "$sbjt sent by messenger"; + readingsSingleUpdate($hash,"state",$mga,1 ); + Log3 $devname,3,"[PostMe] ".$mga; + return undef; + + ##-- speak as TTS + }elsif( $key eq "ttsSay" ){ + my $sbjt = ReadingsVal($devname, sprintf("postme%02dName",$pmn),undef); + my $text = PostMe_LineOut($hash,ReadingsVal($devname, sprintf("postme%02dCont",$pmn),undef),10); + $text =~ s/,/\/g; + my $dev = AttrVal($devname,"postmeTTSDev",undef); + + if( $sbjt && $text && $dev ){ + fhem('set '.$dev.' ttsSay '.$sbjt.' enthält '.$text); + } + my $mga = "$sbjt spoken by TTS"; + readingsSingleUpdate($hash,"state",$mga,1 ); + Log3 $devname,3,"[PostMe] ".$mga; + return undef; + } + + #-- list all PostMe + } elsif ($key eq "all") { + #-- current number of PostMes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + + for( my $loop=1;$loop<=$cnop;$loop++){ + $res .= ReadingsVal($devname, sprintf("postme%02dName",$loop),""); + $res .= ": ".PostMe_LineOut($hash,ReadingsVal($devname, sprintf("postme%02dCont",$loop),"")."\n",10); + } + return $res; + } +} + +######################################################################################### +# +# PostMe_widget - Displays PostMes as widgets +# +# Parameter = web argument list +# +######################################################################################### + +sub PostMe_widget($) { + my ($arg) = @_; + my $type = $FW_webArgs{type}; + $type = "show" + if( !$type); + my $devname= $FW_webArgs{postit}; + my $name = $FW_webArgs{name}; + my $pmn; + my $res = ""; + + #-- device name + if( !$devname ){ + Log 1,"[PostMe_widget] Error, web argument postit=... is missing"; + return undef; + } + + my $hash = $defs{$devname}; + my $style = AttrVal($devname,"postmeStyle","jQuery"); + my $icon = AttrVal($devname,"postmeIcon","images/default/pin_red_32.png"); + my $click = AttrVal($devname,"postmeClick","0"); + my $css = ''; + + ##################################################-- type=pins => list with pins + if( $type eq "pins"){ + #-- current number of Postmes + my $cnop = ReadingsVal($devname,"postmeCnt",0); + + #-- jQuery rendering + if( $style eq "jQuery" ){ + $FW_RETTYPE = "text/html"; + $FW_RET=""; + $res .= $css; + #-- we need our own jQuery object + $res .= ''; + $res .= ''; + + #-- this is for the selector + $res .= '
'; + for( my $loop=1;$loop<=$cnop;$loop++){ + my $name = ReadingsVal($devname, sprintf("postme%02dName",$loop),""); + my $sel = sprintf("sel%02d",$loop); + $res .= '
'.$name.'

'; + }; + $res .= '
'; + + #-- this is the scripting for the dialog box + $res .= ''; + FW_pO $res; + + #-- HTML rendering + }elsif( $style eq "HTML"){ + $FW_RETTYPE = "text/html; charset=$FW_encoding"; + $FW_RET=""; + $res .= $css; + $res .= '
'; + for( my $loop=1;$loop<=$cnop;$loop++){ + my $name = ReadingsVal($devname, sprintf("postme%02dName",$loop),""); + if( $click == 0){ + $res .= '
'.$name.'

'; + }else{ + $res .= '
'; + $res .= ''.$name.'

'; + } + } + FW_pO $res.'
'; + + #-- SVG rendering + }else{ + $FW_RETTYPE = "image/svg+xml"; + $FW_RET=""; + FW_pO ''; + for( my $loop=1;$loop<=$cnop;$loop++){ + my $name = ReadingsVal($devname, sprintf("postme%02dName",$loop),""); + $res.= sprintf(''; + $res.= + } + FW_pO $res.''; + } + return ($FW_RETTYPE, $FW_RET); + } + + #-- PostMe name + if( !$name ){ + Log 1,"[PostMe_widget] Error, web argument name=... is missing"; + return undef; + } + + $pmn = PostMe_Check($hash,$name); + if( !$pmn ){ + Log 1,"[PostMe_widget] Error, a PostMe named $name does not exist"; + return undef; + } + + ##################################################-- type=pin => single pin + if( $type eq "pin"){ + #-- jQuery rendering + if( $style eq "jQuery"){ + + my $name = ReadingsVal($devname, sprintf("postme%02dName",$pmn),""); + my $sel = sprintf("sel%02d",$pmn); + + $FW_RETTYPE = "text/html"; + $FW_RET=""; + $res .= $css; + #-- we need our own jQuery object + $res .= ''; + $res .= ''; + + #-- this is for the selector + $res .= '
'; + $res .= '
'.$name.'

'; + $res .= '
'; + + #-- this is the scripting for the dialog box + $res .= ''; + FW_pO $res; + + #-- HTML rendering + }elsif( $style eq "HTML"){ + $FW_RETTYPE = "text/html"; + $FW_RET=""; + $res .= $css; + $res .= '
'; + my $name = ReadingsVal($devname, sprintf("postme%02dName",$pmn),""); + if( $click == 0){ + $res.= '
'; + } + FW_pO $res.''.$name.'
'; + + #-- SVG rendering + }else{ + $FW_RETTYPE = "image/svg+xml"; + $FW_RET=""; + FW_pO ''; + my $name = ReadingsVal($devname, sprintf("postme%02dName",$pmn),""); + $res.= ''; + FW_pO $res.''; + } + return ($FW_RETTYPE, $FW_RET); + } + + ################################################## default (type missing) => content of a single postme + + my @lines=split(',',ReadingsVal($devname, sprintf("postme%02dCont",$pmn),"")); + if( !(int(@lines)>0) ){ + Log 1,"[PostMe_widget] Asking to display empty PostMe $name"; + return undef; + } + + #-- HTML rendering + if( $style ne "SVG"){ + $FW_RETTYPE = "text/html; charset=$FW_encoding"; + $FW_RET=""; + $res .= $css; + $res .= '
'; + $res .= ''.$name.'
'; + for (my $i=0;$i'; + } + FW_pO $res.'
'; + + #--- SVG rendering + }else{ + $FW_RETTYPE = "image/svg+xml"; + $FW_RET=""; + FW_pO ''; + + $res = ''; + $res.= $name.''; + for (my $i=0;$i',25+$i*12); + $res.= PostMe_LineOut($hash,$lines[$i],0); + $res.= ''; + } + FW_pO $res.''; + + } + return ($FW_RETTYPE, $FW_RET); +} + +1; + +=pod +=item helper +=item summary to set up a system of sticky notes, similar to Post-Its™ +=begin html + + +

PostMe

+

FHEM module to set up a system of sticky notes, similar to Post-Its™

+ + +

Define

+

+ define <postit> PostMe +
Defines the PostMe system, <postit> is an arbitrary name for the system.

+ +

Usage

+ Special meta data for items may be included by using "[" and "]"; characters, e.g. + set <postit> add <name> <item> [<attribute1>="<data1>" ... + The attribute-value pairs may be added,modified and removed with the set modify command, see below. + The sticky notes may be integrated into any Web page by simply embedding the following tags +
    +
  • <embed src="/fhem/PostMe_widget?type=pins&postit=<postit>"/>
    + to produce an interactive list of all PostMe names with pins from system <postit>.
  • +
  • <embed src="/fhem/PostMe_widget?type=pin&postit=<postit>&name=<name>"/>
    + to produce an interactive entry for PostMe <name>from system <postit>
  • +
+ + +

Set

+
    +
  • set <postit> create <name> +
    creates a sticky note named <name>
  • +
  • set <postit> rename <name> <newname> +
    renames the sticky note named <name> as <newname>
  • +
  • set <postit> delete <name> +
    deletes the sticky note named <name>
  • +
  • set <postit> add <name> <item> +
    adds to the sticky note named <name> an item <item>
  • +
  • set <postit> modify <name> <item> <attribute> <data> +
    adds/modifies/removes and attribute-value-pair <attribute>="<data>" to the item <item> on the sticky note named <name>
    + adding, if this attribute is not yet present; modification, if it is present - <data> will then be overwritten; removal, if no <data> is given
  • +
  • set <postit> remove <name> <item> +
    removes from the sticky note named <name> an item <item>
  • +
  • set <postit> clear <name> +
    clears the sticky note named <name> from all items
  • + +
+ +

Get

+
    +
  • get <postit> version +
    Display the version of the module
  • +
  • get <postit> all +
    Show all sticky notes and their content
  • +
  • get <postit> list <name> +
    Show the sticky note named <name> and its content
  • +
  • get <postit> mail <name> +
    Send the sticky note named <name> and its content via eMail to a predefined + recipient (e.g. sticky note is sent to ).
  • +
  • get <postit> message <name> +
    Send the sticky note named <name> and its content via instant messenger to a predefined + recipient (e.g. sticky note is sent to ). The messenger + subroutine is called with three parameters for recipient, subject + and text.
  • +
  • get <postit> ttsSay <name> +
    Speak the sticky note named <name> and its content on a predefined + device
  • +
+ +

Attributes

+
    +
  • attr <postit> postmeStd <name1,name2,...> +
    Comma separated list of standard sticky notes that will be created on device start.
  • +
  • attr <postit> postmeClick 1|0 (default) +
    If 0, embedded sticky notes will pop up on mouseover-events and vanish on mouseout-events (default).
    + If 1, embedded sticky notes will pop up on click events and vanish after closing the note
  • +
  • attr <postit> postmeicon <string> +
    Icon for display of a sticky note
  • +
  • attr <postit> postmeStyle SVG|HTML|jQuery (default) +
    If jQuery, embedded sticky notes will produce jQuery code (default)
    + If HTML, embedded sticky notes will produce HTML code
    + If SVG, embedded sticky notes will produce SVG code
  • +
  • attr <postit> postmeMailFun <string> +
    Function name for the eMail function. This subroutine + is called with three parameters for recipient, subject + and text.
  • +
  • attr <postit> postmeMsgFun <string> +
    Function name for the instant messenger function. This subroutine + is called with three parameters for recipient, subject + and text.
  • +
  • attr <postit> postmeTTSDev <string> +
    Device name for the TTS function.
  • +
  • Standard attributes alias, comment, event-on-update-reading, event-on-change-reading, room, eventMap, loglevel, + webCmd
  • +
+=end html +=begin html_DE + + +

PostMe

+ +=end html_DE +=cut