From 229f4db35ca37cb2f62895d537de153c335c7fd5 Mon Sep 17 00:00:00 2001 From: mfr69bs Date: Wed, 30 Jan 2013 06:11:24 +0000 Subject: [PATCH] added opt-in message git-svn-id: https://svn.fhem.de/fhem/trunk@2600 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_notice.pm | 749 ++++++++++++++++++++++++ fhem/FHEM/FhemUtils/update-20130127-001 | 138 +++++ 2 files changed, 887 insertions(+) create mode 100644 fhem/FHEM/98_notice.pm create mode 100644 fhem/FHEM/FhemUtils/update-20130127-001 diff --git a/fhem/FHEM/98_notice.pm b/fhem/FHEM/98_notice.pm new file mode 100644 index 000000000..ead6e341f --- /dev/null +++ b/fhem/FHEM/98_notice.pm @@ -0,0 +1,749 @@ +# $Id$ +# vim: ts=2:et +################################################################ +# +# Copyright notice +# +# (c) 2013 Copyright: Martin Fischer (m_fischer at gmx dot de) +# All rights reserved +# +# 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 strict; +use warnings; +use Time::Local; + +sub CommandNotice($$); +sub notice_Confirmation($$$); +sub notice_Get($$$); +sub notice_List($$); +sub notice_Read($$$); + +use vars qw(@locale); +@locale = qw(de en); + +my $confirmationFile = ".notice-confirmation"; + +######################################## +sub +notice_Initialize($$) +{ + my %hash = ( + Fn => "CommandNotice", + Hlp => "[confirm|list|reset|view] ,view and confirmation of system messages", + ); + $cmds{notice} = \%hash; +} + +######################################## +sub +CommandNotice($$) +{ + my ($cl,$param) = @_; + my $modPath = (-d "updatefhem.dir" ? "updatefhem.dir":$attr{global}{modpath}); + my $modDir = "$modPath/FHEM"; + my $noticeDir = "$modDir/FhemUtils"; + my $name = "notice"; + my @commands = qw(confirm condition get list position reset view); + my $ret; + + # split arguments + my @args = split(/ +/,$param); + + $args[0] = "list" if(!defined($args[0])); + + if(!@args || $args[0] ~~ @commands) { + my $cmd = $args[0]; + + if($cmd eq "list") { + # view all a list of notes + my $type = "all"; + if(defined($args[1])) { + $type = $args[1]; + } + $ret = notice_List($noticeDir,$type); + + } elsif($cmd eq "view") { + # view a single note + return "notice view needs an argument" + if(!defined($args[1])); + + my $id = $args[1]; + my $notice_ref = {}; + $notice_ref = notice_Read($notice_ref,$noticeDir,$args[1]); + return "Nothing to view. Maybe wrong ID?" + if(!keys %$notice_ref); + + my $locale = "en"; + my $header = 1; + if(@args == 3) { + $locale = ($args[2] ~~ @locale) ? $args[2] : "en"; + $header = ($args[2] eq "noheader") ? 0 : 1; + } elsif(@args == 4) { + if($args[2] ~~ @locale) { + $locale = ($args[2] ~~ @locale) ? $args[2] : "en"; + $header = ($args[3] eq "noheader") ? 0 : 1; + } elsif($args[2] eq "noheader") { + $header = ($args[2] eq "noheader") ? 0 : 1; + $locale = ($args[3] ~~ @locale) ? $args[3] : "en"; + } + } + + if($header) { + $ret = sprintf("%-10s: %s\n","ID",$id); + $ret .= sprintf("%-10s: %s\n","From",$notice_ref->{$id}{from}) + if(exists $notice_ref->{$id}{from}); + $ret .= sprintf("%-10s: %s\n","Date",$notice_ref->{$id}{date}) + if(exists $notice_ref->{$id}{from}); + $ret .= sprintf("%-10s: %s\n","Expire",$notice_ref->{$id}{expire}) + if(exists $notice_ref->{$id}{expire}); + $ret .= sprintf("%-10s: %s\n","Title",$notice_ref->{$id}{locale}{$locale}{title}) + if(exists $notice_ref->{$id}{locale}{$locale}{title}); + $ret .= "### Start of Text\n"; + } + + foreach my $line (@{$notice_ref->{$id}{locale}{$locale}{text}}) { + $ret .= $line."\n"; + } + + $ret .= "### End of Text\n" if($header); + + } elsif($cmd eq "confirm") { + # confirm a note + return "notice view needs an argument" + if(!defined($args[1])); + + my $id = $args[1]; + my $notice_ref = {}; + $notice_ref = notice_Read($notice_ref,$noticeDir,$id); + return "Nothing to view. Maybe wrong ID?" + if(!keys %$notice_ref); + + if(!defined($notice_ref->{$id}{confirm}) || + (defined($notice_ref->{$id}{confirm}) && $notice_ref->{$id}{confirm} == 0) ) { + return "$id needs no confirmation."; + } else { + my $confirmation = 1; + if(@args > 2) { + shift @args; + shift @args; + $confirmation = "@args"; + } + $ret = notice_Confirmation($noticeDir,$id,$confirmation); + } + + } elsif($cmd eq "get") { + # get list of notes + my $type = (defined($args[1])) ? $args[1] : "all"; + my $value = (defined($args[2]) && $args[2] =~ /[0-8]/) ? $args[2] : 0; + return notice_Get($noticeDir,$type,$value); + + } elsif($cmd eq "position") { + # returns position of notice + return "notice position needs an argument" + if(!defined($args[1])); + + my $id = $args[1]; + my $notice_ref = {}; + $notice_ref = notice_Read($notice_ref,$noticeDir,$id); + return (defined($notice_ref->{$id}{position})) ? $notice_ref->{$id}{position} : undef; + } elsif($cmd eq "reset") { + # reset all confirmations + if(-e "$noticeDir/$confirmationFile") { + if(defined($args[1] && lc($args[1]) eq "yes")) { + my $cmdret = unlink "$noticeDir/$confirmationFile"; + if(!$cmdret) { + $ret = "an error occured while deleting file '$noticeDir/$confirmationFile': $!"; + } else { + $ret = "all confirmations deleted successfully."; + } + } else { + $ret = "This command delete all confirmations.\n"; + $ret .= "If you really want to do this, call 'notice reset yes'"; + return $ret; + } + } else { + $ret = "nothing to do. no confirmation exists."; + } + } elsif($cmd eq "condition") { + # supplies a value of an embedded test + return "condition view needs an argument" + if(!defined($args[1])); + + my $id = $args[1]; + my $notice_ref = {}; + $notice_ref = notice_Read($notice_ref,$noticeDir,$id); + return "Nothing to view. Maybe wrong ID?" + if(!keys %$notice_ref); + + my %conditions; + foreach my $key (sort %{$notice_ref->{$id}}) { + my $order; + if(lc($key) =~ /^key_/) { + (undef,$order) = split("_",$key); + if(defined($notice_ref->{$id}{"val_$order"})) { + $conditions{$notice_ref->{$id}{$key}}{value} = ($notice_ref->{$id}{"val_$order"}) ? + eval $notice_ref->{$id}{"val_$order"} : undef; + $conditions{$notice_ref->{$id}{$key}}{condition} = (defined($notice_ref->{$id}{"con_$order"})) ? + $notice_ref->{$id}{"con_$order"} : ""; + Log 5, "notice id:$id condition key:".$notice_ref->{$id}{$key} . " " . + "value:" .$conditions{$notice_ref->{$id}{$key}}{value} . " " . + "condition:".$notice_ref->{$id}{"val_$order"}; + } + } + } + + if(keys %conditions) { + foreach my $key (sort keys %conditions) { + Log 5, "notice id:$id condition key:$key value:$conditions{$key}{value} condition:$conditions{$key}{condition}"; + $ret .= "$key:$conditions{$key}{value}:$conditions{$key}{condition}"; + $ret .= "|"; + } + chop $ret; + return $ret; + } else { + return undef; + } + + } + + + } else { + return "Unknown argument $args[0]; choose one of " . join(" ", sort @commands); + } + + return $ret; +} + +######################################## +sub +notice_List($$) +{ + my ($noticeDir,$type) = @_; + $type = ($type eq "all") ? ".*" : $type; + my @dir; + my $ret; + + if(opendir(my $DH, "$noticeDir")) { + @dir = grep { /^$type-.*\d+$/ && -f "$noticeDir/$_" } readdir($DH); + closedir $DH; + + my $notice_ref = {}; + foreach my $file (@dir) { + $notice_ref = notice_Read($notice_ref,$noticeDir,$file); + } + + my @col1 = sort keys %{$notice_ref}; + my $col1 = (reverse sort { $a <=> $b } map { length($_) } @col1)[0]; + if(!keys %$notice_ref) { + $ret = "==> nothing found"; + } else { + + my @confirmationFile; + if(open(my $FH, "<$noticeDir/$confirmationFile")) { + Log 5, "notice read file: $noticeDir/$confirmationFile"; + while(my $line = <$FH>) { + chomp $line; + push(@confirmationFile,$line); + } + close $FH; + } + + foreach my $lang (sort @locale) { + $ret .= "==> Language: $lang\n"; + $ret .= sprintf(" %-*s %-10s %-10s %-10s %s\n",$col1,"ID","Published","Expired","Confirmed","Description"); + foreach my $notice (sort keys %{$notice_ref}) { + my ($dateTime,$oldConfirmation); + next if(!exists $notice_ref->{$notice}{locale}{$lang}); + foreach my $line (@confirmationFile) { + if($line =~ /^$notice\s*/) { + ($dateTime,$oldConfirmation) = $line =~ /^.*\s*(\d{4}-\d{2}-\d{2})\s\d{2}:\d{2}:\d{2}\s*(.*)$/; + $dateTime = substr($dateTime,8,2).".".substr($dateTime,5,2).".".substr($dateTime,0,4); + } + } + $ret .= sprintf(" %-*s %-10s %-10s %-10s %s\n", + $col1, + $notice, + (defined($notice_ref->{$notice}{publish}) && $notice_ref->{$notice}{publish} ne "0") ? + $notice_ref->{$notice}{publish} : "actually", + (defined($notice_ref->{$notice}{expire}) && $notice_ref->{$notice}{expire} ne "0") ? + $notice_ref->{$notice}{expire} : "never", + ($dateTime) ? $dateTime : + (defined($notice_ref->{$notice}{confirm}) && $notice_ref->{$notice}{confirm} ne "0") ? + "no" : "not needed", + $notice_ref->{$notice}{locale}{$lang}{title}); + } + $ret .= "\n"; + } + chomp $ret; + } + + } else { + $ret = "update could not open directory '$noticeDir': $!"; + Log 1, $ret; + } + + return $ret; +} + +######################################## +# value: 0 = all +# 1 = not confirmed +# 2 = not expired +# 3 = not confirmed, not expired +# 4 = published +# 5 = not confirmed, published +# 6 = not expired, published +# 7 = not confirmed, not expired, published +# 8 = confirmed +sub +notice_Get($$$) +{ + my ($noticeDir,$type,$value) = @_; + $value = ($value) ? $value : 0; + my @now = localtime(); + + my @dir; + + if(opendir(my $DH, "$noticeDir")) { + my $search = ($type eq "all") ? ".*" : $type; + @dir = grep { /^$search-.*\d+$/ && -f "$noticeDir/$_" } readdir($DH); + closedir $DH; + } else { + Log 1, "notice could not open directory '$noticeDir': $!"; + } + + my @confirmed; + if($value == 1 || $value == 3 || $value == 5 || $value == 7 || $value == 8) { + if(open(my $FH, "<$noticeDir/$confirmationFile")) { + Log 5, "notice read file: $noticeDir/$confirmationFile"; + while(my $line = <$FH>) { + my ($id,undef) = split(" ",$line); + if($type eq "all") { + push(@confirmed,$id); + } elsif($id =~ /^$type/) { + push(@confirmed,$id); + } + } + close $FH; + } + } + + if(@dir) { + my $notice_ref = {}; + foreach my $file (sort @dir) { + $notice_ref = notice_Read($notice_ref,$noticeDir,$file); + } + + if(!keys %$notice_ref) { + return undef; + } else { + + my $ret; + if($value == 0) { + # all + $ret = join(",",sort @dir); + } elsif($value == 1) { + # not confirmed + $ret = _notConfirmed($notice_ref,@confirmed); + Log 5, "notice notConfirmed:$ret"; + } elsif($value == 2) { + # not expired + $ret = _notExpired($notice_ref,@now); + Log 5, "notice notExpired:$ret"; + } elsif($value == 3) { + # not confirmed, not expired + my $notConfirmed = _notConfirmed($notice_ref,@confirmed); + my $notExpired = _notExpired($notice_ref,@now); + Log 5, "notice notConfirmed:$notConfirmed notExpired:$notExpired"; + my @merged; + foreach my $id (@dir) { + push (@merged, $id) if($notConfirmed =~ /$id/ && $notExpired =~ /$id/); + } + $ret = join(",",sort @merged); + } elsif($value == 4) { + # published + $ret = _published($notice_ref,@now); + Log 5, "notice published:$ret"; + } elsif($value == 5) { + # not confirmed, published + my $notConfirmed = _notConfirmed($notice_ref,@confirmed); + my $published = _published($notice_ref,@now); + Log 5, "notice notConfirmed:$notConfirmed published:$published"; + my @merged; + foreach my $id (sort @dir) { + push (@merged, $id) if($notConfirmed =~ /$id/ && $published =~ /$id/); + } + $ret = join(",",sort @merged); + } elsif($value == 6) { + # not expired, published + my $notExpired = _notExpired($notice_ref,@now); + my $published = _published($notice_ref,@now); + Log 5, "notice notExpired:$notExpired published:$published"; + my @merged; + foreach my $id (sort @dir) { + push (@merged, $id) if($notExpired =~ /$id/ && $published =~ /$id/); + } + $ret = join(",",sort @merged); + } elsif($value == 7) { + # not confirmed, not expired, published + my $notConfirmed = _notConfirmed($notice_ref,@confirmed); + my $notExpired = _notExpired($notice_ref,@now); + my $published = _published($notice_ref,@now); + Log 5, "notice notConfirmed:$notConfirmed notExpired:$notExpired published:$published"; + my @merged; + foreach my $id (sort @dir) { + push (@merged, $id) if($notConfirmed =~ /$id/ && $notExpired =~ /$id/ && $published =~ /$id/); + } + $ret = join(",",sort @merged); + } elsif($value == 8) { + # confirmed + $ret = join(",",sort @confirmed); + } + + return $ret; + + } + + } else { + return undef; + } + +} + +######################################## +sub +_notConfirmed($@) +{ + my ($notice_ref,@confirmed) = @_; + my @ret; + foreach my $id (sort keys %{$notice_ref}) { + push(@ret,$id) + if(defined($notice_ref->{$id}{confirm}) && + $notice_ref->{$id}{confirm} != 0 && !grep (m/^$id$/,@confirmed)); + } + return join(",",@ret); +} + +######################################## +sub +_notExpired($@) +{ + my ($notice_ref,@now) = @_; + my @ret; + foreach my $id (sort keys %{$notice_ref}) { + my ($d,$m,$y); + if(defined($notice_ref->{$id}{expire}) && $notice_ref->{$id}{expire} =~ /\d{2}.\d{2}.\d{4}/) { + $d = substr($notice_ref->{$id}{expire},0,2); + $m = substr($notice_ref->{$id}{expire},3,2)-1; + $y = substr($notice_ref->{$id}{expire},6,4)-1900; + } + push(@ret,$id) + if(!defined($notice_ref->{$id}{expire}) || + (defined($notice_ref->{$id}{expire}) && $notice_ref->{$id}{expire} !~ /\d{2}.\d{2}.\d{4}/) || + (defined($notice_ref->{$id}{expire}) && $notice_ref->{$id}{expire} =~ /\d{2}.\d{2}.\d{4}/ && + notice_epochDate($now[3],$now[4],$now[5]) <= notice_epochDate($d,$m,$y))); + } + return join(",",@ret); +} + +######################################## +sub +_published($@) +{ + my ($notice_ref,@now) = @_; + my @ret; + foreach my $id (sort keys %{$notice_ref}) { + my ($d,$m,$y); + if(defined($notice_ref->{$id}{publish}) && $notice_ref->{$id}{publish} =~ /\d{2}.\d{2}.\d{4}/) { + $d = substr($notice_ref->{$id}{publish},0,2); + $m = substr($notice_ref->{$id}{publish},3,2)-1; + $y = substr($notice_ref->{$id}{publish},6,4)-1900; + } + push(@ret,$id) + if(!defined($notice_ref->{$id}{publish}) || + (defined($notice_ref->{$id}{publish}) && $notice_ref->{$id}{publish} !~ /\d{2}.\d{2}.\d{4}/) || + (defined($notice_ref->{$id}{publish}) && $notice_ref->{$id}{publish} =~ /\d{2}.\d{2}.\d{4}/ && + notice_epochDate($now[3],$now[4],$now[5]) >= notice_epochDate($d,$m,$y))); + } + return join(",",@ret); +} + +######################################## +sub +notice_epochDate($$$) +{ + my ($day,$month,$year) = @_; + return timelocal("0","0","0",$day,$month,$year); +} + +######################################## +sub +notice_Confirmation($$$) +{ + my ($noticeDir,$id,$confirmation) = @_; + my @file; + my $confirmed = 0; + my $oldConfirmation; + my $dateTime; + my $now = TimeNow(); + my $ret; + + if(open(my $FH, "<$noticeDir/$confirmationFile")) { + Log 5, "notice read file: $noticeDir/$confirmationFile"; + while(my $line = <$FH>) { + chomp $line; + if($line =~ /^$id\s*/) { + ($dateTime,$oldConfirmation) = $line =~ /^.*\s*(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s*(.*)$/; + $confirmed = 1; + } + push(@file,$line); + } + close $FH; + } + + if($confirmed == 0) { + push(@file,"$id $now $confirmation\n"); + } + + if($oldConfirmation eq $confirmation) { + $ret = "$id already confirmed on $dateTime: $oldConfirmation"; + } else { + if(open(my $FH, ">$noticeDir/$confirmationFile")) { + Log 5, "notice write file: $noticeDir/$confirmationFile"; + foreach my $line (sort @file) { + if($line =~ /^$id\s*/) { + print $FH "$id $now $confirmation\n"; + if(!$oldConfirmation) { + $ret = "$id confirmed on $now: $confirmation"; + } else { + $ret = "$id changed on $now: $confirmation"; + } + Log 1, "notice $ret"; + } else { + print $FH "$line\n"; + } + } + } else { + $ret = "error while writing file: $noticeDir/$confirmationFile: $!"; + Log 1, "notice $ret"; + } + } + + return $ret; +} + +######################################## +sub +notice_Read($$$) +{ + my ($notice_ref,$noticeDir,$noticeFile) = @_; + my %notice = %$notice_ref if($notice_ref && ref($notice_ref) eq "HASH"); + + if(open(my $FH, "<$noticeDir/$noticeFile")) { + Log 5, "notice read file: $noticeDir/$noticeFile"; + my $key; + my $value; + my $locale; + while(my $line = <$FH>) { + chomp $line; + if(uc($line) =~ /^#\s.*:.*$/ && uc($line) !~ /^#\s*NOTICE_\S{2}$/ && uc($line) !~ /^#\s*TITLE_\S{2}\s*:.*$/) { + ($key,$value) = $line =~ /^#\s*(.*)\s*:\s*(.*)$/; + $notice{$noticeFile}{lc($key)} = $value; + } elsif (uc($line) =~ /^#\s*TITLE_\S{2}\s*:.*$/) { + ($locale,$value) = $line =~ /^#\s*TITLE_(\S{2})\s*:\s*(.*)$/; + $notice{$noticeFile}{locale}{lc($locale)}{title} = $value; + } elsif (uc($line) =~ /^#\s*NOTICE_\S{2}$/) { + ($locale) = $line =~ /^#\s*NOTICE_(\S{2})$/; + } else { + $locale = "EN" if(!$locale); + push @{ $notice{$noticeFile}{locale}{lc($locale)}{text} }, $line; + } + } + close $FH; + } else { + Log 1, "update could not open notice '$noticeDir/$noticeFile': $!"; + return undef; + } + return \%notice; +} + +=pod +=begin html + + +

