######################################################################################## # # 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.4"; 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; $hash->{FW_detailFn} = "PostMe_detailFn"; $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); Log 1,"[PostMe_Init] postme01Name ".ReadingsVal($devname,"postme01Name",0)." postme01Cont ".ReadingsVal($devname,"postme01Cont",0)." postme02Name ".ReadingsVal($devname,"postme02Name",0)." postme02Cont ".ReadingsVal($devname,"postme02Cont",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 ){ my $mga = "Error, a PostMe named $newname does already exist and is not empty"; Log 1,"[PostMe_Rename] $mga"; return "$mga"; } 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 "?"){ #--prevent any default set return undef; #-- obsolete 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 ".join(' ',@args); if( $key eq "create"){ PostMe_Create($hash,$value); }elsif( $key eq "delete"){ PostMe_Delete($hash,$value); }elsif( $key eq "rename"){ PostMe_Rename($hash,$value,@args[0]); }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 "?"){ #-- prevent any default get return undef; #-- obsolete #-- 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); $res .= "\n"; } return $res; } } ######################################################################################### # # PostMe_detailFn - Displays PostMes in detailed view of FHEM # # Parameter = web argument list # ######################################################################################### sub PostMe_detailFn(){ my ($FW_wname, $devname, $room, $pageHash) = @_; # pageHash is set for summaryFn. my $hash = $defs{$devname}; $hash->{mayBeVisible} = 1; my $pmname=$hash->{NAME}; my $pmfirst = ReadingsVal($devname, "postme01Name",""); my $pmlist=""; my $pmoption=""; #-- current number of PostMes my $cnop = ReadingsVal($devname,"postmeCnt",0); for( my $loop=1;$loop<=$cnop;$loop++){ my $n = ReadingsVal($devname, sprintf("postme%02dName",$loop),""); $pmlist .= $n; $pmlist .= "," if( $loop != $cnop); if( $loop == 1){ $pmoption .= ''; }else{ $pmoption .= ''; } } my $icon = AttrVal($devname, "icon", ""); $icon = FW_makeImage($icon,$icon,"icon") . " " if($icon); my $html = '
'. ''. ''. '
'.$icon.'
Initialized
'; $html .= ''; $html .= ''; $html .= '
'. '
'. '
 '.$pmname.' 
'. ''. ''. ''. '
'. '
'. '
 '.$pmname.' 
'. ''. ''. '
'; return $html; } ######################################################################################### # # 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

See http://www.fhemwiki.de/wiki/Modul_PostMe An arbitrary number of lists may be added to the system with the create command as set <postit> create <name> List items may consist of one or more words, and are added/removed by the add and remove command. Attention: A comma "," is the separator for list items. set <postit> add <name> <some text, but careful with commas> Special meta data for items may be included in the items by using "[" and "]"; characters, e.g. set <postit> add <name> <item> [<attribute1>="<data1>" ... These attribute-value pairs may be added, modified and removed with the modify command 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> 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
  • get <postit> JSON <name>
    Return the sticky note named <name> in JSON format
  • get <postit> all
    Show all sticky notes and their content
  • get <postit> version
    Display the version of the module

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