| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771 |
- ##############################################
- # $Id: 98_Sprinkle.pm 6159 2014-06-24 17:43:33Z tobiasfaust $
- #
- # 98_Sprinkle.pm
- #
- # written by Tobias Faust 2013-10-23
- # e-mail: tobias dot faust at online dot de
- #
- ##############################################
- package main;
- use strict;
- use warnings;
- use Data::Dumper;
- use vars qw(%gets %sets %defs %attr);
- # SetParamName -> Anzahl Paramter
- my %sets = (
- "Auto" => "0",
- "An" => "0",
- "Aus" => "0",
- "Toggle" => "0",
- "Disable" => "0"
- );
- # These we may get on request
- #my %gets = (
- # "alarms" => "0"
- #);
- ##########################
- sub Sprinkle_Initialize($)
- {
- my ($hash) = @_;
- require "$main::attr{global}{modpath}/FHEM/97_SprinkleControl.pm";
- $hash->{DefFn} = "Sprinkle_Define";
- $hash->{NotifyFn} = "Sprinkle_Notify";
- $hash->{SetFn} = "Sprinkle_Set";
- $hash->{UndefFn} = "Sprinkle_Undefine";
- $hash->{AttrFn} = "Sprinkle_Attr";
- $hash->{AttrList} = "disable:0,1".
- " Sprinkle_SensorThreshold". # in 0% - 100%
- " Sprinkle_OnTimeSec". # =0: On; >0: on-for-timer x
- " Sprinkle_DefaultCmd:Auto,An".
- " ".$readingFnAttributes;
- }
- ##########################
- # Define <sprinkle> Sprinkle <actor> [<sensor>] [<timespec>]
- ##########################
- sub Sprinkle_Define($$)
- {
- my ($hash, $def) = @_;
- my $me = $hash->{NAME};
- my @a = split("[ \t]+", $def);
-
- #$a[0]: Name
- #$a[1]: Type/Alias -> Sprinkle
- my $device = $a[2];
-
- my $deviceport;
- my $sensor;
- my $sensorport;
- my $timespec;
-
- $sensor = $a[3] if($a[3] && length($a[3])>0);
- $timespec = $a[4] if($a[4] && length($a[4])>0);
-
- if(int(@a) < 3) {
- my $msg = "wrong syntax: define <name> Sprinkle <actor> [<sensor>] [<timespec>]";
- Log3 $hash, 2, $msg;
- return $msg;
- }
-
- my @t;
- # Check definition of device
- if($device =~ m/:/) {
- @t = split(":", $device);
- $device = $t[0];
- $deviceport = $t[1] if($t[1]);
- }
- # check definition of sensor
- if($sensor && $sensor =~ m/:/) {
- @t = split(":", $sensor);
- $sensor = $t[0];
- $sensorport = $t[1] if($t[1]);
- }
- return "Given device not exists: $device" if(!$defs{$device});
- return "Given Sensordevice not exists: $sensor" if(defined($sensor) && !$defs{$sensor});
- #return "The specified reading of device not exists: $deviceport" if (defined($deviceport) && !defined(ReadingsVal($device, $deviceport, undef)));
- #return "The specified reading of sensor not exists: $sensorport" if (defined($sensorport) && !defined(ReadingsVal($sensor, $sensorport, undef)));
-
- return "Wrong timespec, use \"[+]<hour>:<minute>:<second>\"" if(defined($timespec) && $timespec !~ m/^([\+]?)([\d]{2}):([\d]{2}):([\d]{2})$/);
- #ininitial delete
- delete $hash->{Device};
- delete $hash->{DevicePort};
- delete $hash->{Sensor};
- delete $hash->{SensorPort};
- delete $hash->{TimeSpec};
- delete $hash->{NOTIFYDEV};
- $hash->{Device} = $device;
- $hash->{DevicePort} = $deviceport if($deviceport);
- $hash->{Sensor} = $sensor if($sensor);
- $hash->{SensorPort} = $sensorport if($sensorport);
- $hash->{TimeSpec} = $timespec if($timespec);
- $hash->{NOTIFYDEV} = $device;
- if(!$attr{$me}) {
- #Attribute vorbelegen! Nur beim Define, kein Modify
- $attr{$me}{webCmd} = "Auto:An:Aus:Toggle:Disable";
- $attr{$me}{devStateIcon} = "An:general_an Aus:general_aus Auto:time_automatic disabled:remotecontrol/black_btn_POWEROFF2";
- $attr{$me}{Sprinkle_OnTimeSec} = 640;
- $attr{$me}{Sprinkle_SensorThreshold} = 50;
- $attr{$me}{Sprinkle_DefaultCmd} = "Auto";
- }
- UpdateSprinkleControlList(undef, undef);
- if(defined($timespec) && $sensor && $attr{$me}{Sprinkle_OnTimeSec} && $attr{$me}{Sprinkle_SensorThreshold}) {
- readingsSingleUpdate($hash, "state", "Auto", 1);
- Sprinkle_InternalTimerDoIt($hash);
- } else {
- readingsSingleUpdate($hash, "state", "Initialized", 1);
- }
- return undef;
- }
- #####################################
- sub Sprinkle_Undefine($$)
- {
- my ($hash, $arg) = @_;
- my $me = $hash->{NAME};
- Log3 $hash, 4, "$me: Lösche alle internen Timer";
- RemoveInternalTimer($hash);
- return undef;
- }
- ###################################
- #
- ###################################
- sub Sprinkle_Attr(@) {
- my @a = @_;
- my $do = 0;
- my $hash = $defs{$a[1]};
- my $command = $a[0];
- my $setter = $a[2];
- my $value = $a[3];
- if($setter eq "Sprinkle_SensorThreshold" && $command ne "del") {
- return "SensorTreshold isn´t numeric or not in range [0..100]" if ($value !~ m/^(\d+)$/ || $value < 0 || $value > 100);
-
- } elsif($setter eq "Sprinkle_OnTimeSec" && $command ne "del") {
- return "OnTimeSec isn´t numeric or not greater than zero" if ($value !~ m/^(\d+)$/ || $value < 0);
-
- } elsif($setter eq "disable"){
- # 1=disable; 2=enable
- if($command eq "set") {
- $do = (!defined($value) || $value) ? 1 : 2;
- }
- $do = 2 if($command eq "del");
- readingsSingleUpdate($hash, "state", ($do == 1 ? "disabled" : "Initialized"), 1);
- }
- return undef;
- }
- ################################################
- #
- #
- ###############################################
- sub Sprinkle_Set($@)
- {
- my ($hash, @a) = @_;
- my $me = $hash->{NAME};
- return "no set argument specified" if(int(@a) < 2);
- my $cmd = shift(@a); # Dummy
- $cmd = shift(@a); # DevName
- if(!defined($sets{$cmd})) {
- my $r = "Unknown argument $cmd, choose one of ".join(" ",sort keys %sets);
- return $r;
- }
- # Abbruch falls Disabled
- #return undef if(IsDisabled($hash->{NAME}));
- #if($cmd ne "tts") {
- # return "$cmd needs $sets{$cmd} parameter(s)" if(@a-$sets{$cmd} != 0);
- #}
- Log3 $hash, 4, "$me: Lösche alle internen Timer";
- RemoveInternalTimer($hash);
- if($cmd eq "Disable" && !IsDisabled($me)) {
- $attr{$me}{disable}=1;
- readingsSingleUpdate($hash, "state", "disabled", 1); # Deaktivieren
- return undef;
- } elsif($cmd eq "Disable" && IsDisabled($me)) {
- $attr{$me}{disable}=0;
- readingsSingleUpdate($hash, "state", "Aus", 1); # wieder aktivieren, Startzustand: Aus
- return undef;
- } elsif (IsDisabled($me)) { # mache nix da disabled
- return undef;
- } elsif($cmd eq "Toggle") {
- my $aktstate = lc(OldValue($me));
- if($aktstate =~ m/^aus/) {
- $cmd = "An";
- } else {
- $cmd = "Aus";
- }
- } elsif($cmd eq "Auto") {
- return "automode not possible because no sensor defined" if(!defined($hash->{Sensor}));
- return "automode not possible because no sensor threshold (Sprinkle_SensorThreshold) defined or value is 0" if(AttrVal($me, "Sprinkle_SensorThreshold", 0) == 0);
- return "automode not possible because no time definition (Sprinkle_OnTimeSec) defined or value is 0" if(AttrVal($me, "Sprinkle_OnTimeSec", 0) == 0);
- if(OldValue($me) !~ m/Auto/) {
- readingsSingleUpdate($hash, "state", "Auto", 1); # AutoMode aktivieren, Startzustand: Aus
- Sprinkle_InternalTimerDoIt($hash, 0);
- return undef;
- }
- }
- Log3 $hash, 4, "$me: Rufe Funktion DoIt mit Command: $cmd auf";
- Sprinkle_DoIt($hash, $cmd);
-
- return undef;
- }
- ################################################
- #
- #
- ###############################################
- sub Sprinkle_Notify($$) {
- # Log is my entry, Dev is the entry of the changed device
- my ($hash, $dev) = @_;
- my $me = $hash->{NAME};
- my $devname = $dev->{NAME};
- Log3 $hash, 4, "$me: NotifyFn: Statusänderung des überwachten Aktors '$devname' von '".OldValue($devname)."' nach '".Value($devname)."' festgestellt";
-
- return undef if(IsDisabled($me));
- return undef if($hash->{Device} ne $dev->{NAME});
- return undef if(OldValue($devname) eq Value($devname));
- Log3 $hash, 4, "$me: NotifyFn: überwachter Aktor $devname, Statuswechsel von '".OldValue($devname)."' nach '".Value($devname)."'";
- my $SprinkleControl = AttrVal($me, "SprinkleControl", undef);
-
- my $newState;
- $newState = "An" if(lc(ReadingsVal($devname, "state", "")) =~ m/(an|on)/);
- $newState = "Aus" if(lc(ReadingsVal($devname, "state", "")) =~ m/(aus|off)/);
- if($newState eq "An") {
- Log3 $hash, 4, "$me: NotifyFn: Allokiere einen neuen Thread im SprinkleControl: $SprinkleControl" if($SprinkleControl);
- SprinkleControl_AllocateNewThread($SprinkleControl, $me, "An") if($SprinkleControl);
- } elsif($newState eq "Aus") {
- Log3 $hash, 4, "$me: NotifyFn: Gebe einen Thread frei im SprinkleControl: $SprinkleControl" if($SprinkleControl);
- SprinkleControl_DeallocateThread($SprinkleControl, $me) if($SprinkleControl);
- }
- if(lc(ReadingsVal($me, "state", "")) =~ m/auto/) {
- $newState = "Auto(An)" if ($newState eq "An");
- $newState = "Auto" if ($newState eq "Aus");
- }
- Log3 $hash, 4, "$me: NotifyFn: Setze neuen Status auf: $newState" if($newState);
- readingsSingleUpdate($hash, "state", $newState, 1) if($newState);
- return undef;
- }
- ################################################
- # Setzt den Internen Timer und startet die
- # Hauptprozedur.
- #
- # param1: $hash
- # param2: DoIt = 1 -> Starte InternalTimer und DoIt
- # DoIt = 2 -> Starte nur InternalTimer
- ###############################################
- sub Sprinkle_InternalTimerDoIt(@) {
- my ($hash, $DoIt) = @_;
- my $me = $hash->{NAME};
-
- $DoIt = 1 if(!defined($DoIt));
- if(defined($hash->{TimeSpec}) && $hash->{TimeSpec} =~ m/^([\+]?)([\d]{2}):([\d]{2}):([\d]{2})$/) {
- my ($rel, $hr, $min, $sec) = ($1, $2, $3, $4);
- my @lt = localtime(time);
- my $nt = time;
- if($rel ne "+") {
- $nt -= (($lt[2]*3600)+($lt[1]*60)+$lt[0]); # Midnight for absolute time
- $nt += 86400 if((($lt[2]*3600)+($lt[1]*60)+$lt[0]) >= (($hr*3600)+($min*60)+$sec)); # tomorrow is next time
- }
- $nt += (($hr*3600)+($min*60)+$sec); # Plus relative time
- @lt = localtime($nt);
- my $ntm = sprintf("%02d.%02d.%04d %02d:%02d:%02d", $lt[3], ($lt[4]+1), ($lt[5]+1900), $lt[2], $lt[1], $lt[0]);
- $hash->{TriggerTime_FMT} = $ntm;
- $hash->{TriggerTime} = $nt;
- my $DefaultCmd = AttrVal($me, "Sprinkle_DefaultCmd", "Auto");
-
- Log3 $hash, 4, "$me: InternalTimerDoIt: Lösche alle internen Timer";
- RemoveInternalTimer($hash);
- Sprinkle_DoIt($hash, $DefaultCmd) if($DoIt == 1);
- Log3 $hash, 4, "$me: InternalTimerDoIt: Setze InternalTimer auf: $ntm";
- InternalTimer($nt, "Sprinkle_InternalTimerDoIt", $hash, 0);
- } else {
- delete $hash->{TriggerTime_FMT};
- delete $hash->{TriggerTime};
- }
- }
- ##############################################
- # HauptProzedur zur Bewässerungssteuerung
- #
- # param1: $hash
- # param2: Command, zb: An, Auto, Aus...
- ##############################################
- sub Sprinkle_DoIt($$) {
- my ($hash, $cmd) = @_;
- my $me = $hash->{NAME};
- Log3 $hash, 4, "$me: DoIt: Mache etwas, Command: $cmd";
- return undef if(IsDisabled($me));
- return undef if((lc(ReadingsVal($me, "state", undef)) =~ m/an/) &&
- (lc($cmd) !~ m/aus/)) ; # Aufruf durch InternalTimer und manuell wurde bereits angeschaltet oder Wartestellung
- my $SensorTreshold = AttrVal($me, "Sprinkle_SensorThreshold", undef);
- my $OnTimeSec = AttrVal($me, "Sprinkle_OnTimeSec", undef);
-
- my $device = $hash->{Device};
- my $deviceport = $hash->{DevicePort} if(defined($hash->{DevicePort}));
- my $sensor = $hash->{Sensor} if(defined($hash->{Sensor}));
- my $sensorport = $hash->{SensorPort} if(defined($hash->{SensorPort}));
- my $oldState;
- my $sensorvalue;
- # aktuellen Status des Device abfragen
- if(defined($deviceport)) {
- $oldState = lc(ReadingsVal($device, $deviceport,undef));
- } else {
- $oldState = lc(ReadingsVal($device, "state", undef));
- }
- Log3 $hash, 4, "$me: DoIt: ermittelter Status des Aktors: $oldState";
- return "actual state of given device not accessable, please check definition of $me" if(!$oldState);
- # Status des Sensors abfragen
- if (defined($sensor) && defined($sensorport)) {
- $sensorvalue = ReadingsVal($sensor, $sensorport, undef);
- }
- if(defined($sensor) && !defined($sensorport)) {
- $sensorvalue = ReadingsVal($sensor, "status", undef);
- $sensorvalue = ReadingsVal($sensor, "state", undef) if (!defined($sensorvalue));
-
- #Bodenfeuchte ist kein Messwert sondern nur ein on/off Reading
- $sensorvalue = 0 if(lc($sensorvalue) =~ m/^(on)/);
- $sensorvalue = 999 if(lc($sensorvalue) =~ m/^(off)/);
- }
- Log3 $hash, 4, "$me: DoIt: ermittelter Wert des Sensors: $sensorvalue";
-
- return "AutoMode not accessable. Please check your Sprinkle attributes and value of Sensor"
- if(lc($cmd) eq "auto" && (!defined($OnTimeSec) || $OnTimeSec <= 0 || !defined($sensorvalue) || !defined($SensorTreshold)));
-
- my $newState;
- my $OnCmd;
- my $OnCmdAdd = "";
- my $doit = 0; # 0 => mache nichts; 1 => mache; 2 => warte auf Freigabe SprinkleControl
- if(defined($OnTimeSec) && $OnTimeSec > 0 ) {
- $OnCmd = "on-for-timer ".$OnTimeSec;
- } else {
- $OnCmd = "on";
- }
- my $SprinkleControl = AttrVal($me, "SprinkleControl", undef);
- if(defined($deviceport)) {
- $OnCmdAdd = "output ".$deviceport; #zb OWSwitch, ev. unterscheiden nach OWSWITCH und OWDEVICE
- }
- if(lc($cmd) eq "an") {
- $newState = $cmd;
- if($oldState ne $newState && (($SprinkleControl && SprinkleControl_AllocateNewThread($SprinkleControl, $me, $cmd)) || !$SprinkleControl)) {
- Log3 $hash, 4, "$me: DoIt: Schalte Aktor $device auf $OnCmd";
- fhem "set $device $OnCmdAdd $OnCmd";
- $doit = 1;
- } elsif($oldState ne $newState) {
- Log3 $hash, 4, "$me: Setze Status auf: wait";
- $newState = "Wait";
- $doit = 2;
- }
-
- } elsif(lc($cmd) eq "aus") {
- $newState = $cmd;
- if($oldState ne $newState && (($SprinkleControl && SprinkleControl_DeallocateThread($SprinkleControl, $me)) || !$SprinkleControl)) {
- Log3 $hash, 4, "$me: DoIt: Schalte Aktor $device aus";
- fhem "set $device off";
- $doit = 1;
- }
-
- } elsif(lc($cmd) eq "auto") {
- if($SensorTreshold >= $sensorvalue) {
- Log3 $hash, 4, "$me: DoIt: Im Automodus wurde Schwellwert unterschritten erkannt. Soll: $SensorTreshold , Ist: $sensorvalue";
- $newState = "Auto(An)";
- if($oldState ne "on" && (($SprinkleControl && SprinkleControl_AllocateNewThread($SprinkleControl, $me, $cmd)) || !$SprinkleControl)) {
- Log3 $hash, 4, "$me: DoIt: Schalte im AutoModus Device $device auf $OnCmd";
- fhem "set $device $OnCmdAdd $OnCmd";
- $doit = 1;
- } elsif($oldState ne $newState) {
- Log3 $hash, 4, "$me: DoIt: Setze im Automodus auf: wait";
- $newState = "Wait";
- $doit = 2;
- }
- } else {
- Log3 $hash, 4, "$me: DoIt: Im Automodus wurde Schwellwert noch nicht erreicht. Soll: $SensorTreshold , Ist: $sensorvalue";
- $newState = "Auto";
- if($oldState ne "off" && (($SprinkleControl && SprinkleControl_DeallocateThread($SprinkleControl, $me)) || !$SprinkleControl)) {
- Log3 $hash, 4, "$me: DoIt: Schalte im Automodus Device $device aus";
- fhem "set $device off";
- $doit = 1;
- }
- }
- }
- readingsSingleUpdate($hash, "state", $newState, 1) if($doit >= 1);
- Log3 $hash, 4, "$me: DoIt: Setze neuen Status auf: $newState" if($doit >= 1);
- return $newState;
- }
- 1;
- =pod
- =begin html
- <a name="Sprinkle"></a>
- <h3>Sprinkle</h3>
- <ul>
- <br>
- <a name="Sprinkledefine"></a>
- <b>Define</b>
- <ul>
- <b>Local : </b><code>define <name> Sprinkle <alsadevice></code><br>
- <b>Remote: </b><code>define <name> Sprinkle <host>[:<portnr>][:SSL] [portpassword]</code>
- <p>
- This module converts any text into speech with serveral possible providers. The Device can be defined as locally
- or remote device.
- </p>
-
- <li>
- <b>Local Device</b><br>
- <ul>
- The output will be send to any connected audiodevice. For example external speakers connected per jack
- or with bluetooth speakers - connected per bluetooth dongle. Its important to install mplayer.<br>
- <code>apt-get install mplayer</code><br>
- The given alsadevice has to be configured in <code>/etc/asound.conf</code>
- <p>
- <b>Special AlsaDevice: </b><i>none</i><br>
- The internal mplayer command will be without any audio directive if the given alsadevice is <i>none</i>.
- In this case mplayer is using the standard audiodevice.
- </p>
- <p>
- <b>Example:</b><br>
- <code>define MyTTS Sprinkle hw=0.0</code><br>
- <code>define MyTTS Sprinkle none</code>
- </p>
- </ul>
- </li>
- <li>
- <b>Remote Device</b><br>
- <ul>
- This module can configured as remote-device for client-server Environments. The Client has to be configured
- as local device.<br>
- Notice: the Name of the locally instance has to be the same!
- <ul>
- <li>Host: setting up IP-adress</li>
- <li>PortNr: setting up TelnetPort of FHEM; default: 7072</li>
- <li>SSL: setting up if connect over SSL; default: no SSL</li>
- <li>PortPassword: setting up the configured target telnet passwort</li>
- </ul>
- <p>
- <b>Example:</b><br>
- <code>define MyTTS Sprinkle 192.168.178.10:7072 fhempasswd</code>
- <code>define MyTTS Sprinkle 192.168.178.10</code>
- </p>
- </ul>
- </li>
- </ul>
- </ul>
- <a name="Sprinkleset"></a>
- <b>Set</b>
- <ul>
- <li><b>tts</b>:<br>
- Giving a text to translate into audio.
- </li>
- <li><b>volume</b>:<br>
- Setting up the volume audio response.<br>
- Notice: Only available in locally instances!
- </li>
- </ul><br>
- <a name="Sprinkleget"></a>
- <b>Get</b>
- <ul>N/A</ul><br>
- <a name="Sprinkleattr"></a>
- <b>Attributes</b>
- <ul>
- <li>TTS_Delemiter<br>
- optional: By using the google engine, its not possible to convert more than 100 characters in a single audio brick.
- With a delemiter the audio brick will be split at this character. A delemiter must be a single character.!<br>
- By default, ech audio brick will be split at sentence end. Is a single sentence longer than 100 characters,
- the sentence will be split additionally at comma, semicolon and the word <i>and</i>.<br>
- Notice: Only available in locally instances with Google engine!
- </li>
- <li>TTS_Ressource<br>
- optional: Selection of the Translator Engine<br>
- Notice: Only available in locally instances!
- <ul>
- <li>Google<br>
- Using the Google Engine. It´s nessessary to have internet access. This engine is the recommend engine
- because the quality is fantastic. This engine is using by default.
- </li>
- <li>ESpeak<br>
- Using the ESpeak Engine. Installation of the espeak sourcen is required.<br>
- <code>apt-get install espeak</code>
- </li>
- </ul>
- </li>
- <li>TTS_CacheFileDir<br>
- optional: The downloaded Goole audio bricks are saved in this folder for reusing.
- No automatically implemented deleting are available.<br>
- Default: <i>cache/</i><br>
- Notice: Only available in locally instances!
- </li>
- <li>TTS_UseMP3Wrap<br>
- optional: To become a liquid audio response its recommend to use the tool mp3wrap.
- Each downloaded audio bricks are concatinated to a single audio file to play with mplayer.<br>
- Installtion of the mp3wrap source is required.<br>
- <code>apt-get install mp3wrap</code><br>
- Notice: Only available in locally instances!
- </li>
- <li>TTS_MplayerCall<br>
- optional: Setting up the Mplayer system call. The following example is default.<br>
- Example: <code>sudo /usr/bin/mplayer</code>
- </li>
- <li>TTS_SentenceAppendix<br>
- Optional: Definition of one mp3-file to append each time of audio response.<br>
- Using of Mp3Wrap is required. The audio bricks has to be downloaded before into CacheFileDir.
- Example: <code>silence.mp3</code>
- </li>
- <li>TTS_FileMapping<br>
- Definition of mp3files with a custom templatedefinition. Separated by space.
- All templatedefinitions can used in audiobricks by i>tts</i>.
- The definition must begin and end with e colon.
- The mp3files must saved in the given directory by <i>TTS_FIleTemplateDir</i>.<br>
- <code>attr myTTS TTS_FileMapping ring:ringtone.mp3 beep:MyBeep.mp3</code><br>
- <code>set MyTTS tts Attention: This is my ringtone :ring: Its loud?</code>
- </li>
- <li>TTS_FileTemplateDir<br>
- Directory to save all mp3-files are defined in <i>TTS_FileMapping</i> und <i>TTS_SentenceAppendix</i><br>
- Optional, Default: <code>cache/templates</code>
- </li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li><br>
- <li><a href="#disable">disable</a><br>
- If this attribute is activated, the soundoutput will be disabled.<br>
- Possible values: 0 => not disabled , 1 => disabled<br>
- Default Value is 0 (not disabled)<br><br>
- </li>
- <li><a href="#verbose">verbose</a><br>
- <b>4:</b> each step will be logged<br>
- <b>5:</b> Additionally the individual debug informations from mplayer and mp3wrap will be logged
- </li>
- </ul>
- =end html
- =begin html_DE
- <a name="Sprinkle"></a>
- <h3>Sprinkle</h3>
- <ul>
- <br>
- <a name="Sprinkledefine"></a>
- <b>Define</b>
- <ul>
- <b>Local : </b><code>define <name> Sprinkle <alsadevice></code><br>
- <b>Remote: </b><code>define <name> Sprinkle <host>[:<portnr>][:SSL] [portpassword]</code>
- <p>
- Das Modul wandelt Text mittels verschiedener Provider/Ressourcen in Sprache um. Dabei kann das Device als
- Remote oder Lokales Device konfiguriert werden.
- </p>
-
- <li>
- <b>Local Device</b><br>
- <ul>
- Die Ausgabe erfolgt auf angeschlossenen Audiodevices, zb. Lautsprecher direkt am Gerät oder per
- Bluetooth-Lautsprecher per Mplayer. Dazu ist Mplayer zu installieren.<br>
- <code>apt-get install mplayer</code><br>
- Das angegebene Alsadevice ist in der <code>/etc/asound.conf</code> zu konfigurieren.
- <p>
- <b>Special AlsaDevice: </b><i>none</i><br>
- Ist als Alsa-Device <i>none</i> angegeben, so wird mplayer ohne eine Audiodevice Angabe aufgerufen.
- Dementsprechend verwendet mplayer das Standard Audio Ausgabedevice.
- </p>
- <p>
- <b>Beispiel:</b><br>
- <code>define MyTTS Sprinkle hw=0.0</code><br>
- <code>define MyTTS Sprinkle none</code>
- </p>
- </ul>
- </li>
- <li>
- <b>Remote Device</b><br>
- <ul>
- Das Modul ist Client-Server fäas bedeutet, das auf der Haupt-FHEM Installation eine Sprinkle-Instanz
- als Remote definiert wird. Auf dem Client wird Sprinkle als Local definiert. Die Sprachausgabe erfolgt auf
- der lokalen Instanz.<br>
- Zu beachten ist, das die Sprinkle Instanz (Definition als local Device) auf dem Zieldevice identisch benannt ist.
- <ul>
- <li>Host: Angabe der IP-Adresse</li>
- <li>PortNr: Angabe des TelnetPorts von FHEM; default: 7072</li>
- <li>SSL: Angabe ob der der Zugriff per SSL erfolgen soll oder nicht; default: kein SSL</li>
- <li>PortPassword: Angabe des in der Ziel-FHEM-Installtion angegebene Telnet Portpasswort</li>
- </ul>
- <p>
- <b>Beispiel:</b><br>
- <code>define MyTTS Sprinkle 192.168.178.10:7072 fhempasswd</code>
- <code>define MyTTS Sprinkle 192.168.178.10</code>
- </p>
- </ul>
- </li>
- </ul>
- </ul>
- <a name="Sprinkleset"></a>
- <b>Set</b>
- <ul>
- <li><b>tts</b>:<br>
- Setzen eines Textes zur Sprachausgabe.
- </li>
- <li><b>volume</b>:<br>
- Setzen der Ausgabe Lautstärke.<br>
- Achtung: Nur bei einem lokal definierter Sprinkle Instanz möglich!
- </li>
- </ul><br>
- <a name="Sprinkleget"></a>
- <b>Get</b>
- <ul>N/A</ul><br>
- <a name="Sprinkleattr"></a>
- <b>Attribute</b>
- <ul>
- <li>TTS_Delemiter<br>
- Optional: Wird ein Delemiter angegeben, so wird der Sprachbaustein an dieser Stelle geteilt.
- Als Delemiter ist nur ein einzelnes Zeichen zulässig.
- Hintergrund ist die Tatsache, das die Google Sprachengine nur 100Zeichen zulässt.<br>
- Im Standard wird nach jedem Satzende geteilt. Ist ein einzelner Satz länger als 100 Zeichen,
- so wird zusätzlich nach Kommata, Semikolon und dem Verbindungswort <i>und</i> geteilt.<br>
- Achtung: Nur bei einem lokal definierter Sprinkle Instanz möglich und nur Nutzung der Google Sprachengine relevant!
- </li>
- <li>TTS_Ressource<br>
- Optional: Auswahl der Sprachengine<br>
- Achtung: Nur bei einem lokal definierter Sprinkle Instanz möglich!
- <ul>
- <li>Google<br>
- Nutzung der GoogleSprachengine. Ein Internetzugriff ist notwendig! Aufgrund der Qualität ist der
- Einsatz diese Engine zu empfehlen und der Standard.
- </li>
- <li>ESpeak<br>
- Nutzung der ESpeak Offline Sprachengine. Die Qualitä ist schlechter als die Google Engine.
- ESpeak ist vor der Nutzung zu installieren.<br>
- <code>apt-get install espeak</code>
- </li>
- </ul>
- </li>
- <li>TTS_CacheFileDir<br>
- Optional: Die per Google geladenen Sprachbausteine werden in diesem Verzeichnis zur Wiedeverwendung abgelegt.
- Es findet zurZEit keine automatisierte Löschung statt.<br>
- Default: <i>cache/</i><br>
- Achtung: Nur bei einem lokal definierter Sprinkle Instanz möglich!
- </li>
- <li>TTS_UseMP3Wrap<br>
- Optional: Für eine flüssige Sprachausgabe ist es zu empfehlen, die einzelnen vorher per Google
- geladenen Sprachbausteine zu einem einzelnen Sprachbaustein zusammenfassen zu lassen bevor dieses per
- Mplayer ausgegeben werden. Dazu muss Mp3Wrap installiert werden.<br>
- <code>apt-get install mp3wrap</code><br>
- Achtung: Nur bei einem lokal definierter Sprinkle Instanz möglich!
- </li>
- <li>TTS_MplayerCall<br>
- Optional: Angabe der Systemaufrufes zu Mplayer. Das folgende Beispiel ist der Standardaufruf.<br>
- Beispiel: <code>sudo /usr/bin/mplayer</code>
- </li>
- <li>TTS_SentenceAppendix<br>
- Optional: Angabe einer mp3-Datei die mit jeder Sprachausgabe am Ende ausgegeben wird.<br>
- Voraussetzung ist die Nutzung von MP3Wrap. Die Sprachbausteine müssen bereits als mp3 im
- CacheFileDir vorliegen.
- Beispiel: <code>silence.mp3</code>
- </li>
- <li>TTS_FileMapping<br>
- Angabe von möglichen MP3-Dateien mit deren Templatedefinition. Getrennt duch Leerzeichen.
- Die Templatedefinitionen können in den per <i>tts</i> übergebenen Sprachbausteinen verwendet werden
- und müssen mit einem beginnenden und endenden Doppelpunkt angegeben werden.
- Die Dateien müssen im Verzeichnis <i>TTS_FIleTemplateDir</i> gespeichert sein.<br>
- <code>attr myTTS TTS_FileMapping ring:ringtone.mp3 beep:MyBeep.mp3</code><br>
- <code>set MyTTS tts Achtung: hier kommt mein Klingelton :ring: War der laut?</code>
- </li>
- <li>TTS_FileTemplateDir<br>
- Verzeichnis, in dem die per <i>TTS_FileMapping</i> und <i>TTS_SentenceAppendix</i> definierten
- MP3-Dateien gespeichert sind.<br>
- Optional, Default: <code>cache/templates</code>
- </li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li><br>
- <li><a href="#disable">disable</a><br>
- If this attribute is activated, the soundoutput will be disabled.<br>
- Possible values: 0 => not disabled , 1 => disabled<br>
- Default Value is 0 (not disabled)<br><br>
- </li>
- <li><a href="#verbose">verbose</a><br>
- <b>4:</b> Alle Zwischenschritte der Verarbeitung werden ausgegeben<br>
- <b>5:</b> Zusätzlich werden auch die Meldungen von Mplayer und Mp3Wrap ausgegeben
- </li>
- </ul>
- =end html_DE
- =cut
|