notice

+
    + notice [confirm [value]|list [<keyword>]|reset [yes]|view <id> [noheader|[de|en]]]
    +
    + View and confirmation of system messages. +
    +
    + During an update or a system start from FHEM sometimes it is necessary to + inform the user about important changes or additions. It may be necessary + to confirm a system message by the user. +
    +
    + By entering the command 'notice' a list of all messages is displayed. + Are messages available in different languages, they are ordered by language. +
    + Example: +
    +    fhem> notice
    +    ==> Language: de
    +      ID                  Published  Expired    Confirmed  Description
    +      advice-20130128-002 actually   never      not needed kurze beschreibung
    +      update-20130128-002 31.01.2013 01.02.2013 no         kurze beschreibung
    +
    +    ==> Language: en
    +      ID                  Published  Expired    Confirmed  Description
    +      advice-20130128-001 actually   never      no         short description
    +      advice-20130128-002 actually   never      not needed short description
    +      update-20130128-001 actually   never      no         short description
    +      update-20130128-002 31.01.2013 01.02.2013 no         short description
    +    
    + By entering 'notice list <keyword>' the output of the list contains only + available messages that starts with '<keyword>'. +
    + Example: +
    +    fhem> notice list update
    +    ==> Language: de
    +      ID                  Published  Expired    Confirmed  Description
    +      update-20130128-002 31.01.2013 01.02.2013 no         kurze beschreibung
    +
    +    ==> Language: en
    +      ID                  Published  Expired    Confirmed  Description
    +      update-20130128-001 actually   never      no         short description
    +      update-20130128-002 31.01.2013 01.02.2013 no         short description
    +    
    + To display a single message, enter the command 'notice view <id>' where id + is the Identifier of the message. You can use the optional parameter noheader + or the language codes de or en to display the message + without the header informations or in your prefered language if available. +
    + Example: +
    +    fhem> notice view advice-20130128-002 de
    +    ID        : advice-20130128-002
    +    From      : M. Fischer
    +    Date      : 28.01.2013
    +    Expire    : 0
    +    Title     : kurze beschreibung
    +    ### Start of Text
    +    test-advice
    +
    +    dies ist ein test
    +
    +    001
    +    ### End of Text
    +    
    + If it is necessary to confirm a message, this is be done by entering 'notice confirm <id> [value]'. + The optional argument value will also be stored with the confirmation. +
    + Example: +
    +    fhem> notice confirm update-20130128-001 foo:bar
    +    update-20130128-001 confirmed on 2013-01-29 20:58:57: foo:bar
    +    
    + Sometimes it is necessary to reset all confirmations. This is be done by entering + 'notice reset'. +
    + Example: +
    +    fhem> notice reset
    +    This command delete all confirmations.
    +    If you really want to do this, call 'notice reset yes'
    +    
    +
    + For developers only: +
    +
    + notice [condition <id>|get <keyword> <value>|position <id>]
    +
    +
    + These arguments are normally not needed by any user. +
    +
    + A message may optionally contains one or more code snippets. The argument condition supplies the determined + value(s) of the embedded test(s) as a key:value pair. If more than one pair returned, they they are seperated by |. + It is possible to define your own rules for a condition, like !empty or >>5 and so on. An example + of a condition is shown in the below example message file. + Example: +
    +    fhem> notice condition update-20130127-001
    +    configfile:./fhem.cfg|sendStatistics:never:!empty
    +    
    + The argument get, followed by a keyword and a number from 0 to 8, returns a + comma seperated list of message ids. + The possible outputs are: +
      +
    • 0 returns a list of all messages.
    • +
    • 1 returns a list of unconfirmed messages.
    • +
    • 2 returns a list of messages that are not expired.
    • +
    • 3 returns a list of messages that are not expired and unconfirmed.
    • +
    • 4 returns a list of published messages.
    • +
    • 5 returns a list of unconfirmed and published messages.
    • +
    • 6 returns a list of published messages that are not expired.
    • +
    • 7 returns a list of published, unconfirmed and not expired messages.
    • +
    • 8 returns a list of confirmed messages.
    • +
    + Example: +
    +    fhem> notice get all 2
    +    advice-20130128-001,advice-20130128-002,update-20130128-001,update-20130128-002
    +    
    + The argument position followed by an <id> returns the view position of a message if defined. +
    + Example: +
    +    fhem> notice position update-20130128-001
    +    before
    +    
    + Example of a message file: +
    +    # FROM: M. Fischer
    +    # DATE: 28.01.2013
    +    # CONFIRM: 1
    +    # PUBLISH: 31.01.2013
    +    # EXPIRE: 01.02.2013
    +    # KEY_1: sendStatistics
    +    # VAL_1: AttrVal("global","sendStatistics",undef);
    +    # CON_1: !empty
    +    # KEY_2: configfile
    +    # VAL_2: AttrVal("global","configfile",undef);
    +    # POSITION: top
    +    # TITLE_DE: kurze beschreibung
    +    # NOTICE_DE
    +    Hinweis:
    +
    +    dies ist ein test
    +    # TITLE_EN: short description
    +    # NOTICE_EN
    +    Advice:
    +
    +    this is a test
    +    
    + The keywords 'FROM, DATE, CONFIRM, PUBLISH, EXPIRE, TITLE_DE, TITLE_EN, NOTICE_DE, NOTICE_EN' are fixed. + It is possible to add any key:value string to these files. Also it is possible to set only one or both keywords of + 'TITLE_DE, TITLE_EN' and 'NOTICE_DE, NOTICE_EN'. +
+ +=end html +1; diff --git a/fhem/FHEM/FhemUtils/update-20130127-001 b/fhem/FHEM/FhemUtils/update-20130127-001 new file mode 100644 index 000000000..4cc8a3175 --- /dev/null +++ b/fhem/FHEM/FhemUtils/update-20130127-001 @@ -0,0 +1,138 @@ +# FROM: M. Fischer +# DATE: 27.01.2013 +# CONFIRM: 1 +# PUBLISH: 0 +# EXPIRE: 0 +# POSITION: before +# KEY_1: sendStatistics +# VAL_1: AttrVal("global","sendStatistics",undef); +# CON_1: !empty +# TITLE_DE: Das FHEM-Projekt moechte Dich um Deine Unterstuetzung bitten! +# NOTICE_DE + HINWEIS: + + Das FHEM-Projekt moechte Dich um Deine Unterstuetzung bitten! + + Im Rahmen der Aktualisierung kann FHEM Informationen ueber diese Installation + an einen zentralen Server uebertragen. Diese Daten beinhalten Angaben ueber + die installierte FHEM-Version, das Betriebssystem und Rechner-Architektur, + die aktuelle Perl-Version, sowie eine Liste der zur Laufzeit definierten + Module (inkl. der Anzahl der Definitionen je Modultyp). Weiterhin werden die + definierten Modelltypen ermittelt. + + Die am FHEM-Projekt beteiligten Entwickler erhalten wertvolle Informationen zu + der Umgebung, in der FHEM installiert ist, und eine Einschaetzung, wie haeufig + die jeweiligen Module eingesetzt werden. Dies kann Auswirkungen auf die + Weiterentwicklung aber auch auf die zeitnahe Bereitstellung von Erweiterungen + und Korrekturen haben. + + Es werden keine personenbezogenen Daten uebertragen und / oder gespeichert. + Die Daten werden nicht an Dritte weitergegeben und nicht fuer kommerzielle + Zwecke verwendet. Sie dienen einzig als Hilfestellung zur Entwicklung und + zur Einschaetzung der Verbreitung von FHEM. + + Eine weiterfuehrende Beschreibung ist der Dokumentation zu dem FHEM-Befehl + 'fheminfo' sowie dem globalen Paramater 'sendStatsistics' zu entnehmen. Eine + Uebersicht der erhobenen Informationen kann jederzeit ueber den Aufruf von + 'fheminfo' abgerufen werden. + + Wenn Du das FHEM-Projekt unterstuetzen moechtest, solltest Du jetzt ueber das + globale Attribut 'sendStatsistics' die automatische Uebermittlung aktivieren: + + attr global sendStatistics onUpdate + + Im Anschluss solltest Du die aktuelle Konfiguration speichern, um diesen + Hinweis nicht erneut angezeigt zu bekommen. Der Updatevorgang kann dann wie + gewohnt fortgesetzt werden. + + Moechtest Du keine automatische Uebermittlung der Daten waehrend der + Aktualisierung, solltest Du nun das globale Attribut 'sendStatistics' auf + 'manually' setzen: + + attr global sendStatistics manually + + Die Uebermittlung der Daten muss manuell ueber den Befehl 'fheminfo send' + erfolgen. + + Moechtest Du niemals Daten ueber die vorhandene FHEM-Installation uebermitteln, + so muss das globale Attribut auf 'never' gesetzt werden: + + attr global sendStatistics never + + Ein Aufruf von 'fheminfo send' ist damit wirkungslos. + + Die obigen Einstellungen koennen jederzeit geaendert werden. Eine Uebersicht + der bereits von anderen Installationen uebermittelten Informationen kann ueber + + http://fhem.de/stats/statistics.cgi + + eingesehen werden. + + Das FHEM-Team freut sich, wenn auch Du durch die automatische Uebermittlung + Deiner technischen Daten zum FHEM-Projekt beitraegst. + + Dieser Hinweistext kann erneut durch den Aufruf von 'update viewAdvice' + angezeigt werden. + + Vielen Dank fuer Deine Unterstuetzung! +# TITLE_EN: The FHEM Project asks for your support! +# NOTICE_EN + The FHEM Project asks for your support! + + During the update process FHEM is able to send statistical information + regarding your installation to a central server. This may include data like + your installed FHEM version, the operating system, Perl version, computer + achitecture and the list of modules used during the update. Also the list of + model types and number of definitions for each module may be collected. + + The developers behind the FHEM project receive valuable information about the + environment in which FHEM is installed and get an overview how often those + modules are used. This may affect the further development of FHEM as well as + the timely provision of extensions and corrections. + + No personal information will be transferred or stored during this process. The + data collected will neither be made available to a third party nor used for + commercial purposes. The only purpose is to support further development of + FHEM and to asses its distribution. + + A more detailed explanation can be found in the documentation related to the + command 'fheminfo' and the global parameter 'sendStatistics'. An overview + about all information collected can be displayed at any time by using the + command 'fheminfo'. + + If you would like to support the FHEM project, you may set the global attribut + 'sendStatistics' to enable the automatic info transfer process. + + attr global sendStatistics onUpdate + + Thereafter you should save the current configuration to avoid this note beeing + displayed again. The update process can be continued like before. + + In case you do not whish an automatic transmission of the data collected + during update, you should set the global attribute 'sendStatistics' to + 'manually': + + attr global sendStatistics manually + + Manual transfer of the data can then be performed by using the command + 'fheminfo send'. + + If you never want to send information about your FHEM installation by all + means, you need to set the global attribut 'sendStatistics' to 'never': + + attr global sendStatistics never + + Even the use of 'fheminfo send' will then not transfer any data. + + All the settings mentioned above can be amended at any time. An overview of + data sent from other installations can be obtained at + + http://fhem.de/stats/statistics.cgi + + The FHEM Project Team would be happy if you considered supporting the + development of FHEM by transferring your technical data to the project. + + This info text can be displayed again by using the command + 'update viewAdvice'. + + Thanks a lot for your support!